【a-blog cms】拡張アプリで管理画面を作成するための InjectTemplate クラスの使い方解説

今回のブログでは、a-blog cms の拡張アプリで管理画面を作成するための InjectTemplate クラスの使い方を解説します。InjectTemplate クラスを使用することで自分で実装したモジュールのモジュールID設定画面が簡単に作成できる他、拡張アプリ専用の管理画面まで作れてしまいます。a-blog cms の拡張アプリを自分で作ってみたい! という方はぜひ読んでいってください💁🏻

InjectTemplate クラス

まずは InjectTemplate クラスの概要と基本的な使い方について説明していきます。

InjectTemplate クラスの概要

InjectTemplate クラスとはその名の通り、テンプレートを注入するためのクラスです。テンプレートの特定の場所に指定したテンプレート(html)を注入します。InjectTemplate の機能があることで、拡張アプリ側で自由に管理画面を作成することができます。

InjectTemplate クラスの使い方

InjectTemplate クラスの使い方を説明します。InjectTemplate クラスは以下のように記述することで使用できます。

$inject = InjectTemplate::singleton();
$inject->add('admin-module-select', PLUGIN_DIR . 'SamplePlugin/template/module-select.html');

詳しく解説していきます。

$inject = InjectTemplate::singleton();

まず、InjectTemplate::singleton() の部分で InjectTemplate クラスのインスタンスを取得しています。

$inject->add('admin-module-select', PLUGIN_DIR . 'SamplePlugin/template/module-select.html');

次に、InjectTemplate クラスの add メソッドを実行しています。InjectTemplate クラスの add メソッドは引数を2つ取ることができます。1つ目はテンプレートを注入する場所、2つ目は注入したいテンプレートのパスです。つまり、上記のコードでは、admin-module-select という場所に extension/plugins/SamplePlugin/template/module-select.html を注入するという意味になります。

ここで不思議に思う方もいるかと思います。そもそも admin-module-select という場所とはテンプレート上のどの場所を指しているのでしょうか?それは、テンプレート上で以下のコードが記述されている部分です。

<!-- BEGIN_MODULE Admin_InjectTemplate id="admin-module-select" --><!-- END_MODULE Admin_InjectTemplate -->

↑ のコードは themes/system/admin/module/select.html に記述されています。この id="" の部分が注入先を表す識別子です。system テーマ内のテンプレートファイル上には↑のような Admin_InjectTemplate モジュールのコードがいくつか記述されていますので、基本的には用意されている場所にテンプレートを挿入するという使い方になります。

しかし、拡張アプリによっては JavaScript を注入したいなどで、独自の注入先を定義したい場面があるかもしれません。そんな場合でも独自の識別子を定義することで、任意の場所にテンプレートを注入することができます。

例えば、今現在開発している square を利用した決済機能を拡張できる拡張アプリでは、以下のようにAdmin_InjectTemplate モジュールのコードを拡張アプリ使用者が任意に場所に記述することで square との決済に必要な JavaScript を注入しています。

<!-- BEGIN_MODULE Admin_InjectTemplate id="square-header" -->
<!-- END_MODULE Admin_InjectTemplate -->

拡張アプリ側のソースコードとしては以下になります。

$inject = InjectTemplate::singleton();
$inject->add('square-header', PLUGIN_DIR . 'ShoppingCart/template/squareHeader.html');

このように、InjectTemplate の機能を使用することで、テンプレート上の任意の場所にテンプレートを注入することもできるようになります。

自作モジュールのモジュールID設定画面を実装する

ここからは応用編ということで、先程説明した InjectTemplate の機能を使用して、自作モジュールのモジュールID設定画面を実装してみます。

モジュールID設定画面を作成する場合のテンプレート注入先の id は最初から用意されています。admin-module-config-モジュール名 の識別子でテンプレートを注入することで自作モジュールのモジュールID設定画面を実装することができます。例えば、Sample という名前の自作モジュールを実装した場合は、ServiceProviderの initメソッド 内で以下のように記述します。

$inject = InjectTemplate::singleton();
$inject->add('admin-module-config-Sample', PLUGIN_DIR. 'Sample/template/sample_body.html');

また、注入する設定画面のテンプレートですが、system テーマ内にあるビルトインモジュールのモジュールID設定画面のテンプレートを利用するのが良いかと思います。ビルトインモジュールのモジュールID設定画面のテンプレートは基本的に system/admin/config/ ディレクトリの中にあります。

例えば、Entry_Summary を拡張した自作モジュールを作成した場合は、system/admin/config/entry/summary_body.html を拡張アプリ内にコピペしてきて、自作モジュール用に調整するのがおすすめです。

ただ、自作モジュールのモジュールID設定画面を実装する際には少し注意が必要な点があります。それは、以下のコードです。

<!-- BEGIN_MODULE Admin_Rule_Name -->
<input type="hidden" name="rid" value="{rid}" /><!-- END_MODULE Admin_Rule_Name --><!-- BEGIN_MODULE Admin_Module_Name -->
<input type="hidden" name="mid" value="{mid}" /><!-- END_MODULE Admin_Module_Name --><!-- BEGIN_MODULE Admin_Config_Set_Name -->
<input type="hidden" name="setid" value="{setid}" /><!-- END_MODULE Admin_Config_Set_Name -->

このコードは、設定のルール対応やコンフィグセット、モジュールID対応をするために記述されています。先程例として出した Entry_Summary のモジュールID設定画面のテンプレートにも最後の行に記述されています。このコードがないと、ルールやコンフィグセットによってモジュールIDの設定を分けている場合にうまく動作しなくなってしまいます。 また、モジュールIDの設定がそもそも保存できなくなってしまいます。

ビルトインモジュールのテンプレートであれば、上記のコードで良いのですが、InjectTemplate でモジュールID設定画面のテンプレートを注入する場合はそのままではうまく動いてくれません。表示側からモジュールIDの設定を変更しようとしても変更が反映されないのです。

ブラウザの開発者ツールで確認してみると、rid , mid, setid ともにすべての value 属性の値が空になっているためです。(ルール及びコンフィグセットを利用している場合)

僕の細かいことまでは理解していませんが、InjectTemplate で注入するテンプレートは実行順が通常と異なるらしく、モジュールをエスケープする必要があります。そのため先程の部分を以下のように書き換えます。

<!-- BEGIN_MODULE\ Admin_Rule_Name -->
<input type="hidden" name="rid" value="\{rid\}" /><!-- END_MODULE\ Admin_Rule_Name --><!-- BEGIN_MODULE\ Admin_Module_Name -->
<input type="hidden" name="mid" value="\{mid\}" /><!-- END_MODULE\ Admin_Module_Name --><!-- BEGIN_MODULE\ Admin_Config_Set_Name -->
<input type="hidden" name="setid" value="\{setid\}" /><!-- END_MODULE\ Admin_Config_Set_Name -->

↑ のようにモジュールのエスケープをすることで、表示側からのモジュールIDの設定変更が反映されるようになります。

まとめ

今回の内容はこれで以上になります。みなさんも InjectTemplate を利用して独自の管理画面を実装してみてください😌