Skip to main content

Jekyll: Easy searching with JSON and jQuery

Jekyll is a great tool to build web sites, unfortunately there is no built in search. This post will describe how to create one a basic search using JSON and jQuery.

Step 1: Create search.json

There are quite a few methods to create a search.json file. For me, I wanted to use built in Jekyll methods (no plugins). For that, I based the code from JSONify your Jekyll Site as well as other aspects of my site. The new code will look for attributes in one of your site posts. Below is what my search.json looks like, it can also be found on my github Repository.

---
---
[
    {% for post in site.posts %}
    {
      "title"    : "{{ post.title }}",
      "href"     : "{{ post.url }}",
      "summary"     : "{{ post.content | strip_html | strip_newlines | truncatewords: 30 | escape }}",
      "category" : [{% for category in post.categories %}"{{ category }}",{% endfor %} null],
      "tags"     : [{% for tag in post.tags %}"{{ tag }}",{% endfor %} null],
      "date"     : "{{ post.date | date: "%b %-d, %Y" }}"
    }
    {% unless forloop.last %},{% endunless %}
    {% endfor %}
]

Step 2: Update your HTML code

Next, we need to update the search form:

<form role="search" method="get" class="navbar-form navbar-right form-inline" action="/search.html">
    <div class="form-group" id="searchdiv">
    <input type="search" id="searchbox" name="searchbox" class="form-control search" placeholder="Search ... ">
    <label class="hide">Search for:</label>
    </div>
    <button type="submit" class="btn btn-success search"> <i class="fa fa-search"></i></button>
</form>

Step 3: Create your search.html page

Thirdly, we need to create a basic html page that basically has our title, and a div to hold the jQuery results. Here is the code:

---
layout: default
title: Search Results
---
<h1 id="searchHeader">Search results</h1>
<noscript><p>Sorry, the current site search is only available in JavaScript. Please try this link to search from Google.</p></noscript>
<div id="buildResults"></div>

Step 4: Add the jQuery to your site

To query the search.json, I used jQuery&aspo;s getJSON method. For this, you will need the below code first:

Function 1:

/*start search function;*/
var getSearchResults = function(url) {

    var count = 0;
    var searchedFor = getParameterByName('searchbox'); /*get the query parameter from search box*/
    var searchedForTest = searchedFor.toLowerCase();
    $('#searchbox').val(searchedFor); /*update input field with what was searched for*/

    $.getJSON('/search.json', function(data) {
    $('div#results').append('<section class="col-xs-12 col-sm-6 col-md-12">');
    $.each(data, function(key, val){

        /*values to variable to use more than once.*/
        var blogTitle = val.title;
        var blogCategory = val.category;
        var blogTags = val.tags;
        var blogLink = val.href;
        var blogDate = val.date;
        var blogSummary = val.summary;

        /*search array for*/
        var testCategory = $.inArray(searchedForTest, blogCategory );
        var testTags = $.inArray(searchedForTest, blogTags );

        if ( (blogTitle.toLowerCase().indexOf(searchedForTest) > -1 )  || (testCategory > -1 ) ||  (testTags > -1 ) ) {
        displyResult(blogTitle,blogCategory,blogTags,blogLink,blogDate,blogSummary);
            count++;
        } else {
            /*result not found. Do NOT increment count here.*/
        }

    }); /*end for each*/

        $('h1#searchHeader').after('<h2 class="lead"><strong class="text-danger">'+ count+'</strong> results were found for the search for <strong class="text-danger">'+ searchedFor+'</strong></h2>');
        $('div#rbuildResults').append('</section>');

    }); /*end getjson*/

};/*end get search results*/

Function 2:

var displyResult = function(blogTitle,blogCategory,blogTags,blogLink,blogDate,blogSummary) {

var results = '<article class="posts blogpage">'+
    '<h2 class="entry-title">'+
    '<a class="post-link" href="'+blogLink+'">'+blogTitle+'</a>'+
    '</h2>'+
    '<div class="entry-summary">'+
        '<p>'+
        blogSummary +
        '<a href="'+blogLink+'">Continued</a>'+
        '</p>'+
    '</div>'+
    '<span class="badge blog-date">'+
    '<time class="published">'+
    blogDate+
    '</time>'+
    '</span>'+
    '<div class="pull-right">';

for (var j in blogTags) {
    if (blogTags[j]  === null){
    } else {
        results = results + ' <span class="label label-primary taggedPost"><a href="/search.html?searchbox='+blogTags[j]+'">' + blogTags[j] + '</a></span> ';
    }
}

results = results + '</div>'+
'</article>';

$('div#buildResults').append(results);
};

getSearchResults('/search.json');

This wraps up the post on how to easily add a search to your Jekyll site.

Resources: