HubDB(動的ページ生成)
前回のページでは、HubDBの基本的な使い方を解説しました。今回はもう一歩踏み込んで、HubDBで行ごとにページを生成する方法を解説します。この機能を用いると「体裁はほぼ同じで、大量にページがある」というようなコンテンツをとても管理しやすくなります。
今回の例では、前回のページで作成した「拠点一覧」のテーブルを使用して、
- 東京オフィス(https://www.pensees.co.jp/offices/tokyo)
- 札幌オフィス(https://www.pensees.co.jp/offices/sapporo)
- リモートワーク(https://www.pensees.co.jp/offices/remote)
の3ページを動的に生成する形で解説していきます。
なお上記URLはあくまで解説用であり、実際に弊社のページに上記ページはありません。
目次
HubDBでページを生成するメリット・デメリット
もちろん上記の要件はブログ機能を用いても実装することはできますが、ブログの場合はページを編集するのに、毎回各ページの編集画面を開かなければなりません。
これがHubDBだと、1つのHubDBのテーブル編集画面で複数のページのコンテンツを編集することができます。大幅な業務効率の改善が期待できますね。また、やはりブログよりもデータを再利用しやすいのがHubDBのメリットです。
一方でブログと比較したときに、コンテンツの自由度が低いのはデメリットと言えるでしょう。自由にコンテンツを入力できるリッチテキストも用意はされていますが、ブログなどで使用するRich Textモジュールと比較するとかなり自由度は低いです。その辺りも含めて、解説してきます。
なお公式ドキュメントは、次のページが該当します。
Building Dynamic Pages with HubDB
動的にページを生成するための設定を行う
まずは動的ページ生成をするための設定を行います。設定ボタンをクリックし、ポップアップを表示します。
ポップアップが表示されたら
- パブリックAPIアクセスを許可
- 行データを使用して動的ページの作成が可能
の両方にチェックを入れます。
公式ドキュメントのキャプチャには「パブリックAPIアクセスを許可」にチェックが入っていないのですが、 私が検証する限り、ここにチェックが入っていないとページが生成されませんのでご注意ください。
動的ページ生成の仕組み
ここで、HubDBによる動的ページ生成の仕組みを解説します。先ほどHubDBテーブルの方で設定を変更し、データを登録しましたが、これだけでページが生成される訳ではありません。
まず言葉だけで説明すると、動的ページ生成を行うにはまず親ページを作成する必要があります。例えばこの親ページのURLを「https://www.pensees.co.jp/offices」としましょう。
この親ページの [設定] タブ内の詳細オプションの中に「HubDB 動的ページ用のテーブル」という項目があり、ここでHubDBテーブルを選択し、親ページを公開することで初めてHubDBテーブルの行ごとにページが生成されます。
また、HubDBから生成されるページは、親ページのURLの配下に生成され、またテンプレート側にも特別な記述をしていないと、ページは生成されてもコンテンツが出力されません。これを図でまとめると、次のようなイメージです。
つまりHubDBによる動的ページ生成は親ページに紐付くものであるため、例えば拠点一覧ページとは全く別のアバウトページ(/about)に拠点一覧テーブルを指定すると、aboutの配下にtokyo、sapporo、remoteのページがまた生成されることになります。
テンプレートの設定
HubDBの動的ページ生成の仕組みを理解したところで、テンプレートにそれ用の記述をしなければなりません。先述の概要図から、1つのテンプレートは
- 親ページの生成
- 動的ページの生成
の2つの役割を担っていますので、それぞれの挙動をテンプレート内にif文で記述します。基本としては次のような形になります。
{% if dynamic_page_route_level == 0 %} 親ページ用の処理 {% elif dynamic_page_route_level == 1 %} 動的生成ページ用の処理 {% endif %}
なお条件分岐は次のように書くこともできます。公式ドキュメントの基本形は次の書き方で紹介されていますが、子テーブルによる動的ページ生成には上記の記述が必要ですので、最初から上記の記述で進めます。
{% if dynamic_page_hubdb_row %} 動的生成ページ用の処理 {% elif dynamic_page_hubdb_table_id %} 親ページ用の処理 {% endif %}
親ページ用の設定
まずは親ページ用の設定からです。といっても、親ページの方は前回の解説とほぼ変わりません。拠点名の箇所の列名がnameからhs_nameに変わったのと、そこにa要素でリンクを貼っただけです。コードは次の通りです。
{% if dynamic_page_route_level == 0 %} <div class="bl_spaciousHorizTable"> <table> <tr> <th>拠点名</th> <th>住所</th> <th>電話番号</th> <th>拠点風景</th> <th>在籍スタッフ</th> </tr> {%- for row in hubdb_table_rows(1052147) -%} <tr> <th> {# 列名の変更とa要素の追加 #} <a href="{{ request.path }}/{{ row.hs_path }}">{{ row.hs_name }}</a> </th> <td>{{ row.address }}</td> <td>{{ row.tel }}</td> <td><img src="{{ row.img.url }}" alt="写真:{{ row.name }}拠点風景" width="200"></td> <td> {%- for staff in row.staff -%} {{ staff.name }}{% if not loop.last %}, {% endif %} {%- endfor -%} </td> </tr> {%- endfor -%} </table> </div> <!-- /.bl_spaciousHorizTable --> {% elif dynamic_page_route_level == 1 %} 動的生成ページ用の処理 {% endif %}
これで親ページの方は期待通りにデータが表示され、かつ動的ページも期待通りに生成されました。
動的生成ページ用の設定
次に動的生成ページ用の設定です。動的生成ページのコンテキストでは、HubDBテーブルの各行のデータは「dynamic_page_hubdb_row」というディクショナリ内に格納されています。そのため、次のようにコードを書くことでデータを展開することができます。なお前回に引き続き、CSSは本筋ではないため解説しません。
{% elif dynamic_page_route_level == 1 %} <div> <div> <h1>{{ dynamic_page_hubdb_row.hs_name }}</h1> <p>住所</p> <p>{{ dynamic_page_hubdb_row.address }}</p> <p>電話番号</p> <p>{{ dynamic_page_hubdb_row.tel }}</p> <p>在籍スタッフ</p> <p> {%- for staff in dynamic_page_hubdb_row.staff -%} {{ staff.name }}{% if not loop.last %}, {% endif %} {%- endfor -%} ほか </p> </div> <!-- /.bl_overlapBlock_txtBox --> <figure> <img src="{{ dynamic_page_hubdb_row.img.url }}" alt="写真:{{ dynamic_page_hubdb_row.hs_name }}拠点風景"> </figure> </div> <!-- /.bl_overlapBlock --> {% endif %}
表示は次の通りです。
実装方法の基本はこれだけです。思ったよりも、簡単と感じるのではないでしょうか。
子テーブルを使用してページを動的に生成する
HubDBによる動的ページ生成は、テーブルに子テーブルを指定することでさらに子ページを生成することができます。公式ドキュメントは次のページが該当します。
How to build multilevel dynamic pages with HubDB
例えば、ここまでの解説で出力されているページは次の通りです。
- 拠点一覧ページ:/offices(親ページ)
- 東京オフィス:/offices/tokyo(動的生成ページ)
- 札幌オフィス:/offices/sapporo(動的生成ページ)
- リモートワーク:/offices/remote(動的生成ページ)
ここで東京オフィス行、札幌オフィス行、リモートワーク行にそれぞれ子テーブルを設定することで、次のようなページの出力をすることが可能です。
- 拠点一覧ページ:/offices(親ページ)
- 東京オフィス:/offices/tokyo(動的生成ページ)
- 横山 倫洋:/offices/tokyo/yokoyama(動的生成子ページ)
- 杉山 友宏:/offices/tokyo/sugiyama(動的生成子ページ)
- ...
- 札幌オフィス:/offices/sapporo(動的生成ページ)
- 長澤 賢:/offices/sapporo/nagasawa(動的生成子ページ)
- 海老江 優太:/offices/sapporo/ebie(動的生成子ページ)
- ...
- リモートワーク:/offices/remote(動的生成ページ)
- 村上 泰徳:/offices/tokyo/murakami(動的生成子ページ)
- 東京オフィス:/offices/tokyo(動的生成ページ)
子テーブルを使用した動的ページを生成するには、まず親にあたるテーブル(拠点一覧テーブル)の設定で、「子テーブルの使用を許可」にチェックを入れます。
次の「子テーブルのリストページを自動的に作成」のチェックの有無による挙動は次の通りです。
- trueの場合
- 札幌オフィス:/offices/sapporo(○ 生成される)
- 長澤 賢:/offices/sapporo/nagasawa(○ 生成される)
- falseの場合
- 札幌オフィス:/offices/sapporo(× 生成されない)
- 長澤 賢:/offices/sapporo/nagasawa(○ 生成される)
更新ボタンをクリックすると、新たに「子テーブル」という列が追加されます。ここで、子ページの動的生成に使用したいHubDBテーブルを選択します。
注意点として、子テーブルもHubDBによる動的ページ生成の設定にチェックが入っている必要があります。また各行に子テーブルを設定するという仕様上、前回のHubDBの基本解説で作成したスタッフ一覧テーブルは今回の要件にそぐいません。そのため、
- 東京スタッフ一覧
- 札幌スタッフ一覧
- リモートワークスタッフ一覧
テーブルをそれぞれ作成しました。
例として、札幌スタッフ一覧テーブルの設定項目、データは次の通りです。
このような形で各子テーブルを公開したら、拠点一覧テーブルに戻り、子テーブル列にそれぞれ指定を行います。
これで拠点一覧テーブルをパブリッシュすると、この段階でページが生成されています。ただしテンプレート側で出力の制御をおこなっていないので、コンテンツは表示されません。次のキャプチャはhttps://www.pensees.co.jp/offices/sapporo/handa ページの表示です。
テンプレートの設定
子ページのコンテンツを出力するために、再度テンプレートを調整します。といっても難しいことはなく、基本は次の形です。
{% if dynamic_page_route_level == 0 %} 親ページ用の処理 {% elif dynamic_page_route_level == 1 %} 動的生成ページ用の処理 {% elif dynamic_page_route_level == 2 %} 動的生成 子ページ用の処理 {% endif %}
上記より、「elif dynamic_page_route_level == 2」のブロック内に出力のためのコードを書いていけばよいことになります。各行のデータへのアクセス方法は、動的ページ生成時と変わりません。大まかなコードと表示は、次の通りです。
{% elif dynamic_page_route_level == 2 %} <div> <p> <img alt="写真:{{ dynamic_page_hubdb_row.hs_name }}" src="{{ dynamic_page_hubdb_row.img.url }}"> </p> <div> <p>{{ dynamic_page_hubdb_row.job_title.name }}</p> <h1>{{ dynamic_page_hubdb_row.hs_name }}</h1> <p>{{ dynamic_page_hubdb_row.txt }}</p> </div> <!-- /.bl_profMedia02_body --> </div> <!-- /.bl_profMedia02 --> {% endif %}
これでひとまず、子ページの出力も完了しました。後は細かくコードを調整して導線を設定していくと、次のようにHubDBから生成したページを次々に遷移していくことが可能になります。
自由度の低いリッチテキスト
最後に1つ注意点として、HubDBのリッチテキストはウェブサイトページやブログポストで使用できるRich Textモジュールと比べて、自由度はかなり低くなっています。
ページごとに体裁が大幅に違ったり、デザイン性が求められると「HubDBを使用しているため実現できない」ということも起こり得ますので、体裁は統一的で問題ないか、事前にしっかりと確認してください。
まとめ
以上、HubDBによる動的ページ生成の基本から、応用の子ページ生成まで解説しました。
「体裁はあまり変わらないが、一定の法則に従って大量にページが必要」という場合にとても有効な方法ですので、ぜひ活用してみてください。