Vitalii Ponomar
Vitalii Ponomar

Reputation: 10936

How to return nested dictionary to a Mako template in Pyramid?

When I tried to return a nested dictionary to Mako template, it replaces single quotes with HTML code ' (I saw it in browser's source code).

In views:

@view_config(route_name='main', renderer='myproj:templates/main.mako')
def main_view(request):
    info = {'name': 'Some', 'age': 20}
    return {'info': info, 'country': 'Ukraine'}

In Mako:

<script type="text/javascript">func(${info})</script>

In browser's source code:

<script type="text/javascript">func({&#39;name&#39;: &#39;Some&#39;, &#39;age&#39;: 20})</script>

How to avoid this escaping? (renderer='json' is not variant, because I need that dictionary in Mako)

Upvotes: 2

Views: 3521

Answers (1)

Michael Merickel
Michael Merickel

Reputation: 23331

Mako is configured by default to escape strings. If you want to disable the filters this can be done via |n. Specifically ${info|n}.

In your example, however, you are trying to pass a python dictionary to a javascript function. This obviously doesn't add up and you need to turn the python dict into something usable by javascript. What you actually want to do here is turn your python dict into a string which is then output with no filtering to your javascript code.

This could be prettied up, but the idea is that in python you do:

@view_config(route_name='main', renderer='myproj:templates/main.mako')
def main_view(request):
    info = json.dumps({'name': 'Some', 'age': 20})
    return {'info': info, 'country': 'Ukraine'}

and in mako you do:

<script type="text/javascript">func(${info|n})</script>

By default Pyramid sets mako to use the h filter, which escapes everything (the issue you're seeing). You can edit the default filters but it's not usually the greatest idea because of potential side-effects in other code. The other possibility is to rely on the dict's __str__ implementation to yield valid javascript code. In this case you do not need to serialize anything, simply run ${info|str,n} which (at least in this case) yields your desired result.

Upvotes: 8

Related Questions