1

次のフリーマーカー テンプレートがあります。

[#local snippet ][#noparse]
        [#assign out ]value: ${v}
        [/#assign]
    [/#noparse]
[/#local]
[#assign hook = snippet?interpret ]
...
[#macro trigger ]
    [@hook /]
[/#macro]
...
[#list values as v ]
    [@trigger ]
[/#list]
${out}

それが本質的に行うことは、後で特定の瞬間に実行するフックと、その実行をトリガーするマクロを定義することです。

このテンプレートをレンダリングしようとすると、次のエラーが発生します。

The following has evaluated to null or missing:
==> v  [in template "xxx.ftl->anonymous_interpreted" at line 1, column 17]

次の点に注意してください。

[#list values as v ]
    [@hook ]
[/#list]

つまり、期待どおりにテンプレートをレンダリングvalue: xxxし、リスト内の各値を出力します。

  • ここで何がうまくいかないのか誰か知っていますか?
  • これを期待どおりに動作させる方法はありますか?

編集

解釈されたスニペットの代わりに通常のマクロを渡すと、エラーが発生しないことがわかりました。

[#assign hook = myMacro ]
...

ただし、マクロが別の名前空間で定義されている場合はそうではありません。

4

1 に答える 1

3

ループ変数 ( ) は、基本的にブロックvのローカル変数です。#listしたがって、Java 風の疑似コードを使用すると、次のようになります。

void main() {
   for (int v : values) {
      trigger();
   }
}

void trigger() {
   print(v);  // Error, v is not visible here!
}

で定義されたディレクティブを呼び出すと、?interpret呼び出しの場所にコード スニペットをコピーして貼り付けたかのように動作しようとするため、これは特別です。つまり、呼び出すディレクティブは@hook独自のローカル コンテキストを作成しません。そのため、ループから直接v呼び出すかどうかを確認します。しかし、それを form と呼ぶと、独自のローカル コンテキストを持つマクロのローカル コンテキストに存在します。triggertrigger

それを機能させる時点で... 1つの可能性は、vを介して名前空間スコープ変数に割り当て、次に解釈されたフラグメントで<#assign value = v>参照することです。もちろん、別の解決策は、可能であれば、間接化valueを取り除くことです。triggerさらに別の解決策は、triggerwith?interpretの代わりに withを定義する#macroことです。triggervhook

于 2013-09-06T11:30:39.453 に答える