2

If I use the url tag with double quotes:

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

I get this error:

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

While everything works when using single quotes:

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

Maybe I've been too much head into the code and there's something stupid I'm not seeing?

In the template tag documentation, nor in particular in the @ template tag documentation, I could not see a mention to different semantic meaning of single and double quotes...

In groovy double quotes are templetable strings but still this does not seem to explain why it's failing, and if it is a known behaviour it should be written extremely loud in the doc - it took me quite a good deal of time to understand what the issue was!

Community
  • 1
  • 1
Stefano
  • 18,083
  • 13
  • 64
  • 79

2 Answers2

1

The play.templates.GroovyTemplateCompiler has the follow method for executing @{..} and @@{..}:

@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();
}

The action string here is everything in between @{ and }. And it's called with absolute set to false if you use @{..}. The __reverseWithCheck_absolute_true/false are the methods needed to find the templates. But if the action doesn't match the regex "^'.*'$" (which happens when you use anything else than single qoutes), then it tries to invoke the action as a method of your Controller.

I don't really understand the part where it tries to find the Controller action though, but I believe that's what is throwing the error. The actionBridge is an instance of the ActionBridge class defined in play.templates.GroovyTemplate, if you want to take a look at it ...

mcls
  • 9,071
  • 2
  • 29
  • 28
  • you nailed it! it is not something "generic" about template tags, it is really the way the _that_ template tag is implemented. I had never checked how template tag parsing really work, and I'm a little suprised of this finding, but I'm guessing this is an exception. Anyway, this behaviour should definitely be explained in the documentation!!! – Stefano Mar 07 '12 at 15:22
0

As I know, you can't put a full path string between @{} so it should not work at all. You should simply put directly the "/public/images/blue.png" in your code.

@{} is used for reverse routing the url of a given Controller and action.

And if you really want to check if the file exists, you could have your own tag.

for the #{script /} tag, this is how the "file exists" check is done:

framework/templates/tags/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>
gre
  • 1,841
  • 2
  • 16
  • 26
  • putting a path in a url `@` template tag not only works, but it's the only way to make your static files accessible if you deploy your application as a JBoss war - which is the reason that I have for using it. It's not in the official doc, but in some comments and in SO too: http://stackoverflow.com/questions/7345613/how-do-i-reverse-route-a-static-file – Stefano Mar 07 '12 at 13:09
  • ...and in any case this wouldn't be an answer to my question ;-) – Stefano Mar 07 '12 at 13:10