2012-03-06 82 views
2

如果我用双引号的URL标签:简单与双引号(1.2.4)

@{"/public/images/blue.png"} 

我得到这个错误:

No route able to invoke action CONTROLLERNAME./public/images/blue.png was found 

虽然一切正常当使用单引号:

@{'/public/images/blue.png'} 

也许我已经太多了头进入代码,有一些愚蠢的我没有看到?

template tag documentation,也不特别是在@ template tag documentation,我看不出一提单引号和双引号的不同语义...

在常规双引号templetable strings但仍然没有这似乎不解释为什么它失败了,如果它是一个已知的行为,它应该在文档中写得非常响亮 - 花了我相当多的时间来理解问题是什么!

回答

1

play.templates.GroovyTemplateCompiler有如下方法执行@{..}@@{..}

@Override 
void action(boolean absolute) { 
    String action = parser.getToken().trim(); 
    if (action.trim().matches("^'.*'$")) { 
     if (absolute) { 
      print("\tout.print(__reverseWithCheck_absolute_true("+action+"));"); 
     } else { 
      print("\tout.print(__reverseWithCheck_absolute_false("+action+"));"); 
     } 
    } else { 
     if (!action.endsWith(")")) { 
      action = action + "()"; 
     } 
     if (absolute) { 
      print("\tout.print(actionBridge._abs()." + action + ");"); 
     } else { 
      print("\tout.print(actionBridge." + action + ");"); 
     } 
    } 
    markLine(parser.getLine()); 
    println(); 
} 

action这里的字符串是@{}之间的所有内容。如果您使用@{..},则调用absolute设置为false。 __reverseWithCheck_absolute_true/false是查找模板所需的方法。但是如果这个动作与正则表达式"^'.*'$"(当你使用其他任何东西而不是单独的qoutes时)发生匹配,那么它会尝试调用action作为Controller的一个方法。

虽然我并不十分理解它试图找到Controller动作的部分,但我相信这就是抛出错误的原因。 actionBridge是在play.templates.GroovyTemplate中定义的ActionBridge类的一个实例,如果您想要查看它的话...

+0

你钉了它!它不是关于模板标签的“通用”,它实际上是_that_模板标签实现的方式。我从来没有检查过模板标签解析是如何工作的,我对这个发现有点惊讶,但我猜这是一个例外。无论如何,这个行为绝对应该在文档中解释! – Stefano 2012-03-07 15:22:27

0

据我所知,你不能在@{}之间放置一个完整的路径字符串,所以它不应该工作。您应该直接在您的代码中直接放入"/public/images/blue.png"

@{}用于反向路由给定的控制器和动作的URL。

如果你真的想检查文件是否存在,你可以有自己的标签。

#{script /}标签,这是多么 “文件存在” 检查是:

框架/模板/标签/ script.tag

%{ 
    (_arg) && (_src = _arg); 

    if (!_src) { 
     throw new play.exceptions.TagInternalException("src attribute cannot be empty for script tag"); 
    } 
    _src = "/public/javascripts/" + _src 
    try { 
     _abs = play.mvc.Router.reverseWithCheck(_src, play.Play.getVirtualFile(_src), false); 
    } catch (Exception ex) { 
     throw new play.exceptions.TagInternalException("File not found: " + _src); 
    } 
}% 
<script type="text/javascript" language="javascript"#{if _id} id="${_id}"#{/if}#{if _charset} charset="${_charset}"#{/if} src="${_abs}"></script> 
+0

将路径放入网址'@'模板标记不仅可以工作,而且是唯一的方法如果您将应用程序部署为JBoss战争,则可以访问您的静态文件 - 这是我使用它的原因。它不在官方文档中,但在一些评论中也是如此:http://stackoverflow.com/questions/7345613/how-do-i-reverse-route-a-static-file – Stefano 2012-03-07 13:09:01

+0

...并在任何情况下,这不会是我的问题的答案;-) – Stefano 2012-03-07 13:10:12