`name` as a variable name in freemarker breaks

假如想象 提交于 2019-12-23 22:30:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!