Partial Rendering

Modern websites often (re-)load parts of the page using javascript. TDI attempts to help you somewhat with such demands. It provides the possibility to render only a subnode of the template. Imagine a menu which is reloaded dynamically. Imagine further that you don’t need to change a thing (compared to loading the whole page) except to say, which node should be rendered now. Here it comes:

from tdi import html
template = html.from_string("""
<html>
<body>
    <h1 tdi="doctitle">doc title goes here</h1>
    <ul tdi="menu">
        <li tdi="item"><a tdi="link">some menu item</a></li><li tdi=":-item">
        </li>
    </ul>
    <p tdi="intro" class="edit-intro">Intro goes here.</p>
    <div class="list" tdi="list">
        ...
    </div>
</body>
</html>
""")


class Model(object):
    def __init__(self, menu, page):
        self._menu = menu
        self._page = page

    def render_item(self, node):
        node.repeat(self.repeat_item, self._menu)

    def repeat_item(self, node, (href, menuitem)):
        node.link.content = menuitem
        if (node.ctx[0] + 1 == self._page):
            node.link.hiddenelement = True
        else:
            node.link['href'] = href

menu = [
    (u'/some/', u'Some Menu Item'),
    (u'/other/', u'Editing Content & Attributes'),
    (u'/third.html', u'Another Menu Item'),
]
model = Model(menu=menu, page=2)
template.render(model, startnode="menu")

The “partial rendering” feature is triggered by the startnode argument, which addresses the node symbolically. A dotted notation is allowed in order to specify a specificly nested node. See the → render() method API documentation for more details.

The output now contains the desired node only:

<ul>
        <li><a href="/some/">Some Menu Item</a></li>
        <li>Editing Content &amp; Attributes</li>
        <li><a href="/third.html">Another Menu Item</a></li>
    </ul>