From 25d56e7a31857ab0d0fdab906cc5cea8eaef4644 Mon Sep 17 00:00:00 2001 From: David Grosse Date: Mon, 4 Jul 2022 11:32:45 +0200 Subject: [PATCH 1/4] introduce full-text search --- ...2022_07_04_104832_add_indices_to_posts.php | 18 ++++++ resources/lang/ar.json | 2 +- resources/lang/en.json | 2 +- resources/views/themes/zeus/home.blade.php | 28 ++++----- .../views/themes/zeus/partial/empty.blade.php | 2 +- .../themes/zeus/partial/sidebar.blade.php | 1 + .../zeus/partial/sidebar/search.blade.php | 8 +++ src/Http/Livewire/Posts.php | 57 +++++++++++++------ 8 files changed, 82 insertions(+), 36 deletions(-) create mode 100644 database/migrations/2022_07_04_104832_add_indices_to_posts.php create mode 100644 resources/views/themes/zeus/partial/sidebar/search.blade.php diff --git a/database/migrations/2022_07_04_104832_add_indices_to_posts.php b/database/migrations/2022_07_04_104832_add_indices_to_posts.php new file mode 100644 index 0000000..b2ac0ab --- /dev/null +++ b/database/migrations/2022_07_04_104832_add_indices_to_posts.php @@ -0,0 +1,18 @@ +index('title'); + $table->index('slug'); + $table->index('description'); + $table->fullText('content'); + }); + } +}; diff --git a/resources/lang/ar.json b/resources/lang/ar.json index b4069e6..689ebff 100644 --- a/resources/lang/ar.json +++ b/resources/lang/ar.json @@ -43,5 +43,5 @@ "Post Slug": "الرابط المختصر", "Write an excerpt for your post": "اكتب ملخص للمقالة", "Show All posts in": "هرض كافة المثالات في", - "No posts yet": "لاتوجد تدوينات حاليا" + "No posts found": "لاتوجد تدوينات حاليا" } diff --git a/resources/lang/en.json b/resources/lang/en.json index 955cba1..bd2bfba 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -43,5 +43,5 @@ "Post Slug": "Post Slug", "Write an excerpt for your post": "Write an excerpt for your post", "Show All posts in": "Show All posts in", - "No posts yet": "No posts yet" + "No posts found": "No posts found" } diff --git a/resources/views/themes/zeus/home.blade.php b/resources/views/themes/zeus/home.blade.php index fb5ce36..82c62f1 100644 --- a/resources/views/themes/zeus/home.blade.php +++ b/resources/views/themes/zeus/home.blade.php @@ -10,23 +10,19 @@
- @unless ($posts->isEmpty() && $stickies->isEmpty()) -
- @unless ($posts->isEmpty()) -
-

Posts

-
- @each($theme.'.partial.post', $posts, 'post') - @else - @include($theme.'.partial.empty') - @endunless +
+ @unless ($posts->isEmpty()) +
+

Posts

-
- @include($theme.'.partial.sidebar') -
- @else - @include($theme.'.partial.empty') - @endunless + @each($theme.'.partial.post', $posts, 'post') + @else + @include($theme.'.partial.empty') + @endunless +
+
+ @include($theme.'.partial.sidebar') +
diff --git a/resources/views/themes/zeus/partial/empty.blade.php b/resources/views/themes/zeus/partial/empty.blade.php index aa2b820..9e96e24 100644 --- a/resources/views/themes/zeus/partial/empty.blade.php +++ b/resources/views/themes/zeus/partial/empty.blade.php @@ -1,4 +1,4 @@
- {{ __('No posts yet') }}! + {{ __('No posts found') }}!
diff --git a/resources/views/themes/zeus/partial/sidebar.blade.php b/resources/views/themes/zeus/partial/sidebar.blade.php index acbf366..04f2f19 100644 --- a/resources/views/themes/zeus/partial/sidebar.blade.php +++ b/resources/views/themes/zeus/partial/sidebar.blade.php @@ -1,4 +1,5 @@ {{--@include($theme.'.partial.authors')--}} +@include($theme.'.partial.sidebar.search') @include($theme.'.partial.sidebar.categories') @include($theme.'.partial.sidebar.recent') @include($theme.'.partial.sidebar.pages') diff --git a/resources/views/themes/zeus/partial/sidebar/search.blade.php b/resources/views/themes/zeus/partial/sidebar/search.blade.php new file mode 100644 index 0000000..13d398f --- /dev/null +++ b/resources/views/themes/zeus/partial/sidebar/search.blade.php @@ -0,0 +1,8 @@ +
+

