Drupalでサイトを作っているとほとんどのページはDrupal標準機能で問題ないけれども、ある1ページはJavaScriptでがっつり作り込みが必要なんてことは結構ある。
DrupalのあるページにライブラリとしてReactを取り込んでレンダリングを試みた結果、まぁまぁイケるかもと思えたのでサンプルモジュール、参考にしたドキュメント、ポイントを以下にまとめます。
サンプルモジュール
https://github.com/kazukomurata/drupal-react-example
Demo Umami でインストール後、Githubをモジュールとしてインストールするとレシピコンテンツを難易度でフィルターするカスタムブロックが利用できます。
カスタムブロックでレンダリングするデータを取得し、drupalsettings を通してデータを渡しています。
JSON:APIを使って非同期にデータを取得しているわけではないです。
動作はこんな感じ。
参考にしたドキュメント
React
- Reactの公式ドキュメントのMAIN CONCEPTSを理解する
- Hello World 〜 Reactの流儀まで読んだ。今回のサンプルはその知識だけで作成。
- https://ja.reactjs.org/docs/hello-world.html
- ブラウザで使えるjsにするためにトランスパイル・バンドルの設定を用意する
- 書いたコードはBabelとかWebpackでトランスパイル・バンドルする必要があるため
- 参考
Drupal
- js,cssのライブラリ定義の知識
-
カスタムブロックの知識
ポイント
レンダリングのルートはDrupal.behaviorsに記述する
Reactを導入しても主体はDrupalにしたくて、Drupal.behaviors
を定義して、最初のレンダリングの発火タイミングを委ねた。コードはこちら。
jsファイルを集約対象外に指定する
JavaScript ファイルを集約する中にwebpackでバンドルしたjsを含めると動作しないことがあった。
モジュール名.libraries.yml にpreprocess: false
を指定した方がベター。
翻訳関数 Drupal.t() は別jsに記載する
Translating strings in JavaScript の Notes にもある通り、packed JavaScript files はDrupal.t()を通しても文字列が翻訳辞書収集の対象外になってしまう。
webpackでバンドルしないjsを用意して、翻訳辞書登録した方が良さそう。
Drupal.t()自体はReactのコードと一緒に使えるので、翻訳辞書登録だけしてしまえば問題ない。
最後に
サンプルを作ってReactの思想を触れられたのがよかった。JQueryでDOMをこねくり回すよりReactの方が保守性がいいと思います。
次はReactの公式ドキュメントを読み進めてJSON:APIで非同期処理にチャレンジかな。あとTypeScript化とかやりたい。