# PHPのフレームワークLaravelとAlgoliaで開発 その5

昨日に引き続き👇の Live Coding Session - Advanced Search with Laravel and Algolia by Nuno Maduro をやっています。

昨日は一通り環境が整ったところまで出来たので、今日はフロント側の開発を進めていきます。

# フロントエンドを作っていきます

いわゆるバックエンド実装ではなく、フロントエンド実装。具体的には👇

  • バックエンド実装: ブラウザからのリクエストは一旦PHPのサーバーで受けて、それを元にAlgoliaに検索リクエストをする
  • フロントエンド実装: ブラウザから直接検索リクエストをAlgoliaに投げる

ということで、

resouces -> vuews -> welcome.blade.php を編集していきます。

一旦諸々消して👇の状態にしてあげて、、

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
    </head>

    <body>
    </body>
    
</html>

この空となったviewに検索バーと商品情報を追加していきます。

今回はJavaScriptをCDNから取得して使う形で。👇をコピペで追加。詳細はInstantSearch.jsのページで。

<script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.0.0/dist/algoliasearch-lite.umd.js" integrity="sha256-MfeKq2Aw9VAkaE9Caes2NOxQf6vUa8Av0JqcUXUGkd0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.0.0/dist/instantsearch.production.min.js" integrity="sha256-6S7q0JJs/Kx4kb/fv0oMjS855QTz5Rc2hh9AkIUjUsk=" crossorigin="anonymous"></script>

そして、bodyの中にscriptタグで括って(JavaScriptを外出しにしないで中で使うことで👇のようにクレデンシャルをイイ感じに扱える)実装を進めていきます。

const searchClient = algoliasearch(
    '{{ config("scout.algolia.id") }}',
    '{{ Algolia\ScoutExtended\Facades\Algolia::searchKey(App\Product::class)  }}'
);

1つ目はAlgoliaのApplication IDで、これはPHPの設定から取得しますが、2つ目はSearch "only" API Keyであるべきで(フロント側に展開されるものだから)、それをScoutのAlgolia拡張を使ってイイ感じに。これにしておくと24時間でSearch Keyがローテーションされる仕掛けらしい。

indexの名前はproducts。

const search = instantsearch({
  indexName: 'products',
  searchClient,
});

ってことで、ここまででscriptタグの中身は👇こんな感じ。

      <script type="text/javascript">
        const searchClient = algoliasearch(
            '{{ config("scout.algolia.id") }}',
            '{{ Algolia\ScoutExtended\Facades\Algolia::searchKey(App\Product::class)  }}'
        );

        const search = instantsearch({
          indexName: 'products',
          searchClient,
        });

        search.addWidgets([
          instantsearch.widgets.searchBox({
            container: '#searchbox',
          }),

          instantsearch.widgets.hits({
            container: '#hits',
          })
        ]);

        search.start();
      </script>

そして、bodyタグの中に表示用のdivを追加していきます。

<div id="searchbox"></div>
<div id="hits"></div>

すると、、👇こんな感じでAlgoliaから取得したデータを表示させることができました 😃

search

んま、このままだとちょっと見た目があれなので、、、

# スタイリングしていきます

ってことで、こちらも有り物のヤツで…笑

👇のスタイルシートを使うようにします。

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7.3.1/themes/algolia-min.css" integrity="sha256-HB49n/BZjuqiCtQQf49OdZn63XuKFaxcIHWf0HNKte8=" crossorigin="anonymous">

すると、まぁ、それっぽくはなったかな的な👇

style

んで、ちょっとpaddingを入れたりしつつ、、

style="padding: 8px"

# hitsをイイ感じにしていく

ハイライトとかはとりあえずすっ飛ばして、InstantSearchのhitsウィジェットのテンプレートを使ってイイ感じに。

👇こんな感じで、titleをh2で、descriptionをparagraphで、値段が太字に。

instantsearch.widgets.hits({
  container: '#hits',
  templates: {
    item: `
      <h2>@{{ title }}</h2>
      <p>@{{ description }}</p>
      <strong>@{{ price }} $</strong>
    `,
  },
})

👇だいぶそれっぽい感じになりました 😃

template

# rangeSliderを導入する

簡単に値段で絞り込むヤツを追加できちゃうのよーってヤツ。

👇のようにrangeSliderというWidgetを追加して、

instantsearch.widgets.rangeSlider({
  container: '#range-slider',
  attribute: 'price',
  min: 0,
  max: 100
}),

👇のようにsearchboxとhitsの間にrange-slider用のdivを定義

<div id="searchbox" style="padding: 8px"></div>
<div id="range-slider" style="padding: 8px"></div>
<div id="hits" style="padding: 8px"></div>

👇サクっと導入できました!

range

# 最後にpaginationを追加

ページネーション用のwidgetを追加してあげて、1回に表示するのは4件までにしてそれ以降はボタンを押して遷移していく形。(個人的になんとなく4件だと寂しいので8件にしてみました。笑)

instantsearch.widgets.configure({
  hitsPerPage: 8,
}),

instantsearch.widgets.pagination({
  container: '#pagination',
}),

でもって、pagination用のdivをhitsの下に追加。

<div id="searchbox" style="padding: 8px"></div>
<div id="range-slider" style="padding: 8px"></div>
<div id="hits" style="padding: 8px"></div>
<div id="pagination" style="padding: 8px"></div>

ってことで👇こんな感じになりました 😃

pagination

# 完成版のムービー

このエントリーをはてなブックマークに追加

Algolia検索からの流入のみConversionボタン表示