This plugin replaces octopress google search functionality with lunr.js.
Heavily inspired by jekyll-lunr-search.
Move files into place in your octopress install directory while maintaining directory folder structure
This octopress plugin creates a search.json file and populates it with entries results collected from your website posts & pages.
You can decide to untrack unneeded pages by adding those to the EXCLUDED array:
EXCLUDE = ["Not found", "Internal Server Error", "Blog Archive", "store_bak", "Contact", "Search"]
The "source" folder contains the partials and libraries needed to run the plugin (feel free to edit those accordingly to your needs), each coffeescript file is compiled to js and compressed via yui thanks to the jekyll assets plugin. Here is a blog post with some useful instructions if you need some assitance on how to integrate it with your octopress install.
-
source/_assets: contains needed js libs & main search class.
-
source/_includes/custom/lunr-search: contains needed partials and handlebars template used to display your search results.
-
edit your _config.yml to enable lunr_search and disable simple_search
#_config.yml lunr_search: true simple_search: #http://google.com/search
-
edit template layout (this could vary depending on your own level of customization)
#source/_includes/navigation.html <ul class="subscription" data-subscription="rss{% if site.subscribe_email %} email{% endif %}"> <li><a href="{{ site.subscribe_rss }}" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li> {% if site.subscribe_email %} <li><a href="{{ site.subscribe_email }}" rel="subscribe-email" title="subscribe via email">Email</a></li> {% endif %} </ul> {% if site.simple_search %} <form action="{{ site.simple_search }}" method="get"> <fieldset role="search"> <input type="hidden" name="q" value="site:{{ site.url | shorthand_url }}" /> <input class="search" type="text" name="q" results="0" placeholder="Search"/> </fieldset> </form> {% endif %} {% if site.lunr_search == true %} {% include custom/lunr-search/search-form.html %} {% endif %} {% include custom/navigation.html %}
-
add /search page
Default search path for the form post action is "/search", be sure to create this page or change it together with the value passed to the constructor for the search object in case you want to use another value. Be sure to include entries.html
#source/search/index.markdown
---
layout: page
title: Search Results
footer: false
---
{% include custom/lunr-search/entries.html %}
-
add search-results handlebars partial via liquid into the head section of your page
# source/_includes/head.html {% include custom/lunr-search/search-results-template.html %}
Add dependencies to your app.js.coffee file (used to instantiate other libraries) via sprockets and instantiate a new LunrSearch search object when dom is ready.
# source/_assets/javascripts/app.js.coffee
# Following are plugin libraries.
#= require ./libs/jquery.min
#= require ./libs/lunr.min
#= require ./libs/handlebars
#= require ./libs/jXHR
#= require ./libs/URI.min
#= require lunr_search
# Following are octopress related (defaults).
#= require ./libs/swfobject-dynamic
#= require modernizr-2.0
#= require octopress
# Instantiate a new search when dom is ready.
$(document).ready ->
new LunrSearch '#search-query',
indexUrl: "/search.json",
results: "#search-results",
entries: ".entries",
template: "#search-results-template"
By default octopress is using ender.js as submodule library, so if you are using it in your own octopress install some modifications are needed to prevent conflicts. e.g.:
#source/_assets/javascripts/app.js.coffee
jQuery.noConflict() # prevents conflicts with Ender.js, use jQuery instead of $
jQuery ->
Handlebars.registerHelper "toLowerCase", (value) ->
(if (value and typeof value is "string") then new Handlebars.SafeString(value.toLowerCase()) else "")
<form action="/search" method="get">
<fieldset role ="search">
<input type="text" id="search-query" name="q" placeholder="Search" autocomplete="off" class="search" />
</fieldset>
</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.
<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.
{% raw %}
<script id="search-results-template" type="text/x-handlebars-template">
{{#entries}}
<article>
<h3>
<small><time datetime="{{date}}" pubdate>{{date}}</time></small>
<a href="{{url}}">{{title}}</a>
<p>tagged: {{ tags }} | category: <a href="/categories/{{category }}">{{category}}</a></p>
</h3>
</article>
{{/entries}}
</script>
{% endraw %}
Note the use of {% raw %}
and {% endraw %}
to ensure the HandleBars tags are not stripped out by Octopress.
Testing is possible thanks to jasmine, jasmine-jquery and jasmine-headless-webkit
To setup the bogus app and run the tests
-
Init and add octopress submodule
$: git clone git://github.com/yortz/jekyll-lunr-js-search.git $: cd jekyll-lunr-search $: git submodule init $: git submodule update
PLEASE NOTE! Since the officially-maintained jekyll-assets repo dropped liquid-preprocessing support (read more here) you have to freeze to v0.3.5 or to another version prior to dropped liquid-preprocessing support.
-
Run app
$: cd spec/javascripts/fixtures/app $: rake preview
Above step bootstraps octopress and runs search_generator.rb plugin, updating your public folder with a generated search.json file needed for the tests. You can close your app once public/search.json is generated.
Go back to your jekyll-lunr-search dir and start guard; it will automatically compile coffeescript files and watch for changes in your source and spec directories.
-
Guard
$: cd jekyll-lunr-search $: rake wc
##Demo
You can find a working demo at http://yortz.it/search
Credits go to slashdot's jekyll-lunr-search.