On Tue, Nov 2, 2010 at 5:58 PM, Yang Zhang <yanghates
...@gmail.com> wrote:
> Currently, we're writing templates like the following to escape
> literal substitutions in script blocks:
> $.validated.decorateError($(${"[name=%s]" % script(key)|script,n},
> form), ${unicode(error)|script,n});
> <a href="javascript:deleteEmail(${script(email.id)},
> ${script(reply.id)});void 0;">Delete email</a>
> In the above, script is just:
> def script(string): return re.sub('</', r'<\/', simplejson.dumps(string))
> The intent is basically the following unsafe versions of the above:
> $.validated.decorateError($("[name='${key}']", form), "${error}");
> <a href="javascript:deleteEmail('${email.id}', '${reply.id}'); void
> 0;">Delete email</a>
> Is this the simplest way to escape literals in scripts?
Have you looked at Mako's filtering syntax? It is perhaps just a little
simpler than how you're doing it. You can even define your own filters.
http://www.makotemplates.org/docs/filtering.html
In fact, you're mostly there. Just make sure your script() function
is defined in global scope (or import it from a python module),
<%!
import re
def script(string):
return re.sub('</', r'<\/', simplejson.dumps(string))
%>
And then use it, like:
${email.id | script}
As far as escaping </ into <\/ inside Javascript, which I suppose
is to protect against it matching an HTML/XML end tag, I'm sure
there are probably other better methods. If you are outputting
XHTML for example you could/should put all your Javascript
inside CDATA blocks.
However, when you're mixing in Javascript inside of HTML
attribute values (opposed to <script> elements), then more
correct would be to use the built-in |h filter rather than your regular
expression. You can then define a filter which only converts
values to javascript, but without the re part. Also note I'm using
the \-end of line syntax to keep things more readable.
<%!
import simplejson
def jsliteral( value ):
return simplejson.dumps( value )
%>
<a href="javascript:deleteEmail(\
${ email.id | jsliteral, h }\
,\
${ reply.id | jsliteral, h }\
);\
void 0;\
">Delete email</a>
I'm not quite sure what you're attempting to do with the
validated.decorateError, so I can't comment on that.
> Are there any clever tools that might understand the context from
> which substitutions are being invoked, and select the right filters
> accordingly?
Not that I know of. Filters are generally idempotent and unaware
of their calling context.
--
Deron Meranda
http://deron.meranda.us/