问题
I have the following code in an 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" />
And this is printing this:
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
is the name of my app but can't understand why is it being printed there.. Just used ctrl+f to search for foo-test
and it is nowhere in the ftl or the controller...
Besides this, let's suppose that name
is a variable that has the name of my app.. Then why the second print just prints the right value that i passed to my macro?? This is really strange...
I use Maven and spark so I have this dependency:
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-template-freemarker</artifactId>
<version>2.0.0</version>
</dependency>
The plugins are this:
<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>
And my controller looks like this:
.....
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());
回答1:
This is happening because you have configured maven to filter your resources, which it does substituting ${name}
placeholder with the name of your project.
Remove <resources>
from your pom or if you do need resource filtering you can exclude ftl-s files.
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
BTW the maven-resources-plugin
documentation about resource filtering demonstrates exact this behaviour with the ${name}
placeholder. :)
回答2:
Very strange... it should work, and works for me. I suspect that something search-and-replaces ${name}
in that template before FreeMarker parses it (custom TemplateLoader
-s can do that for example). Like, what happens if you write ${name<#-- just a comment -->}
instead of ${name}
?
来源:https://stackoverflow.com/questions/28178768/name-as-a-variable-name-in-freemarker-breaks