`name` 作为 freemarker 中断中的变量名
Posted
技术标签:
【中文标题】`name` 作为 freemarker 中断中的变量名【英文标题】:`name` as a variable name in freemarker breaks 【发布时间】:2015-03-26 13:22:05 【问题描述】:我在 ftl 中有以下代码:
<#macro field label name value="" type="text">
$name
$name!"print if null"
<div class="field">
<div class="clearfix" id="$name_field">
<label for="$name">$label</label>
<div class="input">
<input type="$type" id="$name" name="$name" value="$value">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div>
</div>
</#macro>
<@field label="label" name="test" />
这是打印这个:
foo-test
test
<div class="field">
<div class="clearfix" id="foo-test_field">
<label for="foo-test">label</label>
<div class="input">
<input type="text" id="foo-test" name="foo-test" value="">
<span class="help-inline"></span>
<span class="help-block"></span>
</div>
</div>
</div>
foo-test
是我的应用程序的名称,但不明白为什么它会打印在那里.. 刚刚使用 ctrl+f 搜索foo-test
,它在 ftl 或控制器中无处...
除此之外,让我们假设name
是一个具有我的应用程序名称的变量。那么为什么第二个打印只打印我传递给我的宏的正确值?这真的很奇怪……
我使用 Maven 和 spark,所以我有这个依赖:
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-template-freemarker</artifactId>
<version>2.0.0</version>
</dependency>
插件是这样的:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<mainClass>com.example.foo.foo-test</mainClass>
</configuration>
</plugin>
</plugins>
</build>
我的控制器看起来像这样:
.....
import spark.ModelAndView;
import spark.Spark;
import spark.template.freemarker.FreeMarkerEngine;
......
Spark.get("/foo", (request, response) ->
Map<String, Object> attributes = new HashMap<>();
return new ModelAndView(attributes, "test.ftl");
, new FreeMarkerEngine());
【问题讨论】:
你在用maven吗? @AleksandrM 是的,这与此有关吗? 你如何在 maven 中打包/包含你的 ftl-s?你能显示你的 pom.xml 吗? @AleksandrM 我刚刚用信息更新了问题 显示你的 pomplugins
部分。
【参考方案1】:
发生这种情况是因为您已将 maven 配置为过滤资源,它确实将 $name
占位符替换为您的项目名称。
从您的 pom 中删除 <resources>
,或者如果您确实需要资源过滤,您可以排除 ftl-s 文件。
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
顺便说一句,关于resource filtering 的maven-resources-plugin
文档使用$name
占位符演示了这种行为。 :)
【讨论】:
就是这样!不敢相信 Maven 正在这样做..并且无法理解为什么只发生在宏内部..谢谢!!【参考方案2】:很奇怪......它应该可以工作,并且对我有用。我怀疑在 FreeMarker 解析它之前,在该模板中搜索并替换了 $name
(例如,自定义 TemplateLoader
-s 可以做到这一点)。比如,如果你写 $name<#-- just a comment -->
而不是 $name
会发生什么?
【讨论】:
你是对的。如果我写$name<#-- just a comment -->
,那么它会打印出我想要的内容。但是如果只在第一行打印$name
,它会抛出一个错误,即名称未定义。为什么这只发生在宏内部??
我不知道在 FreeMarker 得到它之前对模板文件应用了什么魔法......你能做一个System.out.println(template)
其中template
是fremarker.template.Template
对象来看看里面有什么模板?另外,那是什么 FreeMarker 版本($.version
)?我希望不是 10 年前的预览版......
或者更确切地说,System.out.println(template.getSource())
。
版本打印2.3.19
,对于模板,我不知道从哪里获得模板,因为它嵌入在 spark-template-freemarker 中..
2.3.19 是一个过时但稳定的版本,所以这不是问题。至于如何获取Template
对象,您可以做一个hack:实现TemplateDirectiveModel
,然后您可以从env.getTemplate()
获取它(至少如果它是***模板),并打印结果到env.getOut()
Writer
。然后在模板中调用这个指令,如<@'com.example.YourDirective'?new() />
。以上是关于`name` 作为 freemarker 中断中的变量名的主要内容,如果未能解决你的问题,请参考以下文章