Search

+
+
+ +
+
+
diff --git a/src/Http/Livewire/Posts.php b/src/Http/Livewire/Posts.php index 1e7e578..9c77fb0 100644 --- a/src/Http/Livewire/Posts.php +++ b/src/Http/Livewire/Posts.php @@ -2,6 +2,8 @@ namespace LaraZeus\Sky\Http\Livewire; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Facades\DB; use LaraZeus\Sky\Models\Post; use LaraZeus\Sky\Models\Tag; use Livewire\Component; @@ -10,28 +12,49 @@ class Posts extends Component { public function render() { - return view(app('theme').'.home') - ->with([ - 'posts' => Post::NotSticky() - ->orderBy('published_at', 'desc') - ->get(), - - 'pages' => Post::page() - ->orderBy('published_at', 'desc') - ->whereNull('parent_id') - ->get(), + $search = strtolower(request()->get('search')); - 'tags' => Tag::withCount('postsPublished') - ->where('type', 'category') - ->get(), // $this->tag->postsPublished + $posts = Post::NotSticky(); + $posts = $this->applySearch($posts, $search); + $posts = $posts + ->orderBy('published_at', 'desc') + ->get(); - 'stickies' => Post::sticky()->get(), + $pages = Post::page(); + $pages = $this->applySearch($pages, $search); + $pages = $pages + ->orderBy('published_at', 'desc') + ->whereNull('parent_id') + ->get(); - 'recent' => Post::posts() - ->take(config('zeus-sky.site_recent_count', 5)) + $recent = Post::posts() + ->limit(config('zeus-sky.site_recent_count', 5)) ->orderBy('published_at', 'desc') - ->get(), + ->get(); + + return view(app('theme').'.home') + ->with([ + 'posts' => $posts, + 'pages' => $pages, + 'recent' => $recent, + 'tags' => Tag::withCount('postsPublished')->where('type', 'category')->get(), + 'stickies' => Post::sticky()->get(), ]) ->layout(config('zeus-sky.layout')); } + + private function applySearch(Builder $query, string $search): Builder + { + if ($search) { + return $query->where(function ($query) use ($search) { + foreach (['title', 'slug', 'content', 'description'] as $attribute) { + $query->orWhere(DB::raw("lower($attribute)"), 'like', "%$search%"); + } + + return $query; + }); + } + + return $query; + } } From 3826f65756efe3545330150ee6d9d2efd2d72a47 Mon Sep 17 00:00:00 2001 From: David Grosse Date: Mon, 4 Jul 2022 14:03:20 +0200 Subject: [PATCH 2/4] add highlight (yellow background) to search results --- config/zeus-sky.php | 5 +++++ resources/views/themes/zeus/home.blade.php | 4 ++++ src/Http/Livewire/Posts.php | 23 ++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/config/zeus-sky.php b/config/zeus-sky.php index c7e3df9..4d1dbe4 100644 --- a/config/zeus-sky.php +++ b/config/zeus-sky.php @@ -68,6 +68,11 @@ */ 'theme' => 'zeus', + /** + * css class to apply on found search result, e.g. `bg-yellow-400`. + */ + 'search_result_highlight_css_class' => 'highlight', + /** * available locales, this currently used only in tags manager. */ diff --git a/resources/views/themes/zeus/home.blade.php b/resources/views/themes/zeus/home.blade.php index 82c62f1..f703c24 100644 --- a/resources/views/themes/zeus/home.blade.php +++ b/resources/views/themes/zeus/home.blade.php @@ -1,4 +1,8 @@
+ {{-- You can override the used class in config/zeus-sky.php 'search_result_highlight_css_class'' --}} + @unless($stickies->isEmpty())
@foreach($stickies as $post) diff --git a/src/Http/Livewire/Posts.php b/src/Http/Livewire/Posts.php index 9c77fb0..93cf5da 100644 --- a/src/Http/Livewire/Posts.php +++ b/src/Http/Livewire/Posts.php @@ -3,6 +3,7 @@ namespace LaraZeus\Sky\Http\Livewire; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Facades\DB; use LaraZeus\Sky\Models\Post; use LaraZeus\Sky\Models\Tag; @@ -27,6 +28,9 @@ public function render() ->whereNull('parent_id') ->get(); + $pages = $this->highlightSearchResults($pages, $search); + $posts = $this->highlightSearchResults($posts, $search); + $recent = Post::posts() ->limit(config('zeus-sky.site_recent_count', 5)) ->orderBy('published_at', 'desc') @@ -57,4 +61,23 @@ private function applySearch(Builder $query, string $search): Builder return $query; } + + private function highlightSearchResults(Collection $posts, ?string $search = null): Collection + { + if (! $search) { + return $posts; + } + + foreach ($posts as $i => $post) { + $posts[$i]->content = strtr($post->content, [ + $search => sprintf( + '%s', + config('zeus-sky.search_result_highlight_css_class', 'highlight'), + $search + ), + ]); + } + + return $posts; + } } From 30d00e32f4456e7552db43fb6c350ebbd458c617 Mon Sep 17 00:00:00 2001 From: Herbert Maschke Date: Tue, 5 Jul 2022 08:13:31 +0200 Subject: [PATCH 3/4] make highlighting case insensitive ('demo' highlights 'DEmo') --- src/Http/Livewire/Posts.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Http/Livewire/Posts.php b/src/Http/Livewire/Posts.php index 93cf5da..c98f7a2 100644 --- a/src/Http/Livewire/Posts.php +++ b/src/Http/Livewire/Posts.php @@ -68,14 +68,14 @@ private function highlightSearchResults(Collection $posts, ?string $search = nul return $posts; } + $class = config('zeus-sky.search_result_highlight_css_class', 'highlight'); + foreach ($posts as $i => $post) { - $posts[$i]->content = strtr($post->content, [ - $search => sprintf( - '%s', - config('zeus-sky.search_result_highlight_css_class', 'highlight'), - $search - ), - ]); + $posts[$i]->content = str_ireplace( + $search, + sprintf('%s', $class, $search), + $post->content, + ); } return $posts; From b621af474639077761dfcd89a7b137c90de95417 Mon Sep 17 00:00:00 2001 From: David Grosse Date: Tue, 5 Jul 2022 13:06:54 +0200 Subject: [PATCH 4/4] improve highlighting algorithm once more --- src/Http/Livewire/Posts.php | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Http/Livewire/Posts.php b/src/Http/Livewire/Posts.php index c98f7a2..2fc087d 100644 --- a/src/Http/Livewire/Posts.php +++ b/src/Http/Livewire/Posts.php @@ -68,16 +68,29 @@ private function highlightSearchResults(Collection $posts, ?string $search = nul return $posts; } - $class = config('zeus-sky.search_result_highlight_css_class', 'highlight'); - foreach ($posts as $i => $post) { - $posts[$i]->content = str_ireplace( - $search, - sprintf('%s', $class, $search), - $post->content, - ); + $posts[$i]->content = static::hl($post->content, [$search]); } return $posts; } + + /** + * Credits for this code goes to link below. + * + * @link https://stackoverflow.com/questions/8564578/php-search-text-highlight-function + */ + public static function hl(string $inp, array $words): string + { + $class = config('zeus-sky.search_result_highlight_css_class', 'highlight'); + $replace = array_flip(array_flip($words)); + $pattern = []; + + foreach ($replace as $k => $fword) { + $pattern[] = '/\b('.$fword.')(?!>)\b/i'; + $replace[$k] = sprintf('$1', $class); + } + + return preg_replace($pattern, $replace, $inp); + } }