:私はのようなものを使用することにより、完全なテンプレート文字列を望んでいないテンプレート
<@loop>My name is ${name}</@loop>
実装
public class LoopDirective implements TemplateDirectiveModel{
public LoopDirective() {
}
public void execute(Environment env,
Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body)
throws TemplateException, IOException {
System.out.println(body);
// I want to print "My name is ${name}"
}
}
で
使い方${name}
を解決したくない場合は(TemplateDirectiveBody
API)。あなたはそれをすることができないはずです。しかし、私はあなたが汚れたトリックを引くことができると思う、源の位置をenv.getCurrentDirectiveCallPlace()
から得ることによって。今では元のソースコードのどの部分を切り捨てる必要があるのか分かりますが、区切りタグが含まれているので、独自のプログラムロジックでそれらを削除する必要があります(単純な構文解析のビット...)。理論的には、テンプレートのソースコードを取得している時点で、Template
オブジェクトにはそのようなものはありません。しかし、いくつかの悪い遺産のおかげで、あなたはTemplate.getSource(int, int, int, int)
を手に入れました。しかし、Configuration
にtabSize
を1に設定しない限り、タブはスペースで置き換えられます。知るべきもう一つのことは、Template.getSource
がやや遅い(メモリ内の文字をいくらか無駄にコピーする)、毎回区切りタグを削除する必要があるということです。しかし、スピードの問題は、DirectiveCallPlace.getOrCreateCustomData
を使用して回避することもできます。これにより、コールの最後にString
をキャッシュできます。
ありがとうございます。はい、私は '$ {name} 'を解決したくありません。 「あなたはそれをすることができないはずです」と言いますと、何らかの理由がありますか? また、[getChildrenBuffer](https://github.com/apache/incubator-freemarker/blob/2.3-gae/src/main/java/freemarker/core/Environment.java#L2807)がここで公開されていないのでしょうか? Template.getSource(int、int、int、int)は私を助けません。私がカスタムディレクティブを使ってやろうとしていることは、ネストを避けることですが、繰り返しが可能です。 有効 <@loop> $ {ABC}@loop><@loop> $ {XYZ}@loop> <@loop>無効$ {ABC} <@loop> $ {XYZ}@loop>@loop> –
さて、あなたは値を代入するテンプレート言語を指示した場合、それはむしろですその動作を抑止するのに珍しいことであり、(文書化された動作を変更したので)テンプレートを読んだ人には混乱します。しかし、私はあなたが達成したいことを理解していません。実行時にグローバル変数をチェックして、 'loop'を' loop'にネストすることを禁止することができます。それはなぜ$ {exp} 'を解決しないことに関連していますか? AST API-s、特に'getChildrenBuffer'は、実装レベルの低い実装です。 – ddekany
返信いただきありがとうございます。実行時にグローバル変数をチェックしながら 'loop'を' loop'に入れ子にすることをどうやって禁止できますか? 私たちはユーザーからのテンプレートを受け入れています。無限ループやあまりにも多くの繰り返しを避けたいというセキュリティのためです。ループの最大反復回数を制御することができる '#list'のようなカスタムループ指令「<@loop>」を作成しており、ネストを制限することもできます。つまり、「<@loop><@loop>@loop><@/loop>」です。しかし、 '<@loop>@loop><@loop>@loop>'のような繰り返しが必要です。 –