Node-RED 環境に標準で提供されている標準ノードの1つに template ノードがあります(下図赤枠):
この template ノードは次のノードへ送る msg.payload (など)の値をテンプレートをベースに、一部を変数化して生成するノードです。HTML の一部を変数化して扱いたいとか、最近だと生成 AI のプロンプトを作成する際のテンプレートとしても便利に使えるので、今後活用の機会があるかもしれません。
ところで、この template ノードの標準記法として設定されているのが mastache (「マスタッシュ」)記法というものです:
この mastache 記法でどんなことができるのか調べてみました。以下で3つの方法を紹介しますが、とりあえず以下のようなシンプルなフローを作っておきます。inject -> function -> template -> debug の各ノードを一直線につないだだけのシンプルなフローです:
このうち inject ノードは単に処理をスタートさせるためのスイッチとしてだけ使うのであまり意味はありません(このノードの左にある部分をクリックするとフローが実行されます)。また最後の debug ノードはデフォルトで msg.payload の内容を画面右側のデバッグウィンドウに出力するのですが、これもデフォルトのままで大丈夫。つまりこの2つは特に設定変更しません。
そして2つ目の function ノードをダブルクリックして編集状態にして、以下の内容を記載します:
この3つのノード(inject, function, debug)はこの後特に変更しません。 以下で mastache 記法にちうて3つの方法を紹介しますが、全て上述の内容の msg を受け取る仮定として、 template ノードのみ変更して動作を確認していきます。
【テンプレート内に1つの値を指定する場合】
まずはシンプルな例を紹介します。template ノードを開き、以下の内容を記入してください:
そしてこの状態でフローをデプロイし、inject ノードをクリックしてフローを実行します。すると画面右のデバッグペインには以下のように表示されます:
msg オブジェクトの一部が変数としてテンプレートの中を埋めて出力されていることがわかると思います。普通の変数であれば {{ と }} でメッセージ内の値を指定することで表示できそうですね。
ちょっと気になる点があるとすれば "payload.value2" の値でしょうか。そのまま HTML で使えるように一部文字がエスケープされた状態になっています。このエスケープが不要である場合は {{ と }} ではなく、 {{{ と }}} で囲うようにするだけです。試しに template の内容を以下のように書き換えてみます:
そしてフローを再デプロイし、inject ノードで処理を実行すると、今度は文字列がエスケープされずにそのまま表示されます:
【テンプレート内に配列値を指定する場合】
テンプレート内に1つ1つの値を個別に直接指定する方法は上述のような方法でした。では「配列」を扱う場合、テンプレート内にどのように記述するべきでしょうか? 今回の場合だと msg.array1 が配列になっているので、これをどのように列挙するか? というケースを考えます。
その答がこれです。template の内容を以下のように変更します:
この template でデプロイして inject ノードをクリックして処理が実行されると、デバッグ画面に下図のような結果(msg.array1 の配列の内容が1行ずつ表示)が出力されます:
このようにテンプレート内で {{#配列名}} と {{/配列名}} で括り、その中で {{.}} と指定すると配列内の各要素が表示されました。
【テンプレート内に JSON 配列を指定する場合】
最後にテンプレート内で「 JSON オブジェクトの配列」を扱う場合を考えます。 今回の場合だと msg.array2 が JSON 配列になっているので、これをどのように列挙するか? というケースを考えます。
その答がこれです。template の内容を以下のように変更します:
この template でデプロイして inject ノードをクリックして処理が実行されると、デバッグ画面に下図のような結果(msg.array2 の JSON 配列の name 要素が1行ずつ表示)が出力されます:
このようにテンプレート内で {{#配列名}} と {{/配列名}} で括り、その中で {{要素名}} と指定すると JSON 配列内の特定の要素を表示できました。
【まとめ】
Node-RED のテンプレートとしての template ノードはあまり使う機会がなかったのですが、うまく使うとプロンプトエンジニアリングのプロンプト作り(サンプル作り)のテンプレートに使えそうだな、という印象を受けています。この方法でサンプルを列挙するようなプロンプトを生成して、その結果を拙作の watsonxai ノード(https://flows.nodered.org/node/node-red-contrib-dotnsf-watsonxai)に渡して問い合わせする、といった使い方ができるのではないかと考えています:
mastache 記法はここで紹介した内容以外にもいろいろな記法があります。詳しくは以下のページを参照ください。とてもわかりやすく、自分の理解にも使わせていただいたページです。
【参照】
mustache記法について簡単にまとめてみた
この template ノードは次のノードへ送る msg.payload (など)の値をテンプレートをベースに、一部を変数化して生成するノードです。HTML の一部を変数化して扱いたいとか、最近だと生成 AI のプロンプトを作成する際のテンプレートとしても便利に使えるので、今後活用の機会があるかもしれません。
ところで、この template ノードの標準記法として設定されているのが mastache (「マスタッシュ」)記法というものです:
この mastache 記法でどんなことができるのか調べてみました。以下で3つの方法を紹介しますが、とりあえず以下のようなシンプルなフローを作っておきます。inject -> function -> template -> debug の各ノードを一直線につないだだけのシンプルなフローです:
このうち inject ノードは単に処理をスタートさせるためのスイッチとしてだけ使うのであまり意味はありません(このノードの左にある部分をクリックするとフローが実行されます)。また最後の debug ノードはデフォルトで msg.payload の内容を画面右側のデバッグウィンドウに出力するのですが、これもデフォルトのままで大丈夫。つまりこの2つは特に設定変更しません。
そして2つ目の function ノードをダブルクリックして編集状態にして、以下の内容を記載します:
msg = { payload: { value0: "0", value1: 1, value2: "<b>2.0</b>" }, value1: 1, value2: 2.2, array1: [ 2, 3, 5, 7, 11, 13, 17, 19 ], array2: [ { name: "apple" }, { name: "orange" }, { name: "grape" } ] } return msg;
この3つのノード(inject, function, debug)はこの後特に変更しません。 以下で mastache 記法にちうて3つの方法を紹介しますが、全て上述の内容の msg を受け取る仮定として、 template ノードのみ変更して動作を確認していきます。
【テンプレート内に1つの値を指定する場合】
まずはシンプルな例を紹介します。template ノードを開き、以下の内容を記入してください:
payload.value0 = {{payload.value0}} payload.value1 = {{payload.value1}} payload.value2 = {{payload.value2}} value1 = {{value1}} value2 = {{value2}}
そしてこの状態でフローをデプロイし、inject ノードをクリックしてフローを実行します。すると画面右のデバッグペインには以下のように表示されます:
payload.value0 = 0 payload.value1 = 1 payload.value2 = <b>2.0</b> value1 = 1 value2 = 2.2
msg オブジェクトの一部が変数としてテンプレートの中を埋めて出力されていることがわかると思います。普通の変数であれば {{ と }} でメッセージ内の値を指定することで表示できそうですね。
ちょっと気になる点があるとすれば "payload.value2" の値でしょうか。そのまま HTML で使えるように一部文字がエスケープされた状態になっています。このエスケープが不要である場合は {{ と }} ではなく、 {{{ と }}} で囲うようにするだけです。試しに template の内容を以下のように書き換えてみます:
payload.value0 = {{payload.value0}} payload.value1 = {{payload.value1}} payload.value2 = {{{payload.value2}}} value1 = {{value1}} value2 = {{value2}}
そしてフローを再デプロイし、inject ノードで処理を実行すると、今度は文字列がエスケープされずにそのまま表示されます:
【テンプレート内に配列値を指定する場合】
テンプレート内に1つ1つの値を個別に直接指定する方法は上述のような方法でした。では「配列」を扱う場合、テンプレート内にどのように記述するべきでしょうか? 今回の場合だと msg.array1 が配列になっているので、これをどのように列挙するか? というケースを考えます。
その答がこれです。template の内容を以下のように変更します:
{{#array1}} {{.}} {{/array1}}
この template でデプロイして inject ノードをクリックして処理が実行されると、デバッグ画面に下図のような結果(msg.array1 の配列の内容が1行ずつ表示)が出力されます:
このようにテンプレート内で {{#配列名}} と {{/配列名}} で括り、その中で {{.}} と指定すると配列内の各要素が表示されました。
【テンプレート内に JSON 配列を指定する場合】
最後にテンプレート内で「 JSON オブジェクトの配列」を扱う場合を考えます。 今回の場合だと msg.array2 が JSON 配列になっているので、これをどのように列挙するか? というケースを考えます。
その答がこれです。template の内容を以下のように変更します:
{{#array2}} {{name}} {{/array2}}
この template でデプロイして inject ノードをクリックして処理が実行されると、デバッグ画面に下図のような結果(msg.array2 の JSON 配列の name 要素が1行ずつ表示)が出力されます:
このようにテンプレート内で {{#配列名}} と {{/配列名}} で括り、その中で {{要素名}} と指定すると JSON 配列内の特定の要素を表示できました。
【まとめ】
Node-RED のテンプレートとしての template ノードはあまり使う機会がなかったのですが、うまく使うとプロンプトエンジニアリングのプロンプト作り(サンプル作り)のテンプレートに使えそうだな、という印象を受けています。この方法でサンプルを列挙するようなプロンプトを生成して、その結果を拙作の watsonxai ノード(https://flows.nodered.org/node/node-red-contrib-dotnsf-watsonxai)に渡して問い合わせする、といった使い方ができるのではないかと考えています:
mastache 記法はここで紹介した内容以外にもいろいろな記法があります。詳しくは以下のページを参照ください。とてもわかりやすく、自分の理解にも使わせていただいたページです。
【参照】
mustache記法について簡単にまとめてみた
コメント