I’ve implemented a number of things into this blog to make it more interesting and useful for visitors. One of said things is the search, and whilst it was incredibly easy to setup I had one issue along the way to getting it working. In this post I will demonstrate how it was implemented and the wall I ran into.

##The what and how

A simple search on Google returned Christian Fei’s fine work on a Jekyll based search facility. After following Christian’s README.MD I soon got the basics in place.

Here is how the file/folder structure looks for this blog in relation to the search implementation;

\_includes\header.html

  • (contains javascript code needed for the search)
    \_sass\_layout.css
  • (contains the layout information for the search input and results)
    \assets\js\search.js
  • (renamed from jekyll-search.js)
    \search.json
  • (the json object used as a datasource for the search)

###What’s with the _includes and _sass

In Jekyll, whenever you put an underscore before the folder or file name it denotes that the folder or file will not be built by the build process.

See Jekyll rules

So for example, you will have an \_includes folder that won’t be build during the jekyll build process, but files inside it without an underscore will be built.

###So what is in these files?

\_includes\header.html

<header>

.. bunch of stuff for the header of the blog
..
Then the search Javascript code needed

<script type="text/javascript">
SimpleJekyllSearch({
	searchInput: document.getElementById('search-input'),
	resultsContainer: document.getElementById('results-container'),
	json: '/search.json',
	searchResultTemplate: '<table class="search-results-table"><tr><th><img src="{image}" width="40" height="40"></img></th><th><li><a href="{url}" title="{desc}">{title}</a></li></th></tr></table>',
	noResultsText: 'No results found, please try again',
	limit: 10,
	fuzzy: false,
})
</script>	

</header>  

\_sass\_layout.css

Contains all my layout information for the site, including how the search looks and operates.
Here is the search related CSS layout.

/**
 * Search
 */

#search-container {
  margin-left: 15px;
  width: 100%;

  @include media-query($on-palm) {
	width: 100%;
  }
}

#search-input {
	font-family: Imprima;
	font-weight: bold;
	height: 30px;
	width: 97%;
	padding: 0px 0px 0px 5px;
	color: #B03A3A;
	background-color: whitesmoke;
	border-radius: 0px 0px 20px 5px;
	border-top-style: hidden;
	border-left-style: hidden;
	border-bottom-style: hidden;

	-webkit-transition: box-shadow linear 0.25s;
	transition: box-shadow linear 0.25s;

	@include media-query($on-palm) {
		width: 96%;
	}
}

#search-input:focus {
	outline: 0;
	box-shadow: 0 0 10px black;
}

#results-container {
  list-style-type: none;
  margin-top: 0px;
  font-family: Imprima;
  font-size: 20px;
  width: 95%;
  margin-left: 0px;	
  background-color: whitesmoke;
}

.search-results-table th {
  font-weight: normal;
  padding: 3px;
}  

\assets\js\search.js

This the main code for the search, but I changed one line to fulfill a requirement I had. 
.
. Main Christian Fei search code
.  
searchResultTemplate: '<img src="{image}"></img><li><a href="{url}" title="{desc}">{title}</a></li>',  
.  
.  

More on the above later..

##The wall

When I initially got everything in place for the search I couldn’t for the life me get back results from the search box. Through some investigation I noticed that the \search.json wasn’t getting loaded on page load. So I looked at the rendered version of \search.json (the output of jekyll build) and could see that the content markup for a post was all over the place.

This is the original \search.json

---
---
[
{% for post in site.posts %}
{
	"title"    : "{{ post.title | escape }}",
	"image"	   : "{{ post.image }}",
	"category" : "{{ post.category }}",
	"tags"     : "{{ post.tags | join: ', ' }}",
  	"url"      : "{{ site.baseurl }}{{ post.url }}",
  	"date"     : "{{ post.date }}",
  	"content"  : "{{ post.content }}"
} {% unless forloop.last %},{% endunless %}
{% endfor %}
]  

After a good few hours of troubleshooting (in the Chrome inspector) it turned out that the post.content was causing the issue. This is because the post.content result has lots of differing markup in it and for whatever reason I couldn’t clear it up enough when rendered to be usable by the search.

When I say cleaned up I mean using the in-built Jekyll filters.
For example,

  	"content"  : "{{ post.content | xml_escape}}"  

After much fussing I decided to ommit the post.content from the search index and everything started to work!

This is the amended \search.json with the post.content removed.

---
---
[
{% for post in site.posts %}
{
	"title"    : "{{ post.title | escape }}",
	"image"	 : "{{ post.image }}",
	"category" : "{{ post.category }}",
	"tags"     : "{{ post.tags | join: ', ' }}",
  	"url"      : "{{ site.baseurl }}{{ post.url }}",
  	"date"     : "{{ post.date }}",
  	"content"  : ""
} {% unless forloop.last %},{% endunless %}
{% endfor %}
]  

You will note above that I am not including the post.content section. This will result in the search only working for titles, category, tags, url or date.

##UPDATE:
It turns out that Christian has since fixed this issue

##Adding an image to the search results

So now the search is working. But I wanted to go a step further and include a post.image as a graphic alongside the search result. For every post made, I add an image to the post frontmatter. You can read about how I achieved this in a previous post.

To add a post.image to the search turned out to be really trivial and only required a slight change to the search.js.

Now because the search.js has been minified, you will need to deminifiy it to make the code change. Here’s how;

  • Open the search.js file and copy the entire contents. Keep the file open as we want replace the contents shortly.
  • Go to jsbeautifier.org
  • Paste the contents into the top window
  • Click ‘Beautify JavaScript or HTML code’

Jump to the bottom of the code and look for

searchResultTemplate: '<li><a href='{url}' title='{desc}'>{title}</a></li>',

Change it to read

searchResultTemplate: '<img src="{image}"></img><li><a href="{url}" title="{desc}">{title}</a></li>',
  • Select all and copy the entire contents to clipboard
  • Go to jscompress.com
  • Paste the unminified JavaScript into the window and select ‘Compress JavaScript’
  • In the resultant window copy the entire contents to clipboard and then replace the entire contents of your search.js
  • Save the file
  • Perform a jekyll build of the site and voila!

##Check out the results

Go to your blog and perform a search. Below is an example of how it looks on this blog.

Performing a search

I hope you found this post useful and if you have any issues getting this working on your site please leave a comment and i’ll try to help.