jekyll-lunr-js-search-multilingual

jekyll-lunr-js-search-multilingual

Plugin for Jekyll "jekyll-lunr-js-search" with generated gem-file (because gem in repo not updated)

Jekyll + lunr.js = Static websites with powerful full-text search

Use lunr.js to provide simple full-text search, using JavaScript in your browser, for your Jekyll static website.

Inspired by Pascal Widdershoven's Jekyll + indextank and Michael Levin's Sitemap.xml Generator plugins.

This Jekyll plugin handles the generation of a lunr.js compatible .json index file. Runtime search configuration is provided by a simple jQuery plugin.

It allows full-text search of all your Jekyll pages and posts. Executed by the client without any server-side processing (outside of serving static files).

How to use

1. Install the plugin as a Ruby Gem

  1. Write to Jekyll's Gemfile:
    gem 'jekyll-lunr-js-search-multilingual', git: 'https://github.com/fortran-team/jekyll-lunr-js-search-multilingual'
    to install from this git repo or
    gem 'jekyll-lunr-js-search-multilingual'
    to install from 'https://rubygems.org'

  2. Modify your Jekyll _config.yml file to include the Gem:
    plugins:
      - jekyll-lunr-js-search-multilingual

The content from all Jekyll posts and pages will be indexed to a _site/js/index.json file ready for lunr.js to consume. This happens each time the site is generated.

A JavaScript code is provided in _site/js/search.min.js to handle the configuration of lunr.js with the search index JSON data generated by this plugin.

2. Use the plugin by adding a script reference

To use it, you must add a script reference to the bottom of your nominated search page

<script src="{{ site.baseurl }}/js/search.min.js" type="text/javascript" charset="utf-8"></script>

3. Add a search form with a query input as shown

<form action="{{ site.baseurl }}/search" method="get">
    <div class="form-group">
        <input class="form-control" type="text" name="q" placeholder="Search" id="search-query">
    </div>
</form>

Search happens as you type, once at least three characters have been entered.

Providing the form action and specifying the get method allows the user to hit return/enter to also submit the search. Amend the form's action URL as necessary for the search page on your own site.

4. Add an element to contain the list of search result entries

<section id="search-results" style="display: none;"></section>

This may be initially hidden as the plugin will show the element when searching.

5. Create a Mustache template to display the search results

{% raw %}
<script id="search-results-template" type="text/mustache">
  {{#entries}}
    <article>
      <h3>
        {{#date}}<small><time datetime="{{pubdate}}" pubdate>{{displaydate}}</time></small>{{/date}}
        <a href="{{url}}">{{title}}</a>
      </h3>
      {{#is_post}}
      <ul>
        {{#tags}}<li>{{.}} </li>{{/tags}}
      </ul>
      {{/is_post}}
    </article>
  {{/entries}}
</script>
{% endraw %}

Note the use of {% raw %} and {% endraw %} to ensure the Mustache tags are not stripped out by Jekyll.

The fields available to display are as follows:

entries

List of search result entries (mandatory).

date

Raw published date for posts, or null for pages. Can be used to toggle display of the following dates in the template {{#date}}has a date{{/date}} {{#!date}}no date{{/date}}.

pubdate

Post published date, formatted as 'yyyy-mm-dd', to be used in a html5 <time datetime="{{pubdate}}"> element (posts only).

displaydate

Post published date, formatted as 'mmm dd, yyyy', such as Oct 12, 2012 (posts only)

title

Title of the Jekyll page or post.

url

URL of the Jekyll page or post that can be used to create a hyperlink <a href="{{url}}">{{title}}</a>.

categories

Categories (array) of the Jekyll page or post, can be used in a loop {{#categories}}{{.}} {{/categories}} to list them.

tags

Tags (array) of the Jekyll page or post, can be used in a loop {{#tags}}{{.}} {{/tags}} to list them.

is_post

Boolean value, true if current result element is a post. Can be used to toggle display of specific elements in the template {{#is_post}}is a post{{/is_post}}

6. Configure the plugin for the search input field

<script type="text/javascript">
  $(function() {
    $('#search-query').lunrSearch({
      indexUrl  : '{{ site.baseurl }}/js/index.json', // url for the .json file containing search index data
      results   : '#search-results',                  // selector for containing search results element
      template  : '#search-results-template',         // selector for Mustache.js template
      titleMsg  : '<h1>Search results<h1>',           // message attached in front of results (can be empty)
      emptyMsg  : '<p>Nothing found.</p>'             // shown message if search returns no results
    });
  });
</script>

7. To exclude pages from the search index

Add the following exclude_from_search setting to any page's YAML config.

exclude_from_search: true

Or add an array of exclusions (as individual regular expressions) to the site's _config.yml file.

lunr_search:
  excludes: [rss.xml, atom.xml]

8. Stop Words

You can also configure a stopwords file, and a minimum length of word to be included in the index file. This can be done by adding a search block to _config.yml. The default values are:

lunr_search:
  stopwords: "stopwords.txt"
  min_length: 3

The stopwords file must consist of one word per line, in lowercase, without punctuation.

9. Alternate data directory

You can choose to store index.json, search.min.js and lunr.min.js in a different directory like this:

lunr_search:
  js_dir: "javascript"

Demo

Search plugin is deployed to 10consulting.com/search. Some example search queries are /search/?q=git, /search/?q=cqrs.

It also features on-demand loading of the search plugin .js when focusing into the search field on the homepage. Look at the browser network requests clicking into the search input.

How to code and build

I write below how to code and build Jekyll plugin jekyll-lunr-js-search-multilingual on Windows but you can do it everywhere, because instruction is universal, excepting hyperlinks on software. If you want to code and build the plugin, you need:

  • Correct code that you want in directories:
    • for Ruby code:
      <repo_root>/lib
    • for JavaScript code:
      <repo_root>/js
  • Install Ruby Installer Devkit 2.5.3-1
  • Install Ruby Bundler by executing command:
    gem install bundler
  • Execute the following:
    bundle install
  • Install NodeJS.
  • Install NodeJS Bower by executing command:
    npm install -g bower
  • Build the plugin:
    rake build
  • Also you can create gem file:
    • change version in file:
      <repo_root>/lib/jekyll_lunr_js_search/version.rb
    • build and create gem file:
      rake build_gem
  • Also you can create gem file and push it on 'https://rubygems.org':
    • change version in file:
      <repo_root>/lib/jekyll_lunr_js_search/version.rb
    • build, create and push gem file:
      rake publish_gem

If you include the .js and .js.map files your browser developer console will link to the unminified code.