Легкий и легкий плагин полнотекстового поиска в браузере на чистом JavaScript для Ghost (блог)
SearchinGhost — это легкая и расширяемая поисковая система, предназначенная для платформы блогов Ghost. По своей сути он использует Ghost Content API для загрузки контента вашего блога и мощную библиотеку FlexSearch для индексации и выполнения поисковых запросов.
Все происходит в клиентском браузере, это помогает нам предоставлять невероятно быстрые результаты поиска и отображать их в режиме реального времени для ваших пользователей (так называемый «поиск по мере ввода»). Мы также заботимся о минимизации нагрузки на сеть, полагаясь на то, что localStorage
браузера отправляет запросы только при необходимости.
Ваш блог ведется на кириллице, китайском, корейском, греческом, индийском или любом другом нелатинском языке? Не беспокойтесь, он поддерживается, см. специальный раздел.
БОНУС : если вам нравится эта концепция, но вы хотите установить ее быстро и легко (на самом деле менее чем за 3 минуты!), Посетите проект SearchinGhostEasy.
Прежде чем погрузиться в установку и настройку, попробуйте сами с помощью этой интерактивной демонстрации .
В этой демонстрации контент с возможностью поиска поступает из официального демонстрационного API Ghost (т. е. https://demo.ghost.io). Параметры установлены по умолчанию, поэтому каждое входное слово ищется в заголовке сообщения, тегах, отрывке и основном содержании.
Например, введите в поиск слово «мармелад». Его не существует ни в одном заголовке, отрывке или теге сообщения, но он используется один раз в статье «Вниз по кроличьей норе», поэтому в результате вы его получите.
Сначала обновите файл default.hbs
вашей темы, включив в него поле ввода и элемент вывода для отображения результатов поиска. Затем добавьте ссылку на скрипт SearchinGhost и инициализируйте его своим собственным CONTENT_API_KEY
. Чтобы получить ключ API контента, обратитесь к официальной документации Ghost.
< input id =" search-bar " >
< ul id =" search-results " > </ ul >
< script src =" https://cdn.jsdelivr.net/npm/[email protected]/dist/searchinghost.min.js " > </ script >
< script >
var searchinGhost = new SearchinGhost ( {
key : 'CONTENT_API_KEY'
} ) ;
</ script >
Вот и все, все готово! Если вам нужна более детальная конфигурация, прочтите следующие разделы.
Вы можете установить SearchinGhost различными способами, вот возможности:
Это самый простой и предпочтительный способ установки SearchinGhost. Добавьте один из этих скриптов в свою тему default.hbs
. Мы также рекомендуем использовать jsdelivr вместо unpkg из-за его надежности и производительности.
< script src =" https://cdn.jsdelivr.net/npm/[email protected]/dist/searchinghost.min.js " > </ script >
<!-- OR -->
< script src =" https://unpkg.com/[email protected]/dist/searchinghost.min.js " > </ script >
Если вы хотите обслуживать SearchinGhost со своего собственного сервера или включить его в процесс сборки, вы можете получить его из ресурсов страницы выпуска или загрузить файл dist/searchinghost.min.js
.
Установите SearchinGhost как зависимость проекта.
$ npm install searchinghost
# OR
$ yarn add searchinghost
Затем загрузите его из любого файла Javascript.
import SearchinGhost from 'searchinghost' ;
// OR
var SearchinGhost = require ( 'searchinghost' ) ;
Единственное обязательное поле конфигурации — key
. Любое другое поле имеет значение по умолчанию и становится необязательным.
SearchinGhost был разработан для работы «из коробки», эта минимальная конфигурация, но при этом мощная! При каждом нажатии клавиши он будет искать заголовок сообщения, теги, отрывок и контент. Это поведение по умолчанию, поскольку оно кажется наиболее распространенным.
// SearchinGhost minimal configuration
var searchinGhost = new SearchinGhost ( {
key : '<CONTENT_API_KEY>'
} ) ;
Тем не менее, небольшая дополнительная настройка может стоить того, чтобы соответствовать вашим потребностям. Допустим, вы хотите выполнить поиск только по title
и отобразить поля title
и published_at
для каждого найденного сообщения. Вы можете использовать эту конфигурацию:
var searchinGhost = new SearchinGhost ( {
key : '<CONTENT_API_KEY>' ,
postsFields : [ 'title' , 'url' , 'published_at' ] ,
postsExtraFields : [ ] ,
postsFormats : [ ] ,
indexedFields : [ 'title' ] ,
template : function ( post ) {
return `<a href=" ${ post . url } "> ${ post . published_at } - ${ post . title } </a>`
}
} ) ;
SearchinGhost легко настраивается и расширяется благодаря своей конфигурации. Не торопитесь, чтобы изучить каждый вариант из следующего раздела.
{
key : '' ,
url : window . location . origin ,
version : 'v3' ,
loadOn : 'focus' ,
searchOn : 'keyup' ,
limit : 10 ,
inputId : [ 'search-bar' ] ,
outputId : [ 'search-results' ] ,
outputChildsType : 'li' ,
postsFields : [ 'title' , 'url' , 'excerpt' , 'custom_excerpt' , 'published_at' , 'feature_image' ] ,
postsExtraFields : [ 'tags' ] ,
postsFormats : [ 'plaintext' ] ,
indexedFields : [ 'title' , 'string_tags' , 'excerpt' , 'plaintext' ] ,
template : function ( post ) {
var o = `<a href=" ${ post . url } ">`
if ( post . feature_image ) o += `<img src=" ${ post . feature_image } ">`
o += '<section>'
if ( post . tags . length > 0 ) {
o += `<header>
<span class="head-tags"> ${ post . tags [ 0 ] . name } </span>
<span class="head-date"> ${ post . published_at } </span>
</header>`
} else {
o += `<header>
<span class="head-tags">UNKNOWN</span>
<span class="head-date"> ${ post . published_at } </span>
</header>`
}
o += `<h2> ${ post . title } </h2>`
o += `</section></a>`
return o ;
} ,
emptyTemplate : function ( ) { } ,
customProcessing : function ( post ) {
if ( post . tags ) post . string_tags = post . tags . map ( o => o . name ) . join ( ' ' ) . toLowerCase ( ) ;
return post ;
} ,
date : {
locale : document . documentElement . lang || "en-US" ,
options : { year : 'numeric' , month : 'short' , day : 'numeric' }
} ,
cacheMaxAge : 1800 ,
onFetchStart : function ( ) { } ,
onFetchEnd : function ( posts ) { } ,
onIndexBuildStart : function ( ) { } ,
onIndexBuildEnd : function ( index ) { } ,
onSearchStart : function ( ) { } ,
onSearchEnd : function ( posts ) { } ,
indexOptions : { } ,
searchOptions : { } ,
debug : false
} ) ;
Ключ API общедоступного контента для получения доступа к данным блога.
пример:
'22444f78447824223cefc48062'
Полное доменное имя Ghost API.
пример:
'https://demo.ghost.io'
по умолчанию:
window.location.origin
Установите версию Ghost API. Работайте как с
'v2'
, так и с'v3'
.по умолчанию:
'v3'
Установите стратегию загрузки библиотеки. Он может срабатывать при загрузке HTML-страницы, по требованию, когда пользователь нажимает на панель поиска, или никогда.
Чтобы запустить инициализацию панели поиска самостоятельно, установите для этого значения значение
false
(логическое значение). Таким образом, вы сможете вызватьsearchinGhost.loadData()
когда остальная часть вашего кода будет готова.ожидаемые значения:
'page'
,'focus'
илиfalse
по умолчанию:
'focus'
Выберите, когда поисковый запрос должен быть выполнен. Для поиска при каждом нажатии клавиши пользователя и отправке формы используйте
'keyup'
. Чтобы выполнять поиск только тогда, когда пользователь отправляет форму с помощью кнопки или нажимает клавишу «Ввод», используйте'submit'
. Если вы хотите иметь полный контроль над ним из своего собственного кода JavaScript, используйтеfalse
(логическое значение) и выполните поиск самостоятельно, используяsearchinGhost.search("...")
.ожидаемые значения:
'keyup'
,'submit'
илиfalse
по умолчанию:
'keyup'
Установите максимальное количество сообщений, возвращаемых по поисковому запросу. Любое значение от
1
до50
будет молниеносным, а значения ниже1000
не должны сильно снижать производительность. Но помните: когда поисковая система достигает этого предела, она перестает копать и возвращать результаты: чем ниже, тем лучше.Хотя это настоятельно не рекомендуется, установите для этого значения значение
0
, чтобы отобразить все доступные результаты.по умолчанию:
10
[Устарело] До
v1.6.0
это поле былоstring
, такое поведение устарело.Ваш сайт может иметь одну или несколько строк поиска, каждая из которых должна иметь уникальный атрибут HTML
id
. Поместите каждыйid
панели поиска в этот массив. Не включайте в имя символ «#».Если вам не нужно какое-либо поле ввода, установите значение
[]
(пустой массив), а также установите дляsearchOn
значениеfalse
(логическое значение). Затем запустите поиск, используяsearchinGhost.search("<your query>")
.по умолчанию:
['search-bar']
[Устарело] До
v1.6.0
это поле былоstring
, такое поведение устарело.Ваш веб-сайт может использовать один или несколько элементов HTML для отображения результатов поиска. Этот массив ссылается на атрибут
id
всех этих выходных элементов. Если какой-либо из этих элементов уже имеет содержимое, оно будет перезаписано результатами поиска.Если вы используете платформу JS для отображения результатов поиска, установите для этого значения значение
[]
(пустой массив). Вы получите найденные сообщения в виде значения, возвращаемого функциейsearchinGhost.search("<your query>")
.по умолчанию:
['search-results']
[Устарело] До версии
v1.6.0
эти поля представляли собойstring
. это устарело.Каждый результат поиска помещается в дочерний элемент перед добавлением к родительскому элементу
outputId
. Тип по умолчанию —li
, но вы можете установить его для любого допустимого элемента HTML (см. документацию MDN).Если вы не хотите использовать элемент-оболочку для непосредственного добавления результатов
template
иemptyTemplate
к выходному элементу, установите значениеfalse
(логическое значение).по умолчанию:
'li'
Массив всех желаемых полей сообщений. Все эти поля станут доступны в функции
template
для отображения полезной информации о сообщениях.Обратитесь к официальной документации «поля».
Примечание. Если вы используете
'custom_excerpt'
, его содержимое будет автоматически помещено в'excerpt'
чтобы упростить создание шаблонов.по умолчанию:
['title', 'url', 'excerpt', 'custom_excerpt', 'published_at', 'feature_image']
Этот массив позволяет использовать дополнительные поля, такие как
tags
илиauthors
. Лично я не знаю, почему их нет с другими «полями», но Ghost API устроен именно так…Установите его значение
[]
(пустой массив), чтобы полностью отключить его.Обратитесь к официальной документации «include».
по умолчанию:
['tags']
Это соответствует API-интерфейсу Ghost API, который позволяет получать содержимое сообщений в формате HTML или в виде обычного текста.
Установите его значение
[]
(пустой массив), чтобы полностью отключить его.Пожалуйста, обратитесь к официальной документации «форматы».
по умолчанию:
['plaintext']
Список индексированных полей. Содержимое всех этих полей будет доступно для поиска.
Все значения в этом списке должны быть определены в сообщениях. В противном случае результат поиска не будет точным, но приложение не вылетит! Дважды проверьте значения
postsFields
,postsExtraFields
иpostsFormats
.ПРИМЕЧАНИЕ . В параметр
customProcessing
добавлено странное поле'string_tags'
. Если вы хотите использовать теги, эта уродливая вещь необходима (на данный момент), потому что FlexSearch не может правильно обрабатывать массивы. Если вам это не нравится/не нравится, переопределитеcustomProcessing
, чтобы возвращать толькоposts
без дополнительных изменений. Если вы решите использовать теги, используйте здесь также'string_tags'
.по умолчанию:
['title', 'string_tags', 'excerpt', 'plaintext']
Определите свой собственный шаблон результатов. Этот шаблон будет использоваться для каждого найденного сообщения для генерации результата и добавлен в качестве дочернего элемента к выходному элементу. Здесь нет шаблонизатора, только встроенная функция javascript, использующая объект
post
в качестве аргумента.Этот вариант шаблона намного мощнее, чем вы могли ожидать. Мы также можем думать об этом как о специальной функции обработки результатов поиска. Например, если вы хотите выполнить некоторую фильтрацию, ничего не возвращайте (например,
return;
) или пустую строку (например,return "";
), чтобы отбросить элемент.Обратите внимание на использование обратных кавычек (например, '`') вместо одинарных/двойных кавычек. Это необходимо для включения очень полезной интерполяции переменных JavaScript.
Доступные переменные — это те, которые определены в опции
postsFields
.пример:
template: function ( post ) { return `<a href=" ${ post . url } "># ${ post . tags } - ${ post . published_at } - ${ post . title } </a>` }
Определите свой собственный шаблон результатов, если результат не найден.
пример:
emptyTemplate: function ( ) { return '<p>Sorry, nothing found...</p>' }
Вам нужно внести дополнительные изменения в данные сообщений, полученные из Ghost? Используйте эту функцию, чтобы делать все, что вам нужно. Эта функция вызывается для каждого сообщения и выполняется после
onFetchEnd()
и передonIndexBuildStart()
.Если вы хотите удалить публикацию, верните любое ложное значение JS (например,
null
,undefined
,false
,""
, ...).Чтобы легко отлаживать входные/выходные данные, используйте
onFetchEnd()
иonIndexBuildEnd()
для отображения результата с помощьюconsole.log()
. Если вы более опытный пользователь, лучшим вариантом будет использование отладчика. Также не забудьте почистить локальный кеш при тестировании!Примечание : по умолчанию эта опция уже заполнена вспомогательной функцией, упрощающей использование поля «теги» в сообщениях. См. параметры
indexedFields
.пример:
customProcessing: function ( post ) { post . extra_field = "hello" ; return post ; }
Определите формат даты, полученный из сообщений.
Дополнительную информацию см. в справочнике MDN.
пример:
date: { locale : "fr-FR" , options : { weekday : 'long' , year : 'numeric' , month : 'long' , day : 'numeric' } }
Установите максимальный возраст кэша в секундах. В течение этого периода времени, если в локальном хранилище будет найден уже существующий индекс, он будет загружен без какого-либо дополнительного HTTP-запроса для подтверждения его достоверности. При очистке кеша значение сбрасывается.
Это особенно полезно для экономии широкополосной и сетевой нагрузки вашего сервера. Значение по умолчанию установлено на полчаса. Это значение основано на продолжительности сеанса пользователя по умолчанию, используемой аналитикой Google.
по умолчанию:
1800
Определите функцию обратного вызова, прежде чем мы получим данные из Ghost API.
Эта функция не принимает аргументов.
пример:
onFetchStart: function ( ) { console . log ( "before data fetch" ) ; }
Определите функцию обратного вызова после завершения выборки. Даже если изменения, внесенные в
posts
сохраняются, мы рекомендуем использовать для этого функциюcustomProcessing()
.Функция принимает один аргумент: массив всех сообщений, возвращаемых самим Ghost.
пример:
onFetchEnd: function ( posts ) { console . log ( "Total posts found on Ghost:" , posts . length ) ; }
Определите функцию обратного вызова, прежде чем мы начнем создавать индекс поиска.
Функция не принимает аргументов.
пример:
onIndexBuildStart: function ( ) { console . log ( "before building the index" ) ; }
Определите функцию обратного вызова после завершения построения индекса поиска.
Функция принимает один аргумент: объект индекса FlexSearch сборки.
пример:
onIndexBuildEnd: function ( index ) { console . log ( "index built:" , index ) ; }
Определите функцию обратного вызова перед началом выполнения поискового запроса. Например, его можно использовать для скрытия HTML-элемента результатов во время ожидания завершения
onSearchEnd
или для добавления каких-либо необычных эффектов перехода. Но в большинстве случаев в этом нет необходимости, поскольку функция поиска достаточно быстра и приятна для глаз.Функция не принимает аргументов.
пример:
onSearchStart: function ( ) { console . log ( "before executing the search query" ) ; }
Определите функцию обратного вызова, когда результаты поиска будут готовы.
Функция принимает один аргумент: массив совпадающих сообщений.
пример:
onSearchEnd: function ( posts ) { console . log ( "search complete, posts found:" , posts ) ; }
Добавьте дополнительную конфигурацию индекса поиска или переопределите настройки по умолчанию. Эти параметры будут объединены с уже предоставленными:
{ doc : { id : "id" , field : this . config . indexedFields } , encode : "simple" , tokenize : "forward" , threshold : 0 , resolution : 4 , depth : 0 }Также используйте этот параметр, чтобы включить поддержку нелатинских языков, см. этот раздел.
по умолчанию:
{}
Сделано для продвинутых пользователей, позволяет тонко настроить поисковые запросы. Обратитесь к документации FlexSearch.
Мы используем следующую конструкцию запроса:
index.search("your query", searchOptions)
поэтому все, добавленное вsearchOptions
будет передано во FlexSearch таким образом.Этот параметр может быть очень полезен при фильтрации сообщений по тегу. В качестве примера:
searchOptions: { where : { string_tags : "getting started" } }Также обратите внимание, что параметр
limit
Searchinghost автоматически объединяется с параметромsearchOptions
. В нашем случае это в конечном итоге будет выглядеть так:searchOptions: { where : { string_tags : "getting started" } , limit : 10 }по умолчанию:
{}
Если что-то работает не так, как ожидалось, установите значение
true
для отображения журналов приложений.по умолчанию:
false
Если в вашем блоге используется язык с латинским алфавитом (например, английский, французский, испанский) или язык Северной/Восточной Европы (например, немецкий, шведский, венгерский, словенский, эстонский), конфигурация по умолчанию будет работать нормально. В других случаях найдите подходящее значение indexOptions
и добавьте его в основную конфигурацию SearchinGhost.
Чтобы создать свои собственные настройки, обратитесь к README FlexSearch и этим трем вопросам.
Если у вас ничего не работает или полученное в результате поведение неправильное, смело создавайте проблему.
indexOptions: {
encode : false ,
rtl : true ,
split : / s+ /
}
indexOptions: {
encode : false ,
tokenize : function ( str ) {
return str . replace ( / [x00-x7F] / g , "" ) . split ( "" ) ;
}
}
Эту опцию можно использовать в любом языке слов, разделенных пробелами, в котором используются сложные символы.
indexOptions: {
encode : false ,
split : / s+ /
}
Если вам нужно использовать несколько типов языков (например, кириллицу/английский или индийский/испанский), используйте специальную конфигурацию ниже. Я знаю, на первый взгляд это может показаться пугающим, но просто скопируйте/вставьте его и поверьте мне.
indexOptions: {
split : / s+ / ,
encode : function ( str ) {
var regexp_replacements = {
"a" : / [àáâãäå] / g ,
"e" : / [èéêë] / g ,
"i" : / [ìíîï] / g ,
"o" : / [òóôõöő] / g ,
"u" : / [ùúûüű] / g ,
"y" : / [ýŷÿ] / g ,
"n" : / ñ / g ,
"c" : / [ç] / g ,
"s" : / ß / g ,
" " : / [-/] / g ,
"" : / ['!"#$%&\()*+,-./:;<=>?@[]^_`{|}~] / g ,
" " : / s+ / g ,
}
str = str . toLowerCase ( ) ;
for ( var key of Object . keys ( regexp_replacements ) ) {
str = str . replace ( regexp_replacements [ key ] , key ) ;
}
return str === " " ? "" : str ;
}
}
Сначала мы также попробовали другие решения: Lunr.js, minisearch и Fuse.js. В конце концов, FlexSearch предложил лучшие общие результаты с быстрыми и точными результатами, достаточно небольшим размером пакета, а также его было легко установить/настроить. Здесь есть все, что нужно выбрать!
Не беспокойтесь, это нормально. SearchinGhost использует систему кэширования для хранения данных вашего блога в браузере, ограничивая взаимодействие с сетью. По умолчанию кэшированные данные, сохраненные менее 30 минут назад, по-прежнему считаются действительными. По истечении этого времени новая статья будет вам доступна.
Имейте в виду, что другим пользователям, возможно, не придется ждать 30 минут в зависимости от того, когда они в последний раз проводили исследование. Если вы были 1 час назад, их кеш будет очищен и обновлен, поэтому статья появится.
Если вы хотите, чтобы ваши пользователи всегда были в курсе последних событий, установите для cacheMaxAge
значение 0
. При этом вам также следует установить для loadOn
значение 'focus'
чтобы ограничить количество HTTP-запросов.
По умолчанию, когда вы используете переменную URL-адреса feature_image
для отображения изображений в результатах поиска, вы всегда получаете исходное/полноразмерное изображение, и они, как правило, слишком велики (по размеру и весу) для наших нужд, лучше использовать миниатюру. соответствовать.
Начиная с Ghost V3, в него встроен механизм обработки мультимедиа для создания адаптивных изображений. По умолчанию Ghost воссоздает 6 разных изображений данного. Доступные размеры: w30
, w100
, w300
, w600
, w1000
, w2000
.
В нашем случае самый простой способ ускорить загрузку изображений — просто использовать изображения меньшего размера. По сути, мы хотим, чтобы этот URL-адрес https://www.example.fr/content/images/2020/05/picture.jpg
(по умолчанию, полученный из Ghost API) стал https://www.example.fr/content/images/size/w600/2020/05/picture.jpg
(ширина 600 пикселей).
Для этого обновите конфигурацию, добавив поле "customProcessing"
со следующим примером кода. Конечно, вместо w600
вы можете использовать любой из доступных размеров, упомянутых выше.
customProcessing: function ( post ) {
if ( post . tags ) post . string_tags = post . tags . map ( o => o . name ) . join ( ' ' ) . toLowerCase ( ) ;
if ( post . feature_image ) post . feature_image = post . feature_image . replace ( '/images/' , '/images/size/w600/' ) ; // reduce image size to w600
return post ;
}
Это изменение не происходит немедленно: вам нужно обновить кэш, чтобы увидеть разницу.
Создайте элемент HTML с идентификатором "search-counter"
и используйте функцию onSearchEnd()
чтобы заполнить его результатом. Вот пример:
< p id =" search-counter " > </ p >
onSearchEnd: function ( posts ) {
var counterEl = document . getElementById ( 'search-counter' ) ;
counterEl . textContent = ` ${ posts . length } posts found` ;
}
Да, используя внутренние методы SearchinGhost, но это возможно. Это может выглядеть как черная магия, но добавьте приведенный ниже код в вашу текущую конфигурацию. Здесь searchinGhost
относится к вашему собственному экземпляру, созданному с помощью new SearchinGhost(...)
.
emptyTemplate: function ( ) {
var allPostsArray = Object . values ( searchinGhost . index . l ) ;
var latestPosts = allPostsArray . slice ( 0 , 6 ) ;
searchinGhost . display ( latestPosts ) ;
}
Если вы используете такую структуру, как React, Vue или Angular, вы, вероятно, не захотите, чтобы SearchinGhost самостоятельно манипулировал DOM. Поскольку вам определенно необходимо поддерживать любое обновление контента в рамках вашей структуры, вам следует использовать следующую конфигурацию:
var searchinGhost = new SearchinGhost ( {
key : '<CONTENT_API_KEY>' ,
inputId : false ,
outputId : false ,
[ ... ]
} ) ;
Теперь, чтобы запустить поисковый запрос, вызовите метод SearchinGhost:
var postsFound = searchinGhost . search ( "my query" ) ;
// Where 'postsFound' content looks like:
[
{
"title" : "A Full and Comprehensive Style Test" ,
"published_at" : "Sep 1, 2012" ,
[ ... ]
} ,
{
"title" : "Publishing options" ,
"published_at" : "Aug 20, 2018" ,
[ ... ]
}
]
Таким образом, ничего не будет рендериться за вашей спиной и все останется под контролем в ShadowDom.
debug: true
onFetchStart()
, onSearchStart()
,... С этого момента любые изменения отслеживаются в этом специальном файле CHANGELOG.md.
Любой вклад более чем приветствуется! Если вы обнаружили ошибку или хотите улучшить код, пожалуйста, не стесняйтесь создавать проблему или PR.
Все обновления кода должны выполняться в каталоге src
.
Чтобы собрать проект самостоятельно, запустите:
$ npm install
$ npm run build
При разработке вместо этого используйте команду watch, она будет быстрее перестраиваться при каждом изменении файла и включать ссылку на исходную карту, что упрощает отладку.
$ npm run watch
Примечание. При создании этого проекта я использую Node v12.16.2 с NPM v6.14.4, но он также должен работать со старыми/новыми версиями.
SearchinGhost не единственный производитель поисковых плагинов Ghost. Вот краткий список других связанных проектов. Вам обязательно стоит попробовать их, чтобы увидеть, соответствуют ли они вашим потребностям:
GhostHunter (v0.6.0 - 101 КБ, gzip 26 КБ)
Плюсы:
- Самый известный, о нем много статей и уроков.
- Мощная система кэширования на основе localStorage.
- Полнотекстовая индексация (не только заголовка поста)
Минусы:
- Опирается на jQuery
- Работает только с API Ghost v2 (на данный момент)
- Исходный код со временем стал беспорядочным
призрак-поиск (v1.1.0 - 12 КБ, 4,2 КБ gzip)
Плюсы:
- Хорошо написанная и легко читаемая кодовая база
- Используйте «нечеткие» возможности
Минусы:
- Браузер подтормаживает при поиске длинных слов
- Может отправляться слишком много запросов API
- Не использует систему оценок для отображения лучших результатов первыми.
Ghost Finder (v3.1.2 - 459 КБ, gzip 116 КБ)
Плюсы:
- Чистая библиотека Javascript
Минусы:
- Огромный окончательный размер пакета
- Отправляйте HTTP-запрос для каждой нажатой клавиши!
- Не использует поисковую систему, ищет только подстроки в заголовках сообщений.
- Неправильно индексирует подчеркнутые символы (например, «é» следует искать вместе с «e»)