Sub-rendering means, that you can prematurely render a node during the regular rendering process (i.e. from within a render_name method). This is useful if you want to process the render result before actually emitting it to the output stream. Sub-rendering is implemented by the node’s → render method.
That’s a typical use case. Imagine you have a piece of HTML code, that only makes sense if javascript is enabled, or just a fragment that you need later in your script. TDI cannot render HTML within a javascript block (because it’s just a piece of text from TDI‘s point of view).
The following example shows how to render the HTML in the regular template context and then remove it (using the content picking method with node.replace()) and placing it in the javascript content afterwards. It’s surprisingly simple, given that this explanation takes much more space than the code itself:
from tdi import html
from tdi.tools import javascript
template = html.from_string("""
<html>
<body>
<tdi tdi="-script">
<div tdi="*html"><h1 tdi="h1">dynamic js-only-content</h1></div>
<script tdi="*script">
document.write('__html__')
</script>
</tdi>
</body>
</html>
""".lstrip())
class Model(object):
def render_h1(self, node):
node.content = u"My Heading"
def render_script(self, node):
html = node.html.render()
javascript.fill(node.replace(None, node.script), dict(html=html))
template.render(Model())
The example produces the following output:
<html>
<body>
<script>
document.write('<div><h1>My Heading<\/h1><\/div>')
</script>
</body>
</html>
The code uses the javascript.fill() function, which is part of the javascript tools.
Also note, how contents of the node is rendered using the model. The options of the render() method are described in the API documentation.