144 lines
5.0 KiB
Markdown
144 lines
5.0 KiB
Markdown
@def hascode = true
|
|
|
|
# Add search with Lunr
|
|
|
|
\toc\skipline
|
|
|
|
[`lunr.js`](https://lunrjs.com/) is a neat little Javascript library that allows to equip your website with a search functionality fairly easily.
|
|
|
|
The steps below show a simple way of doing this matching what is done on this website.
|
|
Once it's working, you might want to adjust the `build_index.js` and/or the `lunrclient.js` to match your needs.
|
|
|
|
## Pre-requisites
|
|
|
|
### Libraries
|
|
|
|
Install `lunr` and `cheerio` (a HTML parser) with `node`:
|
|
|
|
```bash
|
|
$> npm install lunr
|
|
$> npm install cheerio
|
|
```
|
|
|
|
(you might have to add `sudo` before `npm`).
|
|
|
|
### Files
|
|
|
|
Copy [this folder](https://github.com/tlienart/franklindocs/tree/master/_libs/lunr) to a `/_libs/lunr/` directory.
|
|
Discard the `lunr_index.js` which is the index of this website, you will rebuild your own of course!
|
|
|
|
The important files are `build_index.js` and `lunrclient.js` (of which a minified version is provided which you will want to re-generate if you modify the base file).
|
|
These files are adapted from [this repository](https://github.com/BLE-LTER/Lunr-Index-and-Search-for-Static-Sites) which shows how to use Lunr on a static website.
|
|
|
|
You can choose whether to serve your own copy of `lunr.min.js` (done here) or to use an online version via
|
|
|
|
```html
|
|
<script src="https://unpkg.com/lunr/lunr.js"></script>
|
|
```
|
|
|
|
|
|
### Index builder
|
|
|
|
The file `build_index.js` does the following:
|
|
|
|
@@tlist
|
|
- it goes over all files in a `HTML_FOLDER` (by default: `/__site/`),
|
|
- it builds an index `lunr_index.js` which can subsequently be queried upon the user entering search terms.
|
|
@@
|
|
|
|
By default, the index built is fairly barebone to reduce the size of the generated index. If you want fancier search, you might want to modify this a bit to add a preview of the page, boost results depending on where there are (title, keyword, ...), add stop words, etc. (Refer to the [Lunr docs](https://lunrjs.com/docs/index.html) for this as well as [the example repo](https://github.com/BLE-LTER/Lunr-Index-and-Search-for-Static-Sites) mentioned earlier or [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl/blob/master/assets/html/search.js)'s version).
|
|
|
|
\note{
|
|
Modify this file at will but be careful with the lines with `PATH_PREPEND` if your website is a project website (i.e. the root URL is something like `username.github.io/project/`). These lines help ensure that the generated links are valid. See also the section on [updating the index](#buildingupdating_the_index).
|
|
}
|
|
|
|
### Client
|
|
|
|
The file `lunrclient.js` (and its minified version) does the following:
|
|
|
|
@@tlist
|
|
- query the index
|
|
- display the results
|
|
@@
|
|
|
|
You might want to modify the `parseLunrResults` if you want the results to be displayed differently.
|
|
|
|
\note{
|
|
If you modify this file, make sure it's called properly in the `src/_html_parts/index.html` and, eventually, [minify it](https://jscompress.com/).
|
|
}
|
|
|
|
## Adding a search box
|
|
|
|
### Adding a form in `head.html`
|
|
|
|
The search box on this website is added with the following HTML in `_layout/head.html`:
|
|
|
|
```html
|
|
<!doctype html>
|
|
<!-- first few lines ... -->
|
|
<script src="/libs/lunr/lunr.min.js"></script>
|
|
<script src="/libs/lunr/lunr_index.js"></script>
|
|
<script src="/libs/lunr/lunrclient.min.js"></script>
|
|
</head>
|
|
<!-- ... -->
|
|
<form id="lunrSearchForm" name="lunrSearchForm">
|
|
<input class="search-input" name="q" placeholder="Enter search term" type="text">
|
|
<input type="submit" value="Search" formaction="/search/index.html">
|
|
</form>
|
|
<-- ... -->
|
|
```
|
|
|
|
You may want to style it a bit like so:
|
|
|
|
```css
|
|
.result-title a { text-decoration: none; }
|
|
.result-title a:hover { text-decoration: underline; }
|
|
.result-preview { color: #808080; }
|
|
.resultCount { color: #808080; }
|
|
.result-query { font-weight: bold; }
|
|
#lunrSearchForm { margin-top: 1em; }
|
|
```
|
|
|
|
### Target search page
|
|
|
|
You also need to add a `src/search.md` to display the results with the appropriate divs:
|
|
|
|
```html
|
|
@def title = "Search ⋅ YourWebsite"
|
|
|
|
## Search
|
|
|
|
Number of results found: ~~~<span id="resultCount"></span>~~~
|
|
|
|
~~~
|
|
<div id="searchResults"></div>
|
|
~~~
|
|
```
|
|
|
|
Note that if you modify the `id` of these elements, you will need to adapt the `lunrclient` file(s) accordingly.
|
|
|
|
## Building/updating the index
|
|
|
|
Franklin exports a `lunr()` function which
|
|
|
|
@@tlist
|
|
- checks that you have the right files at the right place,
|
|
- (re)builds the index, prepending a path to links if required.
|
|
@@
|
|
|
|
If you are experimenting locally, just call `lunr()` then `serve()` and test that searching works as expected.
|
|
|
|
When you are ready to update your website you can either:
|
|
|
|
@@tlist
|
|
1. (recommended) Call `publish(final=lunr)`,
|
|
1. Call `lunr()` or `lunr(prepath)` if there is a prepath and then publish your updates manually.
|
|
@@
|
|
|
|
The `publish(final=lunr)` calls the `lunr` function as a last step prior to doing a `git push`.
|
|
An advantage of using this is that Franklin will properly handle the `prepath` if there is one defined in your `config.md`.
|
|
|
|
\note{
|
|
This `final=` keyword can be used with your own functions `()->nothing` if you need to do some post-processing with the generated files before pushing.
|
|
}
|