cmlenz@226: .. -*- mode: rst; encoding: utf-8 -*- cmlenz@226: cmlenz@226: ================================== cmlenz@226: Generating Markup Programmatically cmlenz@226: ================================== cmlenz@226: cmlenz@230: Genshi provides a ``builder`` module which lets you generate markup from Python cmlenz@226: code using a very simple syntax. The main entry point to the ``builder`` module cmlenz@226: is the ``tag`` object (which is actually an instance of the ``ElementFactory`` cmlenz@226: class). You should rarely (if ever) need to directly import and use any of the cmlenz@226: other classes in the ``builder`` module. cmlenz@226: cmlenz@226: cmlenz@226: .. contents:: Contents cmlenz@226: :depth: 2 cmlenz@226: .. sectnum:: cmlenz@226: cmlenz@226: cmlenz@226: Creating Elements cmlenz@226: ================= cmlenz@226: cmlenz@226: Elements can be created through the `tag` object using attribute access, for cmlenz@226: example:: cmlenz@226: cmlenz@230: >>> from genshi.builder import tag cmlenz@226: >>> doc = tag.p('Some text and ', tag.a('a link', href='http://example.org/'), '.') cmlenz@226: >>> doc cmlenz@226: cmlenz@226: cmlenz@226: This produces an ``Element`` instance which can be further modified to add child cmlenz@226: nodes and attributes. This is done by “calling” the element: positional cmlenz@226: arguments are added as child nodes (alternatively, the ``append`` method can be cmlenz@226: used for that purpose), whereas keywords arguments are added as attributes:: cmlenz@226: cmlenz@226: >>> doc(tag.br) cmlenz@226: cmlenz@226: >>> print doc cmlenz@226:

Some text and a link.

cmlenz@226: cmlenz@226: If an attribute name collides with a Python keyword, simply append an underscore cmlenz@226: to the name:: cmlenz@226: cmlenz@226: >>> doc(class_='intro') cmlenz@226: cmlenz@226: >>> print doc cmlenz@226:

Some text and a link.

cmlenz@226: cmlenz@226: As shown above, an ``Element`` can easily be directly rendered to XML text by cmlenz@226: printing it or using the Python ``str()`` function. This is basically a cmlenz@226: shortcut for converting the ``Element`` to a stream and serializing that cmlenz@226: stream:: cmlenz@226: cmlenz@226: >>> stream = doc.generate() cmlenz@226: >>> stream cmlenz@230: cmlenz@226: >>> print stream cmlenz@226:

Some text and a link.

cmlenz@226: cmlenz@226: cmlenz@226: Creating Fragments cmlenz@226: ================== cmlenz@226: cmlenz@226: The ``tag`` object also allows creating “fragments”, which are basically lists cmlenz@226: of nodes (elements or text) that don't have a parent element. This can be useful cmlenz@226: for creating snippets of markup that are attached to a parent element later (for cmlenz@235: example in a template). Fragments are created by calling the ``tag`` object:: cmlenz@226: cmlenz@226: >>> fragment = tag('Hello, ', tag.em('word'), '!') cmlenz@226: >>> fragment cmlenz@226: cmlenz@226: >>> print fragment cmlenz@226: Hello, world!