2012-03-06 74 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