diff --git a/v8/flexsearch_plugin/README.md b/v8/flexsearch_plugin/README.md new file mode 100644 index 00000000..c69c8598 --- /dev/null +++ b/v8/flexsearch_plugin/README.md @@ -0,0 +1,226 @@ +# flexsearch_plugin + +This plugin adds search functionality to a Nikola Site. + +It generates a json with all the articles, slugs and titles and then uses [flexsearch](https://github.com/nextapps-de/flexsearch) to search. + +It supports searching clicking the search button or pressing enter. + +The s`earch_index.json` is (re)generated on `nikola build` + +# How to use + +There are 2 options: + +- Use a normal div and add the search results there. +- Use an overlay with the search results. + +Here is an example of the overlay: + +![](imgs/example_overlay.png) + +For a live example check https://diegocarrasco.com + + +## Use a normal div and extend and populate it withthe results + +Append this to your `BODY_END` in `conf.py` + +```html + + +``` + +then add this where you want the search to appear + +```html + + +
+``` + + +## Use an overlay for the results + +This js allows to click the button or press enter to search + +```html + + + +``` + +add this to your template where you want the search to appear + +```html + + + +``` + +add css for the overlay + +```html +/* flexsearch_plugin*/ + +#search_overlay { + position: fixed; /* Fixed position to cover the whole screen */ + width: 100%; + height: 100%; + top: 0; + left: 0; + background: rgba(0, 0, 0, 0.8); /* Semi-transparent background */ + z-index: 1000; /* Make sure it's on top of other content */ + display: flex; + justify-content: center; + align-items: center; +} + +#search_content { + background: white; + padding: 20px; + width: 90%; + max-width: 600px; /* Limit the width on larger screens */ + border-radius: 5px; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); +} + +#search_results { + margin-top: 20px; +} + +button { + cursor: pointer; +} +``` + +## License + +this plugin is under the MIT License + +MIT License + +Copyright (c) [2024] [Diego Carrasco G.] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/v8/flexsearch_plugin/conf.py.sample b/v8/flexsearch_plugin/conf.py.sample new file mode 100644 index 00000000..a6993a7a --- /dev/null +++ b/v8/flexsearch_plugin/conf.py.sample @@ -0,0 +1,130 @@ +# Use this to add the search results to an overlay +# In this case you need the following in your template. Check the readme for a base css.: +# +# +# + +FLEXSEARCH_OVERLAY = """ + + + +""" + +# use this to add the results to a dive, effectively expanding that div. +# In this case you need to add the following to your template. The search results will be added to #search_results: +# +# +# + +FLEXSEARCH_EXTEND = """ + + + +""" + +BODY_END = BODY_END + FLEXSEARCH_EXTEND \ No newline at end of file diff --git a/v8/flexsearch_plugin/flexsearch_plugin.plugin b/v8/flexsearch_plugin/flexsearch_plugin.plugin new file mode 100644 index 00000000..4474cbdc --- /dev/null +++ b/v8/flexsearch_plugin/flexsearch_plugin.plugin @@ -0,0 +1,14 @@ +[Core] +Name = flexsearch_plugin +Module = flexsearch_plugin + +[Documentation] +Author = Diego Carrasco G. +Version = 0.1 +Website = https://plugins.getnikola.com/#flexsearch_plugin +Description = Adds FlexSearch full-text search capabilities to Nikola static sites. + +[Nikola] +MinVersion = 8.0.0 # I haven't tested it with older versions +MaxVersion = 8.3.1 +PluginCategory = LateTask \ No newline at end of file diff --git a/v8/flexsearch_plugin/flexsearch_plugin.py b/v8/flexsearch_plugin/flexsearch_plugin.py new file mode 100644 index 00000000..e030da77 --- /dev/null +++ b/v8/flexsearch_plugin/flexsearch_plugin.py @@ -0,0 +1,69 @@ +# MIT License +# +# Copyright (c) [2024] [Diego Carrasco G.] +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import os +import json +from nikola.plugin_categories import LateTask +from nikola import utils + + +class FlexSearchPlugin(LateTask): + name = "flexsearch_plugin" + + def set_site(self, site): + super(FlexSearchPlugin, self).set_site(site) + self.site = site + site.register_path_handler('search_index', self.search_index_path) + + def gen_tasks(self): + """Generate the search index after all posts are processed.""" + self.site.scan_posts() + yield self.group_task() + + output_path = self.site.config['OUTPUT_FOLDER'] + index_file_path = os.path.join(output_path, 'search_index.json') + + def build_index(): + """Build the entire search index from scratch.""" + index = {} + for post in self.site.timeline: + if post.is_post and not post.is_draft: + index[post.meta('slug')] = { + 'title': post.title(), + 'content': post.text(strip_html=True), + 'url': post.permalink() + } + with open(index_file_path, 'w', encoding='utf-8') as f: + json.dump(index, f, ensure_ascii=False) + + task = { + 'basename': self.name, + 'name': 'all_posts', + 'actions': [build_index], + 'targets': [index_file_path], + 'uptodate': [utils.config_changed({1: self.site.GLOBAL_CONTEXT})], + 'clean': True, + } + yield task + + def search_index_path(self, name, lang): + return [os.path.join(self.site.config['BASE_URL'], 'search_index.json'), None] diff --git a/v8/flexsearch_plugin/imgs/example_overlay.png b/v8/flexsearch_plugin/imgs/example_overlay.png new file mode 100644 index 00000000..52c22988 Binary files /dev/null and b/v8/flexsearch_plugin/imgs/example_overlay.png differ