Reputation: 10300
If a handler returns a variable along with a template:
self.render('page.html', enabled=enabled)
where enabled
is a boolean variable.
So far I know I can do things like:
{% if enabled %}
...
{% end %}
within the HTML part of the template.
But can we conditionally run some javascript code based on this enabled
variable in the Tornado template? In other words, can we access the value of this variable in javascript embedded in the template?
Upvotes: 4
Views: 2256
Reputation: 110271
Of course - Whatever is in the template between the {% if ... %}
and the { % end %}
directives will only be sent to the browser in case the if
the expression is True. So, anything in there, be it a <script >
tag with inline javascript, or a <link>
tag importing a javascript file from somewhere will only be transmited over the network in that case.
You could even place a template if
or for
directive inside Javascript code itself, to enable or disable parts of code based on conditions known to the server code. This, unlinke embedding or not a whole piece of code, I think would not be considered a good pratice - because it would entangle the server and client sides of your code in undesirable ways.
To access the variable from javascript, just do:
var enabled = {{ enabled }};The value inside the {{...}}
marker is rendered with the server variable.
In this case, to ensure the value in enabled
to be compatible across Python and Javascript, you should use the number 0 for False and 1 for True (because if you use Python booleans, the template will render as
var enabled = True;
- which is not what javascript would expect, as the reserved "true" in Javascript is lowercase)
The only restriction is that you can only set teh server-side variables before the page is sent to the browser. So, if you need to set any any variable on the server side that depends on user's action on the page displayed, this way of doing things won't cut it anymore (only with a page reload). the way to make a page to be interactvely updated without reloading is to rely on asynchronous comunications from javascript (formerly known exclusively as "ajax").
edit - The O.P further asked:
here is a problem: when I return a string variable such as myvar='foo-bar' to the template, and when this {{myvar}} get evaluated in JS code, JS apparently interprets foo-bar as a variable name instead of a string. In this case, it will cause error because - denotes subtraction. How do I make JS recognize foo-bar as a string value?
Again, what is going on is quite simple: the {{ <expr> }}
template operator inserts the
string representation of the rsulting expression - so if you have in python
myvar = "bla"
and on the template var myvar = {{ myvar }}
, that gets rendered (and sent to the client browser this way) as var myvar = bla
- without quotes around bla
- that's why javascript treats it as a variable name. The workarounds for this are putting extra quotes around your variable, if it is a string, either on Python side or on the template.
On the template you can do:
var myvar="{{ myvar }}"
- or, on the Python side, when defining myvar: myvar = '"%s"' % "bla"
Upvotes: 5