Skip to content

oskarizu/jekyll-lunr-js-search

 
 

Repository files navigation

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

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. Place build/jekyll_lunr_js_search.rb inside the _plugins folder in the root of your Jekyll site.

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

A jQuery plugin is provided in js/jquery.lunr.search.js to handle the configuration of lunr.js with the search index JSON data generated by this plugin.

Dependencies for the jQuery plugin are as follows.

2. Copy the js/jquery.lunr.search.js to your Jekyll site's JavaScript directory.

3. Add a script reference to the bottom of your nominated search page for jquery.lunr.search.js and each of the dependencies outlined above.

<script src="/js/jquery-1.9.1.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/lunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/mustache.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/date.format.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/URI.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/js/jquery.lunr.search.js" type="text/javascript" charset="utf-8"></script>

Ideally you would concatenate, minify and optimise these six .js files using uglify/Google closure/etc to produce a single search.min.js file to reference.

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

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

<div id="search">
  <form action="/search" method="get">
    <input type="text" id="search-query" name="q" placeholder="Search" autocomplete="off">
  </form>
</div>

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.

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

<section id="search-results" style="display: none;">
  <p>Search results</p>
  <div class="entries">
  </div>
</section>

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

6. 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>
    </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>.

7. Configure the jQuery plugin for the search input field.

<script type="text/javascript">
  $(function() {
    $('#search-query').lunrSearch({
      indexUrl: '/search.json',             // URL of the `search.json` index data for your site
      results:  '#search-results',          // jQuery selector for the search results container
      entries:  '.entries',                 // jQuery selector for the element to contain the results list, must be a child of the results element above.
      template: '#search-results-template'  // jQuery selector for the Mustache.js template
    });
  });
</script>

8. 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]

9. 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.

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.

Building

To build the single jekyll_lunr_js_search.rb plugin file.

Requirements

Requires the following gems:

  • json
  • nokogiri

Install using gem install nokogiri json

To build to plugin.

rake build

Then copy build/jekyll_lunr_js_search.rb to your Jekyll site's _plugins folder.

About

Jekyll + lunr.js = static websites with powerful full-text search using JavaScript

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published