在 freemarker 模板中转义 #{{}}

escape #{{}} in freemarker template

我同时使用 angular js 和 freemarker,在模板中我写了一个 <a> 标签,其 href attr 以 # 开头,所以我可以配置路由在 angular 例如:

<a href="#/edit/user">

但是用angularJS模板写模板时,好像有一些冲突(freemarker语法和angularJS模板语法一起):

 <li ng-repeat="tab in tabs">
    <a href="#{{tab.url}}"> {{tab.title}} </a>
 </li> 

如果我像上面那样写,freemarker 模板将无法解析并出现此异常:

freemarker.core.ParseException: Parsing error in template "mis/newindex.ftl" in line 21, column 80:
Encountered "}", but was expecting one of:
    ","
    ":"
    "."
    "["
    "("
    "?"
    "!"
    <TERMINATING_EXCLAM>
    "??"
    "+"
    "-"
    "*"
    "/"
    "%"
    "!="
    "="
    "=="
    ">="
    <ESCAPED_GTE>
    ">"
    <ESCAPED_GT>
    <LESS_THAN_EQUALS>
    <LESS_THAN>
    ".."
    <AND>
    <OR>

我知道 #{{tab.url}} 应该是导致问题的原因,但我怎样才能绕过这个问题?


我通过在 angular 控制器中添加一个方法来构建前缀为 #

的 url 来绕过这个
function completeUrl(url){
    return '#' + url;
}

<a href={{completeUrl(tab.url)}}> {{tab.title}} </a>

但是,我还是想找到一个更优雅的解决方案。

如果您的问题与 href 值有关,您可以使用 ngHref 指令解决此问题。

代码应该是这样的:

<li ng-repeat="tab in tabs">
    <a ng-href="#/{{tab.url}}"> {{tab.title}} </a>
</li> 

更新: 从 FreeMarker 2.3.28 开始,您可以通过设置 interpolation_syntax 将 FreeMarker 配置为仅使用 ${...},而不是 #{...}配置设置为 dollar(在 Java API: Configuration cfg; ... cfg.setInterpolationSyntax(Configuration.DOLLAR_INTERPOLATION_SYNTAX))。然后 #{...} 只是 FreeMarker 的静态文本。不要将此设置与 tag_syntax 设置混淆。顺便说一句,也可以使用 [=...] 作为插值语法,以防 ${...} 也与某些东西发生冲突(比如 ES6 字符串插值)。另见:https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html

这是与 FreeMarker 的 #{} 的不幸冲突,后者甚至已被弃用,并且仅被识别用于向后兼容,但解析器不可配置为忽略它。我能想到的最短(即使丑陋)的解决方案是 ${'#'}{{}}.