Html Super-Nodes ################ *AnPyLar* extends the powers of the Html Nodes (call them tags if you wish) to make them: - Aware of Observables and its events. - Simplify template formatting. - Integrate them in the routing engine (``routerlink``). - Allow some direct programming in html code. .. note:: The additional methods are all prefixed with ``_`` to make it clear that they don't belong to the standard hierarchy of node methods Formatting ********** The method applied for it is: ``_fmt`` (we could have named it ``_format``, but that takes longer to type) The method takes regular values and can also take *Observables* which will force re-formatting with each new value produced, i.e.: the node subscribes to the value of the observable. An example from the *Tour of Pyroes*:: html.txt(' {name}')._fmt(name=pyro.name_) # obs name_ ``pyro`` has an observable ``name_`` (generated through a binding) and in this case: - ``{name}`` will be formatted and reformatted with each value delivered by ``pyro.name_`` Notice how the ``{name}`` and later ``_fmt(name=xxx)`` syntax resembles that of the string method ``format`` in Python. **It is the same** When designing *AnPyLar* the question was if a new templating language had to be designed and the answer was quick: let's use something which is already built into the language and people know. The same code above could have been written without names, as in:: html.txt(' {}')._fmt(pyro.name_) # obs name_ Still the same *Format Mini-Language* present in Python. Rendering ********* A node (or better said: underneath the node) can be rendered when an observer generates a value. From the *Tour of Pyroes* .. code-block:: python def render(self, node): # render under ul in render_pyroes when observable self.pyroes_ fires with node.select('ul') as ul: # find node where to display the list ul._render(self.render_pyroes, self.pyroes_) def render_pyroes(self, pyroes): for pyro in pyroes: with html.li() as li: # per-pyro list item # per-pyro anchor routing path with parameter pyd with html.a(routerlink=('/detail', {'pyd': pyro.pyd})): html.span(pyro.pyd, Class='badge') # show pyd as badge html.txt(' {name}')._fmt(name=pyro.name_) # obs name_ with html.button('x', Class='delete') as b: # def param avoids closure using last pyro.pyd def pyro_delete(evt, pyd=pyro.pyd): evt.stopPropagation() # avoid evt clicking on "a" self.pyro_delete(pyd) b._bind.click(pyro_delete) # use "bind" to get event The first part describes the rendering binding:: ul._render(self.render_pyroes, self.pyroes_) which can be translated to: - Whenever the observable ``self.pyroes_`` produces a value - Call ``self.render_pyroes`` (with the value generated by ``self.pyroes_``) to render underneath ``ul`` It is guaranteed that: - Any previous DOM structure below ``ul`` will have been unloaded - ``ul`` is selected as the node under which things will be rendered. Dual Binding Formatting-Value ***************************** A standard use case is an ```` field (or ``