0
votes

From the playframework tutorial at the front page, https://www.playframework.com/ the trainer leads you through a simple example, eventually importing a javascript (coffeescript) file for the dynamic generation of a list.

He writes this, inside the index.scala.html template file, so:

<script type='text/javascript' src='@routes.Assets.at("js/index.js")'></script>

Note, the src attribute is single quoted, and the encapsulated at method uses double-quotes as its single string argument.

This is not quite as I might expect, as I know the @routes.Assets.at method is going to be replaced by the resulting value, and I remember it being typical in many programming languages (eg., Perl) that single quotes specify a fixed/static string value. But OK, I guess seeing as we're looking at the start of an attribute of a HTML script tag, it is OK.

Perl:

my $name = "Fred";
print "Hello $name\n";  // prints Hello Fred (with an endline afterwards)
print 'Hello $name\n';  // prints Hello $name\n

https://en.wikibooks.org/wiki/Perl_Programming/Strings

Nonetheless, I don't personally like it. And I preferred to use the opposite:

<script type="text/javascript" src="@routes.Assets.at('javascripts/index.js')"></script>

However, play doesn't like this at all, with the resulting error message being:

"Multiple annotations found at this line:
    - unclosed character literal
    - ')' expected but something 
     found."

That is most unexpected, as it is allowed in HTML, http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.2

and also allowed, say, in Java. For example:

String test = "this is 'not' a test";

So, the question is: what is the logic behind this? Can I find the 'rules' to this documented somewhere? Is it play specific, or, as it is some kind of Scala related file (index.scala.html) it is due to a querk of the Scala syntax? (I am just starting out to look at Scala)

1

1 Answers

1
votes

You have to separate the two different levels here: HTML and Scala.

Scala goes through first, replacing things that start with the @ sign (and a few other known identifiers). So lets cut out the thing that Scala reads and works with:

@routes.Assets.at('javascripts/index.js')

As you can see, the method is given a character literal as argument, but with a String contents - which is not possible in Java (and there for neither in Scala). This is also what it tries to tell you in the error message, it found the start of a character literal and a character, but then the character literal was not terminated.

So the logic is basic Java logic. This is one of the tricky things with these compiled templates: you have to separate in your head what goes through which parser.

Following the rules of both languages involved, the following combinations are allowed:

<script type='text/javascript' src='@routes.Assets.at("js/index.js")'></script>
<script type='text/javascript' src="@routes.Assets.at("js/index.js")"></script>

Note that the syntax highlighting will break for the second option in a lot of editors, including the code block above