Как реализовать поиск Algolia в Drupal 9 (Часть 2)
Опубликовано: 2022-09-13В предыдущей главе этой серии мы провели вас через процесс настройки информационной панели Algolia и вашего сайта Drupal для индексации контента сайта в Algolia. В этой главе вы узнаете, как отображать результаты поиска Algolia на вашем веб-сайте Drupal.
Чтобы отобразить результат поиска, вам нужно будет создать пользовательский блок Drupal и разместить блок на странице /search . Кроме того, вы узнаете, как использовать библиотеку Algolia InstantSearch . Обратите внимание, что этот процесс предполагает, что у вас есть базовое понимание того, как создавать пользовательские модули в Drupal, поэтому мы не будем углубляться в процесс создания пользовательских модулей. Прочтите эту статью, чтобы узнать, как программно создавать пользовательские модули в Drupal 9.
Это вторая глава статьи из двух частей. Нажмите здесь, чтобы прочитать первую часть, где мы говорим о настройке Algolia и Drupal.
Создание пользовательского блока для интерфейса
Мы будем использовать следующую структуру для создания нашего пользовательского блока.
algolia_search_interface - js/ - algolia.js - src/ - Plugin - Block - DemoSearchBlock.php - templates/ - algolia_search_interface-block.html.twig - algolia_search_interface.info.yml - algolia_search_interface.libraries.yml - algolia_search_interface.module
Объявление библиотек
Как объяснялось ранее, для доступа к результатам поиска мы будем использовать библиотеку Algolia InstantSearch. Итак, давайте объявим все библиотеки в algolia_search_interface.libraries.yml, как показано ниже:
algolia-javascript: js: https://cdn.jsdelivr.net/npm/[email protected]/dist/algoliasearch-lite.umd.js : { type: external } https://cdn.jsdelivr.net/npm/[email protected] : { type: external } js/algolia.js: {preprocess: false} dependencies: - core/drupalSettings css: theme: https://cdn.jsdelivr.net/npm/[email protected]/themes/algolia-min.css: { type: external, minified : true }
Доступ и настройка переменных
В демонстрационном блоке поиска (DemoSearchBlock.php) мы просто получим доступ к переменным Algolia из конфигурации Drupal и назначим их drupalSettings, используя следующий код:
public function build() { // Get Algolia config. $config = $this->configFactory->get('search_api.server.algolia_search'); $app_id = $config->get('backend_config.application_id'); $api_key = $config->get('backend_config.api_key'); $index_name = $this->configFactory->get('search_api.index.vehicles_data')->get('options.algolia_index_name'); return [ '#theme' => 'demo_search_block', '#attached' => [ 'library' => 'algolia_search_interface/algolia-javascript', 'drupalSettings' => [ 'app_id' => $app_id, 'index_name' => $index_name, 'api_key' => $api_key, ], ], '#cache' => [ 'contexts' => [ 'url.path', 'url.query_args', ], ], ]; }
Добавить шаблон
Теперь вам нужно добавить шаблон для пользовательского блока. Итак, давайте определим hook_theme для нашего пользовательского блока в algolia_search_interface.module:
/** * Implements hook_theme(). */ function algolia_search_interface_theme($existing, $type, $theme, $path) { return [ 'demo_search_block' => [], ]; }
Определите контейнеры
Теперь давайте определим данные нашего шаблона для отображения результатов поиска. Мы просто определим контейнеры, в которых библиотека InstantSearch будет отображать результаты. Мы добавим 4 контейнера в algolia_search_interface-block.html.twig:
- Searchbox (#searchbox) - Search results (#hits) - Facets (#filter-widget) - Pagination (#pagination)
<div class="demo-instant-search"> <div class="algolia-searchbox"></div> <div class="align-left"> <div class="filter-header">{{ 'Manufacturer'|t }}</div> <div></div> </div> <div class="right-col"> <div></div> </div> </div> <div></div>
Отображение результатов поиска
Теперь у вас есть все ингредиенты, необходимые для отображения результатов поиска. Итак, давайте посмотрим, как использовать InstantSearch для отображения наших результатов.
Во-первых, давайте получим имя индекса, идентификатор приложения и ключ приложения из переменной drupalSettings. Нам нужно, чтобы они перешли к нашему API Algolia в algolia.js.
const index_name = drupalSettings.index_name; const app_id = drupalSettings.app_id; const api_key = drupalSettings.api_key;
Когда у вас есть ключи приложения и имя индекса, вам нужно инициализировать и запустить InstantSearch.
const search = instantsearch({ indexName: index_name, searchClient: algoliasearch(app_id, api_key), }); search.start();
На этом этапе вы не увидите никакой разницы на странице поиска, так как вы не добавили никаких виджетов в InstantSearch. Итак, давайте добавим в мгновенный поиск виджет окна поиска.
search.addWidget( instantsearch.widgets.searchBox({ container: '#searchbox', }) );
Обратите внимание, что мы использовали функцию addwidget() InstantSearch для добавления одного виджета. При использовании нескольких виджетов addwidget() невозможен. Вам нужно будет использовать его следующим образом:
search.addWidgets([ instantsearch.widgets.searchBox({ container: '#searchbox', }), instantsearch.widgets.hits({ container: '#hits' }), ]);
Теперь вы сможете видеть результаты поиска на странице поиска. Но, как мы видим, результат в очень сыром формате:
Чтобы уточнить это, давайте отформатируем результат, используя атрибут шаблона , как показано ниже:
instantsearch.widgets.hits({ container: '#hits', templates: { item: ` <h3 class="title">{{{title.value}}}</h3> <p class="detail"> {{{field_manufacturer}}} </p> <p class="uri">{{{uri}}} </p> `, }, }),
Обратите внимание, что хотя результат выглядит нормально, иногда нам нужно выполнить некоторую обработку данных, прежде чем отображать их на странице. Например, в приведенном выше коде значение URI имеет формат `public://` . Здесь мы можем использовать атрибут transformItems для изменения результатов в соответствии с нашим требованием.
instantsearch.widgets.hits({ container: '#hits', transformItems(items) { return items.map(item => ({ ...item, url: item.uri.replace('public://', /sites/default/files/'), })); }, templates: { item: ` <h3 class="title">{{{title.value}}}</h3> <p class="detail"> {{{field_manufacturer }}} </p> <p class="uri">{{{url}}} </p> `, }, })
Как только набор результатов будет готов, вы можете перейти к отображению данных фасетов, чтобы отфильтровать наши критерии поиска. Вы будете использовать ту же функцию addWidgets() для отображения фасетов.
search.addWidgets([ instantsearch.widgets. refinementList({ container: '#filter-widget, attribute: 'field_manufacturer', }), ]);
Опция атрибута определяет имя поля, относительно которого мы хотим отобразить фасет. Помните, что это также необходимо предварительно настроить на панели управления Algolia.
Наконец, давайте добавим нумерацию страниц, чтобы отображалось больше результатов.
search.addWidgets([ instantsearch.widgets. pagination({ container: '#pagination, }), ]);
И мы закончили! Вот так выглядит окончательный код
const index_name = drupalSettings.index_name; const app_id = drupalSettings.app_id; const api_key = drupalSettings.api_key; if(index_name && app_id && api_key) { const search = instantsearch({ indexName: index_name, searchClient: algoliasearch(app_id, api_key), }); search.addWidgets([ instantsearch.widgets.searchBox({ container: '#searchbox', }), instantsearch.widgets.hits({ container: '#hits', transformItems(items) { return items.map(item => ({ ...item, url: item.uri.replace('public://', '/sites/default/files/'), })); }, templates: { item: ` <h3 class="title">{{{_highlightResult.title.value}}}</h3> <p class="detail"> {{{_highlightResult.field_manufacturer.value}}} </p> <p class="uri"><img src="{{{url}}}" /></p>`, }, }), instantsearch.widgets.refinementList({ container: '#filter-widget', attribute: 'field_manufacturer', }), instantsearch.widgets.pagination({ container: '#pagination', }) ]); search.start(); } else { throw "Algolia settings missing";}
Последние мысли
Завершая нашу серию статей, состоящую из двух частей, мы надеемся, что вы получили достаточное представление об Алголии. Мы рассмотрели, как вы можете интегрировать поиск Algolia с Drupal, чтобы создать мощный поиск потребительского уровня. Мы также обсудили использование библиотеки InstantSearch для настройки результатов поиска. Ищете компанию, на 100% ориентированную на Drupal, которая может помочь вам создать амбициозный опыт Drupal, используя лучшее из Интернета? Мы хотели бы услышать от вас!