Guy Bowden
Guy Bowden

Reputation: 5107

how to stop django template code from escaping

Is there any way to completely turn off django auto_escaping when rendering a template within the view code (for an email for example):

from django.template import Context, Template
subject_template_string = "Hi {{ customer.name }}"
subject_template = Template(subject)
context = Context({'customer':MyCustomerModel.objects.get(pk=1)})
subject = subject_template.render(context)

If customer.name is something like "Jack & Jill" - the subject looks like "Hi Jack &\amp; Jill" (without the backslash!)

is there something like

subject = subject_template.render(context, autoescape=False)

edit: The actual templates are created by the client in the database, I'm hoping to avoid having to say add |safe to all templates where this might happen...

Upvotes: 2

Views: 4554

Answers (5)

Guy Bowden
Guy Bowden

Reputation: 5107

Just came back to answer my own question with a simple solution, and there were already 4 answers.. thanks.

This is what I've gone with:

subject_template = Template(u'{%% autoescape off %%}%s{%% endautoescape %%}' % email.subject)

Upvotes: 0

alecxe
alecxe

Reputation: 473753

How about using mark_safe:

Explicitly mark a string as safe for (HTML) output purposes. The returned object can be used everywhere a string or unicode object is appropriate.

It marks a string as safe, so, you should take customer.name out and pass to the template:

from django.utils.safestring import mark_safe
customer = MyCustomerModel.objects.get(pk=1)
context = Context({'customer_name': mark_safe(customer.name)})
subject = subject_template.render(context)

Though, control what is safe or not is better to do inside the template itself, that's why using autoescape should be preffered.

Upvotes: 6

Peter DeGlopper
Peter DeGlopper

Reputation: 37319

This is untested, but based on source code review it looks like the context object can take autoescape as a key.

context = Context({'customer':MyCustomerModel.objects.get(pk=1), 'autoescape': False})
subject = subject_template.render(context)

That said, that's a pretty sweeping change. If you know what values the templates might be looking for, it's probably better to use mark_safe on those values and pass in the predefined options. That would have the added benefit of not risking the possibility of the client template calling a method with side effects on the customer. The first time someone writes a template and puts in {{ customer.delete }}, you have a problem.

Upvotes: 0

agconti
agconti

Reputation: 18093

Use Django's autoescape tag:

{% autoescape off %}
    {{ body }}
{% endautoescape %}

for more info, check out the docs here.

Upvotes: 0

Wolph
Wolph

Reputation: 80011

Disabling it globally is usually a bad idea since you can easily forget it. I would recommend using the templatetag to disable it for that portion of your template instead.

Something like this:

{% autoescape off %}
    This will not be auto-escaped: {{ data }}.

    Nor this: {{ other_data }}
    {% autoescape on %}
        Auto-escaping applies again: {{ name }}
    {% endautoescape %}
{% endautoescape %}

Upvotes: 6

Related Questions