WordPressのエディタ上でAlgoliaの検索を動かす

検索結果がそんなに変わらないケースだと、毎回AlgoliaにAPIリクエスト飛ばしたくないなーと思うことがあります。

だいたいどこかにキャッシュしましょうということになるわけですが、今回は「WordPressのブロックエディタ上で検索を実行して、結果をDBに直接書き込む」というやりかたを試してみます。

カスタムブロックのコード

「とりあえず動かす」がゴールなので、いきなりコードです。

Algolia Instantsearch用のProviderコンポーネント

edit / saveどちらでもInstantsearchの機能やコンポーネントを使いますので、まずはラッパーを作ります。

import algoliasearch from 'algoliasearch';
import { Hits, InstantSearch, SearchBox } from 'react-instantsearch-dom';
const searchClient = algoliasearch('APP_ID','SEARCH_ONLY_API')
const AlgoliaProvider = ({children}) => {
    return (
        <InstantSearch searchClient={searchClient} indexName='YOUR_INDEX'>
            {children}
        </InstantSearch>
    )
}

attributesに検索結果をいれる

editsaveで個別にrenderが実行される(っぽい)ので、editで検索した結果をsaveで使えるようにattributesを用意します。

registerBlockType( 'examples/algolia-instantsearch-blocks', {
    attributes: {
        hits: {
            type: 'array'
        }
    },
....

Editに検索を実装する

editのコンポーネントにAlgolia Instantsearchを実装します。

import { connectHits, PoweredBy, SearchBox } from 'react-instantsearch-dom';

const CustomHits = connectHits(({hits, setAttributes}) => {
    setAttributes({hits})
    return (
        <ul>
            {hits.map(hit => (
                <li key={hit.objectID} dangerouslySetInnerHTML={{
                    __html: hit.post_title
                }}/>
            ))}
        </ul>
    )
})

registerBlockType( 'examples/algolia-instantsearch-blocks', {
...
    edit: (props) => (
    <AlgoliaProvider>
        <SearchBox />
        <CustomHits setAttributes={props.setAttributes} />
        <PoweredBy />
    </AlgoliaProvider>
    ),

HitのコンポーネントをconnectHitsで自前実装し、その中でsetAttributesすることで検索結果をattributesに渡しています。

Saveに検索結果を表示する

これだけだと、ただブロックエディタ上で検索ができるようになっただけなので、保存しましょう。

registerBlockType( 'examples/algolia-instantsearch-blocks', {
...
    save: (props) => (
    <AlgoliaProvider>
        <ul>
            {props.attributes.hits.map(hit => (
                <li key={hit.objectID} dangerouslySetInnerHTML={{
                    __html: hit.post_title
                }}/>
            ))}
        </ul>
        <PoweredBy />
    </AlgoliaProvider>
    ),

PoweredByはAlgoliaを無料で利用する場合に表示が必須なので、忘れずに入れましょう。

動かしてみる

実際に動かしてみましょう。エディタ側では検索フォームが表示され、入力に応じてリストが切り替わります。

保存して公開すると、記事側には検索結果のリストだけが表示されます。

表側ではAlgoliaを動かしていないですが、Algoliaを使って作ったHTMLなので、仮に問題がなかったとしても入れておいて方がいいかなと思います。

So what?

これだけだと「で?」って感じなのですが、作り込むといろいろできるかなとは思っています。

  • WooCommerceの商品を検索させて「おすすめ商品リスト」を簡単作成
  • RelatedItemsを使った関連記事表示
  • GeoSearch系を使って「その記事で紹介しているお店の近隣情報」を表示

とはいえこの方法の場合、「記事を更新しなければいつまでもデータが変わらない」という問題もあります。

商品の入れ替わりが激しいECなどでは、大人しくフロント側でもInstantsearchを実行してやる方が、「おすすめ商品にでてきたのに販売終了してるやん!」みたいなトラブルが起きなくて良いかなとは思います。

Comment