Notes, known limitations, and differences between SimpleTAL and Zope's ZPT.
Porting SimpleTAL to Python 3 has introduced a number of small changes:
Some notes on aspects of SimpleTAL that might require a little explanation. If there is something you feel should be included in here, please let me know.
SimpleTAL processes HTML templates slightly differently to XML templates. In the HTML 4.01 specification there are several elements (e.g. <img>) for which end tags are forbidden. This would normally cause a problem with TAL, because all tags that have TAL attributes on them must be closed. To solve this problem SimpleTAL will:
These changes ensure that a HTML template can still be a valid HTML document, even if TAL needs to be used on elements that forbid end tags. Additionally the output from the expanded template will also be valid HTML, in that the end tags will be suppressed even if present in the template.
As a consequence of this it is important that any XHTML templates are handled as XML rather than HTML, i.e. by calling compileXMLTemplate to compile the template.
HTML templates can be provided as a string or a file like object that generates strings. If loading from a file use open (filename, 'rt', encoding = "character-set") to load the template encoded in a particular character set.
XML templates specify within the document what encoding they use and so can be passed as a string, bytes, or a file like object. When using strings the XML must have been originally in UTF-8. To load from a file use open (filename, 'rb').
When expanding a template SimpleTAL will determine whether to write out strings if the output file is a sub-class of io.TextIOBase or codecs.StreamWriter. Otherwise the file like object will be assumed to require bytes, and the output will be encoded first using 'outputEncoding', which defaults to utf-8.
When content is included into a template using 'tal:content' or 'tal:replace' the content is by default treated as text. This means that the '<', '>' and '&' characters will be automatically escaped so that they appear in the rendered template correctly.
When using the 'structure' keyword, however, SimpleTAL will pass the content straight through into the template with no escaping. As such it's important to realise that the content placed into a template in such a way can affect the validity of the output. For example if you take user input that contains HTML markup it's important to ensure that the markup is valid HTML, otherwise the resulting template output will not be valid.
When adding a mapping object (e.g. a Dictionary) to the Context, care should be taken on the naming conventions used within the mapping. When SimpleTAL resolves a path, it will first look for attributes on the object with that name, before trying to treat the object as a mapping object. What this means in practice is that paths which match object attributes (e.g. methods) will never select the values given in the mapping. As an example of this consider the following:
Template: <p tal:repeat="item dict/items"><b tal:replace="item"></b></p>
Context:
myDict = {'items': [1,2,3]}
Context.addGlobal ("dict", myDict)
You would expect the output from this to be:
<p>1</p><p>2</p><p>3</p>
However the variable "item" will be set to the output of "myDict.items()" - i.e. it will call the Python dictionary method 'items()'.
When using the 'python:' path type, care must be taken with the use of the less than (<) and greater than (>) signs. These must be escaped in the same way as all other HTML markup. For example:
use: <div tal:condition="python: a < b">Conditional Text</div>
instead of: <div tal:condition="python: a < b">Conditional Text</div>
Non-existent path types, e.g. '<b tal:content="total: $totalAmount"></b>' are not supported. In Zope, this results in the path being interpreted as a string - in simpleTAL/ES the result will be an error.
SimpleTAL 5.2 onwards supports accessing repeat variables through Python paths. Unlike Zope, all variables on the repeat variable are methods, with the exception of length. To access the value from a python path you need to call the method, e.g.: '<b tal:content="python:repeat['item'].index()"></b>
The full list of my published Software
Made with PubTal 3.5
Copyright 2021 Colin StewartEmail: colin at owlfish.com