4
Summary: Fast ZPT engine.
6
Author: Malthe Borch and the Zope Community
7
Author-email: zope-dev@zope.org
12
This is a fast implementation of the ZPT template engine for Zope 3
13
which uses Chameleon to compile templates to byte-code.
15
The package provides application support equivalent to
16
``zope.app.pagetemplate``.
18
For usage, see the README.txt file inside the package.
27
- Use non-strict mode if available for compatibility with the
28
reference engine where expressions are only compiled at evaluation
34
- The provider expression is now first evaluated as a string
35
expression, the result of which is used as the content provider
38
This fixes an issue where (provider-) string expressions would not
39
get evaluated correctly, e.g. ``provider: ${mgr}``.
44
- Configure HTML boolean attributes (in HTML-mode only)::
46
"compact", "nowrap", "ismap", "declare", "noshade",
47
"checked", "disabled", "readonly", "multiple", "selected",
53
- Enable option ``literal_false`` to get the behavior that a value of
54
``False`` does not drop an attribute.
59
- Make sure the builtin names 'path' and 'exists' can be redefined.
61
- Guard ``sys.modules`` (mapped to the builtin variable "modules")
62
against import-time side effects using ``ProxyFactory``.
67
- Use dynamic expression evaluation framework that comes included with
75
- Move implementation-specific context setup to ``render``
76
method. This allows use of template class with an already prepared
79
- Fixed issue with the call flag on the Zope traverser compiler.
84
- Python-expressions are no longer TALES-expressions; previously, the
85
pipe operator would split Python expression clauses, allowing
86
fallbacks even for Python expressions, but this is not the standard
89
- Fixed an issue where an error which occurred inside a dynamic
90
``path`` or ``exists`` evaluation would fail to propagate due to a
91
missing remote context.
93
- Set variables ``here`` and ``context`` to the bound instance value
94
on ``PageTemplate`` instances.
99
- Fixed an issue with ``"exists:"`` expression where a callable would
100
be attempted called. It is meanwhile implied with this expression
101
types that it should use the ``"nocall:"`` pragma.
107
- Update to Chameleon 2.0.
109
This release includes many changes and is a complete rewrite of the
114
* Python 2.5+ now required.
118
* Expression interpolation is always enabled.
120
* Whitespace output is different, now closely aligned to the
123
* New language constructs:
131
* The expression translation interface has been replaced with an
132
expression engine. This means that all expressions must be
135
- The exists expression evaluator should ignore KeyError exceptions
138
- Special-case handling of Zope2's Missing.MV as used by
139
Products.ZCatalog for LP#649343.
145
- Bind template to the template object in the general case.
150
- Fixed compatibility issue with recent change in Chameleon.
152
- Fixed regression introduced with ``args`` being passed
153
in. Incidentally, the name ``args`` was used as the star argument
156
- Look at language set on request before invoking the zope.i18n
157
negotiator. This makes i18n work again on Zope2.
162
- Fixed issue where arguments were not passed on to template as
168
- Update to combined Chameleon distribution.
173
- Bind translation context (request) to translation method. Although
174
not required in newer versions of the translation machinery, some
175
versions will ask for a translation context in order to negotiate
176
language even when a language is explicitly passed in.
178
- Declare zope security settings for classes when zope.security is present
179
as the "class" ZCML directive was moved there.
184
- First point release.
189
- Made the Zope security declaration for the repeat dictionary be conditional
190
on the presence of zope.app.security instead of zope.app.component.
195
- Updated run-time expression evaluator method to work after a recent
196
architectural change in Chameleon. [malthe]
198
- Check that we have a non-trivial response-object before trying to
199
set the content type. [malthe]
201
- Wrap ``sys.modules`` dictionary in an "opaque" dictionary class,
202
such that the representation string does not list all loaded
208
- Removed lxml extra, as we do no longer depend on it. [malthe]
210
- Make sure the path expression is a simple string, not
213
- Detect path prefix properly for ViewPageTemplateFile usage in
216
- The ``template`` symbol is already set by the template base
219
- Set Content-Type header, for backwards compatibility with
220
zope.app.pagetemplate. [sidnei]
225
- Updated language adapter to work with 'structure' meta
231
- When traversing on dictionaries, only exposes dictionary items
232
(never attributes); this is to avoid ambiguity. [sidnei, malthe]
234
- Path expressions need to pass further path items in reverse order to
235
traversePathElement, because that's what it expects. [sidnei]
240
- Insert initial variable context into dynamic scope. The presence of
241
these is expected by many application. [malthe]
246
- If a namespace-acquired object provides ``ITraversable``, use path
249
- Implemented TALES function namespaces. [sidnei, malthe]
251
- Catch ``NameError`` in exists-traverser (return false). [malthe]
253
- Catch ``NameError`` in exists-evaluator (return false). [malthe]
255
- If the supplied ``context`` and ``request`` parameters are trivial,
256
get them from the view instance. [malthe]
258
- Expressions in text templates are never escaped. [malthe]
260
- Do not bind template to a trivial instance. [malthe]
265
- Fixed exists-traverser such that it always returns a boolean
271
- When evaluating path-expressions at runtime (e.g. the ``path``
272
method), run the source through the transform first to support
273
dynamic scope. [malthe]
278
- Allow attribute access to ``__call__`` method on bound page
284
- Fixed issue where symbol mapping would not be carried through under
285
a negation (not). [malthe]
287
- Optimize simple case: if path expression is a single path and path
288
is 'nothing' or has 'nocall:', just return value as-is, without
289
going through path_traverse. [sidnei]
291
- Moved evaluate_path and evaluate_exists over from ``five.pt``, adds
292
support for global ``path()`` and ``exists()`` functions for use in
293
``python:`` expressions (LP #317967).
295
- Added Zope security declaration for the repeat dictionary (tales
301
- The 'not' pragma acts recursively. [malthe]
306
- View templates now support argument-passing for alternative context
307
and request (for compatibility with
308
``zope.app.pagetemplate``). [malthe]
310
- Switched off the $-interpolation feature per default; It may be activated
311
on a per-template basis using ``meta:interpolation='true'``. [seletz]
313
- Allow more flexibility in overriding the PathTranslator method. [hannosch]
315
- Removed the forced defaultencoding from the benchmark suite. [hannosch]
320
- Split out content provider function call to allow modification
321
through subclassing. [malthe]
323
- Added language negotiation. [malthe]
325
- Simplified template class inheritance. [malthe]
327
- Added support for the question-mark operator in path-expressions. [malthe]
329
- Updated expressions to recent API changes. [malthe]
331
- Added 'exists' and 'not' translators. [malthe]
335
- Adjusted the bigtable benchmark test to API changes. [hannosch]
340
- Added ``PageTemplate`` and ``PageTemplateFile`` classes. [malthe]
347
- Allow '.' character in content provider expressions.
349
- Allow '+' character in path-expressions.
356
- Split out compiler to "Chameleon" package. [malthe]
358
Backwards incompatibilities
360
- Moved contents of ``z3c.pt.macro`` module into
361
``z3c.pt.template``. [malthe]
363
- Namespace attribute "xmlns" no longer rendered for templates with no
364
explicit document type. [malthe]
366
- Changes to template method signatures. [malthe]
368
- Engine now expects all strings to be unicode or contain ASCII
369
characters only, unless an encoding is provided. [malthe]
371
- The default path traverser no longer proxies objects. [malthe]
373
- Template output is now always converted to unicode. [malthe]
375
- The ``ViewPageTemplateFile`` class now uses 'path' as the default
376
expression type. [malthe]
378
- The compiler now expects an instantiated parser instance. [malthe]
382
- Added expression translator "provider:" (which renders a content
383
provider as defined in the ``zope.contentprovider``
386
- Added template API to render macros. [malthe]
388
- Optimized template loader so only a single template is instantiated
391
- Made ``z3c.pt`` a namespace package. [malthe]
393
- Added reduce and restore operation to the compilation and rendering
394
flow in the test examples to verify integrity. [malthe]
396
- The ZPT parser now supports prefixed native attributes,
397
e.g. <tal:foo tal:bar="" />. [malthe]
399
- Source-code is now written to disk in debug mode. [malthe]
401
- Custom validation error is now raised if inserted string does not
402
validate (when debug mode is enabled). [malthe]
404
- Added support for omitting rendering of HTML "toggle" attributes
405
(option's ``selected`` and input's ``checked``) within dynamic
406
attribute assignment. If the value of the expression in the
407
assignment evaluates equal to boolean False, the attribute will not
408
be rendered. If the value of the expression in the assignment
409
evaluates equal to boolean True, the attribute will be rendered and
410
the value of the attribute will be the value returned by the
413
- XML namespace attribute is now always printed for root tag. [malthe]
415
- Allow standard HTML entities. [malthe]
417
- Added compiler option to specify an implicit doctype; this is
418
currently used by the template classes to let the loose XHTML
419
doctype be the default. [malthe]
421
- Added support for translation of tag body. [malthe]
423
- Added security configuration for the TALES iterator (repeat
424
dictionary). This is made conditional on the availability of the
425
application security framework. [malthe]
427
- Dynamic attributes are now ordered as they appear in the
430
- Added ``symbol_mapping`` attribute to code streams such that
431
function dependencies can be registered at compile-time. [malthe]
433
- Allow BaseTemplate-derived classes (PageTemplate, PageTemplateFile,
434
et. al) to accept a ``doctype`` argument, which will override the
435
doctype supplied by the source of the template if specified. [chrism]
437
- Language negotiation is left to the page template superclass, so we
438
don't need to pass in a translation context anymore. [malthe]
440
- The ``ViewPageTemplateFile`` class now uses the module path of the
441
calling class to get an absolute path to a relative filename passed
442
to the constructor. [malthe]
444
- Added limited support for the XInclude ``include`` directive. The
445
implemented subset corresponds to the Genshi implementation, except
446
Match-templates, which are not made available to the calling
449
- Use a global template registry for templates on the
450
file-system. This makes it inexpensive to have multiple template
451
class instances pointing to the same file. [malthe]
453
- Reimplemented the disk cache to correctly restore all template
454
data. This implementation keeps a cache in a pickled format in a
455
file next to the original template. [malthe]
457
- Refactored compilation classes to better separate concerns. [malthe]
459
- Genshi macros (py:def) are now available globally. [malthe]
461
- A syntax error is now raised when an interpolation expression is not
462
exhausted, e.g. only a part of the string is a valid
463
Python-expression. [malthe]
465
- System variables are now defined in a configuration class. [malthe]
467
- Improve performance of codegen by not repeatedly calling
468
an expensive "flatten" function. [chrism]
470
- Remove ``safe_render`` implementation detail. It hid information
471
in tracebacks. [chrism]
473
- Implemented TAL global defines. [malthe]
475
- Added support for variables with global scope. [malthe]
477
- Curly braces may now be omitted in an expression interpolation if
478
the expression is just a variable name; this complies with the
479
Genshi syntax. [malthe]
481
- UTF-8 encode Unicode attribute literals. [chrism]
483
- Substantially reduced compiler overhead for lxml CDATA
486
- Split out element compiler classes for Genshi and Zope language
489
- Make lxml a setuptools "extra". To install with lxml support
490
(currently required by Genshi), specify "z3c.pt [lxml]" in
491
any references you need to make to the package in buildout or
492
in setup.py install_requires. [chrism]
494
- Add test-nolxml and py-nolxml parts to buildout so the package's
495
tests can be run without lxml. [chrism]
497
- No longer require default namespace. [malthe]
499
- Changed source code debug mode files to be named <filename>.py instead of
502
- Generalized ElementTree-import to allow both Python 2.5's
503
``xml.etree`` module and the standalone ``ElementTree``
506
- Expression results are now validated for XML correctness when the
507
compiler is running in debug-mode. [malthe]
509
- Preliminary support for using ``xml.etree`` as fallback for
510
``lxml.etree``. [malthe]
512
- String-expressions may now contain semi-colons using a double
513
semi-colon literal (;;). [malthe]
515
- Preserve CDATA sections. [malthe]
517
- Get rid of package-relative magic in constructor of BaseTemplateFile
518
in favor of just requiring an absolute path or a path relative
519
to getcwd(). Rationale: it didn't work when called from __main__
520
when the template was relative to getcwd(), which is the 99% case
521
for people first trying it out. [chrism]
523
- Added support for METAL.
526
- Add a TemplateLoader class to have a convenient method to instantiate
527
templates. This is similar to the template loaders from other template
528
toolkits and makes integration with Pylons a lot simpler.
531
- Switch from hardcoding all options in config.py to using parameters
532
for the template. This also allows us to use the more logical
533
auto_reload flag instead of reusing PROD_MODE, which is also used
537
- Treat comments, processing instructions, and named entities in the
538
source template as "literals", which will be rendered into the
539
output unchanged. [chrism]
543
- Skip elements in a "define-slot" clause if its being filled by the
544
calling template. [malthe]
546
- Support "fill-slot" on elements with METAL namespace. [malthe]
548
- Omit element text when rendering macro. [malthe]
550
- ``Macros`` class should not return callable functions, but rather a
551
``Macro`` object, which has a ``render``-method. This makes it
552
possible to use a path-expression to get to a macro without calling
555
- Fixed bug where a repeat-clause would reset the repeat variable
556
before evaluating the expression. [malthe]
558
- Fixed an issue related to correct restoring of ghosted template
561
- Implicit doctype is correctly reestablished from cache. [malthe]
563
- Remove namespace declaration on root tag to work around syntax error
564
raised when parsing an XML tree loaded from the file cache. [malthe]
566
- Attribute assignments with an expression value that started with the
567
characters ``in`` (e.g. ``info.somename``) would be rendered to the
568
generated Python without the ``in`` prefix (as
569
e.g. ``fo.somename``). [chrism]
571
- When filling METAL slots (possibly with a specific version of
572
libxml2, I am using 2.6.32) it was possible to cause the translator
573
to attempt to add a stringtype to a NoneType (on a line that reads
574
``variable = self.symbols.slot+element.node.fill_slot`` because an
575
XPath expression looking for fill-slot nodes did not work
578
- Preserve whitespace in string translation expressions. [malthe]
580
- Fixed interpolation bug where multiple attributes with interpolation
581
expressions would result in corrupted output. [malthe]
583
- Support try-except operator ('|') when 'python' is the default
584
expression type. [malthe]
586
- METAL macros should render in the template where they're
589
- Avoid printing a line-break when we repeat over a single item
592
- Corrected Genshi namespace (needs a trailing slash). [malthe]
594
- Fixed a few more UnicodeDecodeErrors (test contributed by Wiggy).
595
In particular, never upcast to unicode during transformation, and
596
utf-8 encode Unicode attribute keys and values in Assign expressions
597
(e.g. py:attrs). [chrism]
599
- Fixed off-by-one bug in interpolation routine. [malthe]
601
- The repeat-clause should not output tail with every iteration. [malthe]
603
- CDATA sections are now correctly handled when using the
604
ElementTree-parser. [malthe]
606
- Fixed bug in path-expressions where string instances would be
607
(attempted) called. [malthe]
609
- CDATA sections are now correctly preserved when using expression
610
interpolation. [malthe]
612
- The Genshi interpolation operator ${} should not have its result
613
escaped when used in the text or tail regions. [malthe]
615
- Fixed edge case bug where inserting both a numeric entity and a
616
literal set of unicode bytes into the same document would cause a
617
UnicodeDecodeError. See also
618
http://groups.google.com/group/z3c_pt/browse_thread/thread/aea963d25a1778d0?hl=en
621
- Static attributes are now properly overriden by py:attr-attributes.
627
- Added support for Genshi-templates.
630
- Cleanup and refactoring of translation module.
633
- If the template source contains a DOCTYPE declaration, output it
634
during rendering. [chrism]
636
- Fixed an error where numeric entities specified in text or tail
637
portions of elements would cause a UnicodeDecodeError to be raised
638
on systems configured with an 'ascii' default encoding. [chrism]
640
- Refactored file system based cache a bit and added a simple benchmark for
641
the cache. The initial load speed for a template goes down significantly
642
with the cache. Compared to zope.pagetemplate we are only 3x slower,
643
compared to 50x slower when cooking each template on process startup.
645
- Got rid entirely of the _escape function and inlined the actual code
646
instead. We go up again to 12x for path and 19x for Python expressions :)
649
- Avoid string concatenation and use multiple write statements instead. These
650
are faster now, since we use a list append internally.
653
- Inline the _escape function, because function calls are expensive in Python.
654
Added missing escaping for Unicode values.
657
- When templates are instantiated outside of a class-definition, a
658
relative file path will be made absolute using the module path.
661
- Simplified the _escape function handling by pulling in the str call into the
662
function. Corrected the bigtable hotshot test to only benchmark rendering.
664
- Replaced the cgi.escape function by an optimized local version, we go up
665
to 11x for path and 16x for Python expressions :) In the bigtable benchmark
666
the enhancement is more noticable - we are the same speed as spitfire -O1
667
templates now and just half the speed of -O3 :))
669
- Added a new benchmark test called bigtable that produces results which are
670
directly comparable to those produced by the bigtable.py benchmark in the
673
- Introduce a new config option called `Z3C_PT_DISABLE_I18N`. If this
674
environment variable is set to `true`, the template engine will not call
675
into the zope.i18n machinery anymore, but fall back to simple interpolation
676
in all cases. In a normal Zope environment that has the whole i18n
677
infrastructure set up, this will render the templates about 15x faster than
678
normal TAL, instead of only 10x faster at this point.
680
- Removed the `second rendering` tests from the benchmark suite. Since we
681
enable the file cache for the benchmarks, there's no difference between the
682
first and second rendering anymore after the cache file has been written.
684
- Require zope.i18n 3.5 and add support for using its new negotiate function.
685
If you use the `zope_i18n_allowed_languages` environment variable the target
686
language for a template is only negotiated once per template, instead of
687
once for each translate function call. This more than doubles the speed
688
and the benchmark is back at 9.2 times faster.
690
- Extended the i18n handling to respect the passed in translation context to
691
the template. Usually this is the request, which is passed on under the
692
internal name of `_context` into the render functions. After extending the
693
i18n tests to include a negotiator and message catalog the improvement is
694
only at 4.5 anymore, as most of the time is spent inside the i18n machinery.
696
- Added persistent file cache functionality. If the environment variable is
697
set, each file system based template will add a directory to the cache
698
(currently a SHA-1 of the file's absolute path is used as the folder name)
699
and in the folder one file per params for the template (cache filename is
700
the hash of the params). Once a template file is initialized, an instance
701
local registry is added, which then looks up all cached files and
702
pre-populates the registry with the render functions.
704
- Fixed interpolation edge case bugs.
707
- Added new `Z3C_PT_FILECACHE` environment variable pointing to a directory.
708
If set, this will be used to cache the compiled files.
710
- Added a second variation of the repeat clause, using a simple for loop. It
711
doesn't support the repeatdict, though and is therefor not used yet. Also
712
began work to add introspection facilities to clauses about the variables
713
being used in them. The simpler loop causes the benchmarks to go up to a
714
10.5 (old 9.5) for path expressions and 14.5 (12.5) for python expressions.
715
So the next step is to introduce an optimization phase, that can decide
716
which variant of the loops to use.
718
- Made the debug mode independent from the Python debug mode. You can now
719
specify an environment variable called `Z3C_PT_DEBUG` to enable it.
721
- Added some code in a filecache module that can later be used to write out
722
and reload the compiled Python code to and from the file system. We should
723
be able to avoid reparsing on Python process restart.
725
- Simplified the generated _escape code. cgi.escape's second argument is a
726
simple boolean and not a list of characters to quote.
728
- Use a simple list based BufferIO class instead of a cStringIO for the out
729
stream. Avoiding the need to encode Unicode data is a bigger win. We do
730
not support arbitrarily mixing of Unicode and non-ascii inside the engine.
732
- Merged two adjacent writes into one inside the Tag clause.
734
- Applied a bunch of micro-optimizations. ''.join({}) is slightly faster
735
than ''.join({}.keys()) and does the same. Avoid a try/except for error
736
handling in non-debug mode. Test against 'is None' instead of a boolean
737
check for the result of the template registry lookup. Made PROD_MODE
738
available defined as 'not DEBUG_MODE' in config.py, so we avoid the 'not'
741
- Added more benchmark tests for the file variants.
743
- Optimized 'is None' handling in Tag clause similar to the Write clause.
745
- Made the _out.write method directly available as _write in all scopes, so
746
we avoid the method lookup call each time.
748
- Optimized 'is None' handling in Write clause.
750
- Slightly refactored benchmark tests and added tests for the file variants.
752
- In debug mode the actual source code for file templates is written out to
753
a <filename>.source file, to make it easier to inspect it.
755
- Make debug mode setting explicit in a config.py. Currently it is bound to
756
Python's __debug__, which is False when run with -O and otherwise True.
758
- Use a simplified UnicodeWrite clause for the result of _translate calls,
759
as the result value is guaranteed to be Unicode.
761
- Added benchmark tests for i18n handling.
763
- Added more tests for i18n attributes handling.
765
- Don't generate empty mappings for expressions with a trailing semicolon.
767
- Fixed undefined name 'static' error in i18n attributes handling and added
768
quoting to i18n attributes.
770
- Added condition to the valid attributes on tags in the tal namespace.
772
- Made sure the traceback from the *first* template exception
773
is carried over to __traceback_info__
775
- Added template source annotations on exceptions raised while
776
rendering a template.
781
- Added support for 'nocall' and 'not' (for path-expressions).
783
- Added support for path- and string-expressions.
785
- Abstracted expression translation engine. Expression implementations
786
are now pluggable. Expression name pragmas are supported throughout.
788
- Formalized expression types
790
- Added support for 'structure'-keyword for replace and content.
792
- Result of 'replace' and 'content' is now escaped by default.
794
- Benchmark is now built as a custom testrunner
799
- Added support for comments; expressions are allowed
800
inside comments, i.e.
802
<!-- ${'Hello World!'} -->
804
Comments are always included.
809
- Added support for text templates; these allow expression
810
interpolation in non-XML documents like CSS stylesheets and
816
- Expression interpolation implemented.
821
- Engine now uses cStringIO yielding a 2.5x performance
822
improvement. Unicode is now handled correctly.
827
- Code optimization; bug fixing spree
829
- Added ``ViewPageTemplateFile`` class
831
- Added support for i18n
833
- Engine rewrite; improved code generation abstractions
838
- Major optimizations to the generated code
843
- First public release
847
Classifier: Programming Language :: Python
848
Classifier: Topic :: Text Processing :: Markup :: HTML
849
Classifier: Topic :: Text Processing :: Markup :: XML