| 429 | |
| 430 | == Auto-escaping in templates == |
| 431 | |
| 432 | In [XXXX] a long-awaited feature was committed to make default HTML template usage a bit safe from some forms of cross-site scripting attacks. For full details, read the [http://www.djangoproject.com/documentation/templates/#automatic-html-escaping template author documentation] and the [http://www.djangoproject.com/documentation/templates_python/#filters-and-auto-escaping template filter documentation]. |
| 433 | |
| 434 | Automatic HTML escaping (henceforth ''auto-escaping'') affects any variables in templates. It is only applied to variables and not to template tags. |
| 435 | |
| 436 | {{{ |
| 437 | {{ a_variable }} -- This will be auto-escaped. |
| 438 | {{ variable|filter1|filter1 }} -- so will this |
| 439 | {% a_template_tag %} -- This will not be; it's a tag |
| 440 | }}} |
| 441 | |
| 442 | Also note that the {{{escape}}} filter's behaviour has changed slightly (it is only applied once and only as the last thing done to the output) and new filters {{{force_escape}}} and {{{safe}}} have been introduced if you need them. |
| 443 | |
| 444 | If you never intentionally insert raw HTML into your context variables, no changes will be needed. |
| 445 | |
| 446 | If you have any variables in your templates that do insert raw HTML output and you do ''not'' want this output automatically escaped, you will need to make some changes. There are two approaches here, the first one being the easiest (but not the safest) and can act as a temporary step whilst you do the more detailed second step. |
| 447 | |
| 448 | 1. '''Simple backwards compatibility:''' In every root template (such as your `base.html` template), wrap the entire contents in tags to disable auto-escaping: |
| 449 | |
| 450 | {{{ |
| 451 | {% autoescape off %} |
| 452 | ... normal template content here ... |
| 453 | {% endautoescape %} |
| 454 | }}} |
| 455 | |
| 456 | If one template extends from another template, the auto-escaping behaviour from the root template (the one in the {{{ {% extends ... %} }}} tag) will be inherited. So you only need to add these tags to your root templates. |
| 457 | |
| 458 | This is also the recommended approach for templates that produce, say, email messages or other non-HTML output. The `autoescape` template tag exists for this reason. |
| 459 | |
| 460 | The drawback of this method in templates that are destined for HTML output is that you receive none of the benefits of auto-escaping. |
| 461 | |
| 462 | 2. '''More detailed porting to take advantage of auto-escaping:''' There are two approaches to inserting raw HTML via variables into templates. One option is to pass the variable content through the {{{safe}}} filter. This tells the renderer not to auto-escape the contents: |
| 463 | |
| 464 | {{{ |
| 465 | {{ variable_with_html|safe }} -- will not be auto-escaped. |
| 466 | }}} |
| 467 | |
| 468 | The second and probably more robust way is to use {{{mark_safe()}}} where appropriate (see [http://www.djangoproject.com/documentation/templates_python/#filters-and-auto-escaping the documentation] for details) and go through each of your custom filters attaching {{{is_safe}}} and {{{needs_autoescape}}} attributes where necessary (again, the details are in the above documentation). |
| 469 | |
| 470 | Have a look at Django's default filters (in {{{django/template/defaultfilters.py}}}) for examples of how mixed filters (those which behave differently depending upon whether auto-escaping is in effect or not) can be written. |
| 471 | |
| 472 | The attributes on filter functions and the new {{{escape}}} behaviour mean that you can write templates and filters that will operate correctly in both auto-escaping and non-auto-escaping environments, so you're not forcing your decision onto users of your filters, if you distribute the code. |
| 473 | |