Template Annotations¶
TDI strictly keeps the template and the rendering logic apart. That way you can write your, say, HTML template in HTML and your logic in a real language – python in this case. There is no template language in-between. You just need to label the locations in the template which should be modified later.
For TDI this looks like the following:
<html>
<body>
<h1 tdi="doctitle">doc title goes here</h1>
<p tdi="intro">Intro goes here.</p>
</body>
</html>
When you pass that to TDI, it will be parsed into a document tree
essentially containing the two nodes (doctitle
and intro
).
Everything in between is passed through literally (except when your
template logic changes it, of course). The tree is stuffed into a
template object which you can handle in python. For example:
from tdi import html
template = html.from_string("""
<html>
<body>
<h1 tdi="doctitle">doc title goes here</h1>
<p tdi="intro">Intro goes here.</p>
</body>
</html>
""")
template.render()
template.render()
streams the result to sys.stdout
by
default. So the output of this snippet would be:
<html>
<body>
<h1>doc title goes here</h1>
<p>Intro goes here.</p>
</body>
</html>
We have no render logic specified, so the only difference to the original
template is, that the annotations (tdi=...
) are gone.
Annotation Syntax¶
All annotations recognized by TDI follow the same pattern. They
are defined as markup attribute and consist of a name optionally
prepended by flags. Names are limited to the usual US-ASCII word
alphabet (a-z
, A-Z
, 0-9
, _
) and must start with a
letter. Flags are represented by single “special” characters, which are
not member of the name alphabet (like -
or *
).
The following annotation attributes are recognized (and removed automatically) by the parser:
Attribute / Description | Flag | Description |
---|---|---|
tdi="[flags]name" |
||
Main attribute for labeling modifiable nodes | - |
Hide the markup |
+ |
Show the markup | |
: |
Separator node | |
* |
Silent node | |
tdi:overlay="[flags]name" |
||
Mark overlay source or target | - |
Hide the markup |
+ |
Show the markup | |
< |
Source overlay | |
> |
Target overlay | |
tdi:scope="[flags]name" |
||
Enter a logical scope. Empty names and dotted names allowed | - |
Hide the markup |
+ |
Show the markup | |
= |
Absolute scope |
Note that the +
and -
flags are mutually exclusive per
attribute. If they are mixed across attributes of the same node, -
takes precedence. You only need to set them, if the desired flag differs
from the template parser/builder default. For example, TDI‘s HTML
template factory defaults to +
.
Mock-Up Content¶
When editing or presenting the template it’s often useful to fake parts that are actually generated later. That’s called mock-up content. TDI provides a special annotation for this very purpose:
from tdi import html
template = html.from_string("""
<ul>
<li tdi="item">1st</li>
<li tdi="-">2nd</li>
<li tdi="-">3rd</li>
</ul>
""")
template.render()
All nodes annotated with tdi="-"
are handled as mock-up content and
simply stripped by the template builder. Here’s the output of the
snippet above:
<ul>
<li>1st</li>
</ul>
Note that the builder strips the mock-up nodes (not the renderer). Consequently once the template object is ready, there is no performance penalty at all.
Character Encoding¶
The → encoding
property of the template
object contains information about what TDI knows about the template
encoding. This information is used by TDI itself to encode supplied
content properly (and for consistency checks when combining templates,
but more about that elsewhere).
You can use that information for example, for setting the proper HTTP or MIME headers.
The html
template factory is configured to look out for two encoding
indicators within the template:
- An XML prolog
- An applicable
<meta>
element
If it contains more than one encoding hint, the last one wins. If it
doesn’t contain any hint, US-ASCII
is assumed as the most safe
fallback. The following code shows examples:
from tdi import html
# xml prolog
template = html.from_string(
"""<?xml version="1.0" encoding="latin-1"?>..."""
)
print template.encoding
# meta
template = html.from_string(
"""<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</html>"""
)
print template.encoding
# meta HTML5
template = html.from_string(
"""<html>
<meta charset="windows-1252">
</html>"""
)
print template.encoding
# xml prolog + meta
template = html.from_string(
"""<?xml version="1.0" encoding="latin-1"?>
<meta charset=utf-8>
"""
)
print template.encoding
# none
template = html.from_string("<html>...</html>")
print template.encoding
The script produces the following output:
latin-1
utf-8
windows-1252
utf-8
ascii