如何在 Drupal 9 中實現 Algolia Search(第 2 部分)
已發表: 2022-09-13在本系列的前一章中,我們向您介紹了配置 Algolia 儀表板和您的 Drupal 站點以索引 Algolia 上的站點內容的過程。 在本章中,您將學習如何在您的 Drupal 網站上顯示 Algolia 搜索結果。
要顯示搜索結果,您需要創建一個 Drupal 自定義塊並將該塊放在/search頁面上。 此外,您還將了解如何使用 Algolia 的InstantSearch庫。 請注意,此過程假設您對如何在 Drupal 中創建自定義模塊有基本的了解,因此我們不會深入探討創建自定義模塊的過程。 閱讀本文以了解如何在 Drupal 9 中以編程方式創建自定義模塊。
這是 2 部分系列文章的第二章。 單擊此處閱讀我們討論如何配置 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)中,我們將簡單地從 Drupal 配置中訪問 Algolia 變量,並使用以下代碼將它們分配給 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', ], ], ]; }
添加模板
現在您需要為自定義塊添加模板。 因此,讓我們在 algolia_search_interface.module 中為我們的自定義塊定義 hook_theme:
/** * Implements hook_theme(). */ function algolia_search_interface_theme($existing, $type, $theme, $path) { return [ 'demo_search_block' => [], ]; }
定義容器
現在,讓我們定義我們的模板數據來呈現搜索結果。 我們將簡單地定義 InstantSearch 庫將呈現結果的容器。 我們將在 algolia_search_interface-block.html.twig 中添加 4 個容器:
- 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 變量中獲取索引名稱、應用程序 ID 和應用程序鍵。 我們需要將它們傳遞給 algolia.js 中的 Algolia API。
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', }) );
請注意,我們使用了InstantSearch的addwidget()函數來添加單個小部件。 當使用多個小部件時, 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 有足夠的了解。 我們已經介紹瞭如何將 Algolia 搜索與 Drupal 集成以構建強大的消費級搜索。 我們還討論了使用 InstantSearch 庫來自定義搜索結果。 正在尋找一家 100% 專注於 Drupal 的公司,可以幫助您建立雄心勃勃的 Drupal 體驗,同時利用網絡的精華? 我們很樂意聽取您的意見!