XSS template language
=====================

This language is used internally by the template compiler.

  >>> print render_xss("""\
  ... <html xmlns="http://www.w3.org/1999/xhtml"
  ...       xmlns:xss="http://namespaces.repoze.org/xss">
  ...   <head>
  ...      <title><span xss:content="document-heading">Title</span></title>
  ...   </head>
  ...   <body><span xss:content="document-content">Default content</span></body>
  ... </html>""", content={'document-content': u"Dynamic content",
  ...                      'document-heading': u"Dynamic heading"})
  <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
       <title>Dynamic heading</title>
    </head>
    <body>Dynamic content</body>
  </html>

If we omit the slot from the passed content argument, the element is
left untouched.
  
  >>> print render_xss("""\
  ... <html xmlns="http://www.w3.org/1999/xhtml"
  ...       xmlns:xss="http://namespaces.repoze.org/xss">
  ...   <div>
  ...      <span xss:content="document-content">Default content</span>
  ...   </div>
  ... </html>""", content={})
  <html xmlns="http://www.w3.org/1999/xhtml">
    <div>
       <span>Default content</span>
    </div>
  </html>

When the xss:structure attribute is set, the dynamic content is not
escaped.
  
  >>> print render_xss("""\
  ... <html xmlns="http://www.w3.org/1999/xhtml"
  ...       xmlns:xss="http://namespaces.repoze.org/xss">
  ...   <div>
  ...      <span xss:content="document-content" xss:structure="true">
  ...         Default content
  ...      </span>
  ...   </div>
  ... </html>""", content={'document-content': u"<span>Dynamic content</span>"})
  <html xmlns="http://www.w3.org/1999/xhtml">
    <div>
       <span>Dynamic content</span>
    </div>
  </html>

Attributes may be dynamically applied to elements using the
xss:attributes.

  >>> print render_xss("""\
  ... <html xmlns="http://www.w3.org/1999/xhtml"
  ...       xmlns:xss="http://namespaces.repoze.org/xss">
  ...   <div xss:attributes="example">
  ...      Content
  ...   </div>
  ... </html>""", attributes={'example': {'class': 'example-class'}})
  <html xmlns="http://www.w3.org/1999/xhtml">
    <div class="example-class">
       Content
    </div>
  </html>

As a special case, if "class" is a dynamic attribute, it will not
override an existing "class" attribute on the element, but extend it
(concatenate with a space character).
  
  >>> print render_xss("""\
  ... <html xmlns="http://www.w3.org/1999/xhtml"
  ...       xmlns:xss="http://namespaces.repoze.org/xss">
  ...   <div id="existing" class="existing-class" xss:attributes="example">
  ...      Content
  ...   </div>
  ...   <span xss:attributes="example">
  ...      Content
  ...   </span>
  ... </html>""", attributes={'example': {'id': 'new', 'class': 'additional-class'}})
  <html xmlns="http://www.w3.org/1999/xhtml">
    <div id="new" class="existing-class additional-class">
       Content
    </div>
    <span id="new" class="additional-class">
       Content
    </span>
  </html>

We can supply multiple dynamic attribute identifiers, separated by a
comma.
  
  >>> print render_xss("""\
  ... <html xmlns="http://www.w3.org/1999/xhtml"
  ...       xmlns:xss="http://namespaces.repoze.org/xss">
  ...   <div id="existing" class="existing-class" xss:attributes="example1, example2">
  ...      Content
  ...   </div>
  ... </html>""", attributes={'example1': {'class': 'foo', 'style': 'bar'},
  ...                         'example2': {'class': 'bar', 'style': 'foo'}})
  <html xmlns="http://www.w3.org/1999/xhtml">
    <div style="foo" id="existing" class="existing-class foo bar">
       Content
    </div>
  </html>
