如果我使用带双引号的url标记:
@{"/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中,我无法看到单引号和双引号的不同语义含义......
在groovy双引号中templetable strings
但是这似乎并不能解释为什么它失败了,如果它是一个已知的行为,它应该在文档中写得非常响亮 - 它花了我很多钱是时候了解问题所在!
答案 0 :(得分: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
是ActionBridge
中定义的play.templates.GroovyTemplate
类的一个实例,如果您想查看它...
答案 1 :(得分:0)
据我所知,你不能在@{}
之间放置一个完整的路径字符串,所以它根本不起作用。您只需将"/public/images/blue.png"
直接放在代码中即可。
@{}
用于反向路由给定Controller和action的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>