Интерактивный поиск для jekyll на jquery и json

Серверная часть

search.json

1
2
3
4
5
6
7
8
9
10
---
layout: null
---
[{% for post in site.posts %}{
      "title"    : "{{ post.title | escape }}",
      "category" : "{{ post.categories | join: ', ' }}",
      "tags"     : "{{ post.tags | join: ', ' }}",
      "url"      : "{{ site.url }}{{ post.url }}",
      "text"     : "{{ post.content | strip_html | remove:  '"' | strip_newlines | truncate:100 }}"
    }{% unless forloop.last %},{% endunless %}{% endfor %}]

Добавляем блок поска в нужные шаблоны в _layouts

1
2
3
4
  <div class="sb">
    <label for="searchbox">Быстрый поиск по сайту</label>
    <div class="is"><input type="text" name="search" id="searchbox" size="20" maxlength="20" value="Fast Search" class="inputbox" /></div>
  </div>

При желании, в зависимости от частоты обновления публикаций на сайте, можно настроить допустимое время кеширования файла, содержащего индекс для поиска

1
2
3
4
5
6
  location ~* ^(/search\.json)$ {
        expires 1h;     # час
        # expires 1d;   # день
        # expires 1w;   # неделя
        add_header Cache-Control "public";
  }

Клиентская часть js кода на jquery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$(document).ready(function(){
  $('div.sb').append('<div id="so"></div>');
  var _s = '';
  /* load search.json */
  var jsnf = "not";
  $("#searchbox").focus(function() {
    $(this).val('');
    if(jsnf == "not"){
      $('.sb>label').html('Loading search index');
    }
    if(_s.length == 0){
      $.getJSON( "/search.json" )
        .done(function( data ) {
          _s = data;
          jsnf = "ok";
          $('.sb>label').html('Ready');
          $("#searchbox").parent("div.is").addClass('ok');
      })
        .fail(function( jqxhr, textStatus, error ) {
          jsnf = "error";
          $('.sb>label').html('Fail');
          $("#searchbox").parent("div.is").addClass('fail');
      });
    }
  });
  $('#searchbox').keyup(function(){
    var searchField = $(this).val();
    if(searchField === '')  {
      $('#so').html('');
      return;
    }
    var regex = new RegExp(searchField, "i");
    var output = '';
    /* var count = 1; */
    $.each(_s, function(key, val){
        if ((val.title.search(regex) != -1) || (val.category.search(regex) != -1) || (val.tags.search(regex) != -1) || (val.text.search(regex) != -1)) {
            output += '<a href="' + val.url + '">' + val.title + '</a>';
            output += ' <span>path:(' + val.category + ')</span>'
            output += '<strong>tags:[' + val.tags + ']</strong><br>'
            output += '<em>' + val.text + '</em>'
            output += '<br>'
        }
        /* limit */
    });
    output += '<div class="tail"></div>';
    $('#so').html(output);
  });
});

Пример

Работу можно увидеть и проверить прямо на этом сайте, например внизу этой страницы.