annotate genshi/template/base.py @ 935:705727288d7e

Merge r1143 from py3k: add support for python 3 to remaining genshi.template components: * minor changes to track encoding=None API change in core genshi modules. * genshi/template/directives: * slightly odd syntax changes to make the 2to3 .next() fixer pick up *stream.next() * minor test fix for change in behaviour of division (/) in Python 3. * genshi/template/loader: * add 'b' to file modes to ensure it's loaded as bytes in Python 3. * use not isinstance(s, unicode) instead of isinstance(s, str) since the former is correctly converted by 2to3.
author hodgestar
date Fri, 18 Mar 2011 09:17:52 +0000
parents 85e4678337cf
children
rev   line source
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
2 #
897
85e4678337cf Update changelog and copyright years.
cmlenz
parents: 876
diff changeset
3 # Copyright (C) 2006-2010 Edgewall Software
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
4 # All rights reserved.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
5 #
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
8 # are also available at http://genshi.edgewall.org/wiki/License.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
9 #
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://genshi.edgewall.org/log/.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
13
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
14 """Basic templating functionality."""
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
15
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 817
diff changeset
16 from collections import deque
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
17 import os
609
237050080827 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
18 import sys
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
19
935
705727288d7e Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
20 from genshi.compat import StringIO, BytesIO
636
e0f12a6f3612 Follow-up to [751]: applying the optimization to text templates was actually slowing them down, so only do it for markup templates.
cmlenz
parents: 635
diff changeset
21 from genshi.core import Attrs, Stream, StreamEventKind, START, TEXT, _ensure
434
e065d7906b68 * Better method to propogate the full path to the template file on parse errors. Supersedes r513.
cmlenz
parents: 427
diff changeset
22 from genshi.input import ParseError
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
23
790
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
24 __all__ = ['Context', 'DirectiveFactory', 'Template', 'TemplateError',
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
25 'TemplateRuntimeError', 'TemplateSyntaxError', 'BadDirectiveError']
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 420
diff changeset
26 __docformat__ = 'restructuredtext en'
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
27
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
28
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
29 class TemplateError(Exception):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
30 """Base exception class for errors related to template processing."""
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
31
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
32 def __init__(self, message, filename=None, lineno=-1, offset=-1):
438
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
33 """Create the exception.
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
34
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
35 :param message: the error message
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
36 :param filename: the filename of the template
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
37 :param lineno: the number of line in the template at which the error
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
38 occurred
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
39 :param offset: the column number at which the error occurred
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
40 """
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
41 if filename is None:
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
42 filename = '<string>'
438
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
43 self.msg = message #: the error message string
407
ea71a51e0258 Move string interpolation code into separate module (`genshi.template.interpolation`).
cmlenz
parents: 405
diff changeset
44 if filename != '<string>' or lineno >= 0:
ea71a51e0258 Move string interpolation code into separate module (`genshi.template.interpolation`).
cmlenz
parents: 405
diff changeset
45 message = '%s (%s, line %d)' % (self.msg, filename, lineno)
438
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
46 Exception.__init__(self, message)
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
47 self.filename = filename #: the name of the template file
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
48 self.lineno = lineno #: the number of the line containing the error
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
49 self.offset = offset #: the offset on the line
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
50
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
51
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
52 class TemplateSyntaxError(TemplateError):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
53 """Exception raised when an expression in a template causes a Python syntax
438
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
54 error, or the template is not well-formed.
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
55 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
56
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
57 def __init__(self, message, filename=None, lineno=-1, offset=-1):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
58 """Create the exception
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
59
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
60 :param message: the error message
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
61 :param filename: the filename of the template
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
62 :param lineno: the number of line in the template at which the error
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
63 occurred
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
64 :param offset: the column number at which the error occurred
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
65 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
66 if isinstance(message, SyntaxError) and message.lineno is not None:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
67 message = str(message).replace(' (line %d)' % message.lineno, '')
438
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
68 TemplateError.__init__(self, message, filename, lineno)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
69
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
70
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
71 class BadDirectiveError(TemplateSyntaxError):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
72 """Exception raised when an unknown directive is encountered when parsing
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
73 a template.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
74
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
75 An unknown directive is any attribute using the namespace for directives,
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
76 with a local name that doesn't match any registered directive.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
77 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
78
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
79 def __init__(self, name, filename=None, lineno=-1):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
80 """Create the exception
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
81
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
82 :param name: the name of the directive
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
83 :param filename: the filename of the template
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
84 :param lineno: the number of line in the template at which the error
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
85 occurred
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
86 """
438
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
87 TemplateSyntaxError.__init__(self, 'bad directive "%s"' % name,
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
88 filename, lineno)
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
89
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
90
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
91 class TemplateRuntimeError(TemplateError):
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
92 """Exception raised when an the evaluation of a Python expression in a
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
93 template causes an error.
6fd7e4dc0318 Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
94 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
95
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
96
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
97 class Context(object):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
98 """Container for template input data.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
99
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
100 A context provides a stack of scopes (represented by dictionaries).
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
101
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
102 Template directives such as loops can push a new scope on the stack with
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
103 data that should only be available inside the loop. When the loop
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
104 terminates, that scope can get popped off the stack again.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
105
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
106 >>> ctxt = Context(one='foo', other=1)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
107 >>> ctxt.get('one')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
108 'foo'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
109 >>> ctxt.get('other')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
110 1
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
111 >>> ctxt.push(dict(one='frost'))
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
112 >>> ctxt.get('one')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
113 'frost'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
114 >>> ctxt.get('other')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
115 1
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
116 >>> ctxt.pop()
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
117 {'one': 'frost'}
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
118 >>> ctxt.get('one')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
119 'foo'
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
120 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
121
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
122 def __init__(self, **data):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
123 """Initialize the template context with the given keyword arguments as
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
124 data.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
125 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
126 self.frames = deque([data])
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
127 self.pop = self.frames.popleft
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
128 self.push = self.frames.appendleft
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
129 self._match_templates = []
553
887bbbfa4098 Store state information for py:choose outside of the regular context data.
cmlenz
parents: 548
diff changeset
130 self._choice_stack = []
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
131
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
132 # Helper functions for use in expressions
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
133 def defined(name):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
134 """Return whether a variable with the specified name exists in the
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
135 expression scope."""
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
136 return name in self
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
137 def value_of(name, default=None):
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
138 """If a variable of the specified name is defined, return its value.
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
139 Otherwise, return the provided default value, or ``None``."""
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
140 return self.get(name, default)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
141 data.setdefault('defined', defined)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
142 data.setdefault('value_of', value_of)
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
143
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
144 def __repr__(self):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
145 return repr(list(self.frames))
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
146
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
147 def __contains__(self, key):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
148 """Return whether a variable exists in any of the scopes.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
149
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
150 :param key: the name of the variable
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
151 """
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
152 return self._find(key)[1] is not None
564
b3b07279b86c Alias `__contains__` to `has_key` in `Context` class for code outside of Genshi that may expect that for some wild reason.
cmlenz
parents: 553
diff changeset
153 has_key = __contains__
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
154
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
155 def __delitem__(self, key):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
156 """Remove a variable from all scopes.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
157
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
158 :param key: the name of the variable
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
159 """
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
160 for frame in self.frames:
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
161 if key in frame:
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
162 del frame[key]
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
163
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
164 def __getitem__(self, key):
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
165 """Get a variables's value, starting at the current scope and going
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
166 upward.
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
167
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
168 :param key: the name of the variable
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
169 :return: the variable value
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
170 :raises KeyError: if the requested variable wasn't found in any scope
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
171 """
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
172 value, frame = self._find(key)
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
173 if frame is None:
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
174 raise KeyError(key)
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
175 return value
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
176
420
aa32588342ae Add support for `len()` to the `Context` class.
cmlenz
parents: 407
diff changeset
177 def __len__(self):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
178 """Return the number of distinctly named variables in the context.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
179
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
180 :return: the number of variables in the context
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
181 """
420
aa32588342ae Add support for `len()` to the `Context` class.
cmlenz
parents: 407
diff changeset
182 return len(self.items())
aa32588342ae Add support for `len()` to the `Context` class.
cmlenz
parents: 407
diff changeset
183
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
184 def __setitem__(self, key, value):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
185 """Set a variable in the current scope.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
186
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
187 :param key: the name of the variable
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
188 :param value: the variable value
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
189 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
190 self.frames[0][key] = value
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
191
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
192 def _find(self, key, default=None):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
193 """Retrieve a given variable's value and the frame it was found in.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
194
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
195 Intended primarily for internal use by directives.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
196
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
197 :param key: the name of the variable
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
198 :param default: the default value to return when the variable is not
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
199 found
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
200 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
201 for frame in self.frames:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
202 if key in frame:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
203 return frame[key], frame
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
204 return default, None
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
205
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
206 def get(self, key, default=None):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
207 """Get a variable's value, starting at the current scope and going
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
208 upward.
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
209
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
210 :param key: the name of the variable
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
211 :param default: the default value to return when the variable is not
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
212 found
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
213 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
214 for frame in self.frames:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
215 if key in frame:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
216 return frame[key]
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
217 return default
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
218
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
219 def keys(self):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
220 """Return the name of all variables in the context.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
221
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
222 :return: a list of variable names
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
223 """
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
224 keys = []
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
225 for frame in self.frames:
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
226 keys += [key for key in frame if key not in keys]
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
227 return keys
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
228
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
229 def items(self):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
230 """Return a list of ``(name, value)`` tuples for all variables in the
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
231 context.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
232
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
233 :return: a list of variables
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
234 """
405
bd5da099c113 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
235 return [(key, self.get(key)) for key in self.keys()]
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
236
731
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 715
diff changeset
237 def update(self, mapping):
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 715
diff changeset
238 """Update the context from the mapping provided."""
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 715
diff changeset
239 self.frames[0].update(mapping)
6514d9889ac8 Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
cmlenz
parents: 715
diff changeset
240
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
241 def push(self, data):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
242 """Push a new scope on the stack.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
243
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
244 :param data: the data dictionary to push on the context stack.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
245 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
246
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
247 def pop(self):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
248 """Pop the top-most scope from the stack."""
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
249
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
250
827
0319a8874510 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
251 def _apply_directives(stream, directives, ctxt, vars):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
252 """Apply the given directives to the stream.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
253
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
254 :param stream: the stream the directives should be applied to
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
255 :param directives: the list of directives to apply
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
256 :param ctxt: the `Context`
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
257 :param vars: additional variables that should be available when Python
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
258 code is executed
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
259 :return: the stream with the given directives applied
7800a61eae43 More API doc enhancements.
cmlenz
parents: 434
diff changeset
260 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
261 if directives:
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
262 stream = directives[0](iter(stream), directives[1:], ctxt, **vars)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
263 return stream
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
264
827
0319a8874510 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
265
0319a8874510 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
266 def _eval_expr(expr, ctxt, vars=None):
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
267 """Evaluate the given `Expression` object.
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
268
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
269 :param expr: the expression to evaluate
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
270 :param ctxt: the `Context`
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
271 :param vars: additional variables that should be available to the
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
272 expression
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
273 :return: the result of the evaluation
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
274 """
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
275 if vars:
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
276 ctxt.push(vars)
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
277 retval = expr.evaluate(ctxt)
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
278 if vars:
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
279 ctxt.pop()
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
280 return retval
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
281
827
0319a8874510 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
282
0319a8874510 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
283 def _exec_suite(suite, ctxt, vars=None):
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
284 """Execute the given `Suite` object.
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
285
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
286 :param suite: the code suite to execute
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
287 :param ctxt: the `Context`
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
288 :param vars: additional variables that should be available to the
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
289 code
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
290 """
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
291 if vars:
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
292 ctxt.push(vars)
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
293 ctxt.push({})
750
d007a0d7ba81 Remove some cruft for supporting Python 2.3.
cmlenz
parents: 731
diff changeset
294 suite.execute(ctxt)
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
295 if vars:
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
296 top = ctxt.pop()
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
297 ctxt.pop()
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
298 ctxt.frames[0].update(top)
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
299
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
300
790
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
301 class DirectiveFactoryMeta(type):
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
302 """Meta class for directive factories."""
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
303
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
304 def __new__(cls, name, bases, d):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
305 if 'directives' in d:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
306 d['_dir_by_name'] = dict(d['directives'])
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
307 d['_dir_order'] = [directive[1] for directive in d['directives']]
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
308
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
309 return type.__new__(cls, name, bases, d)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
310
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
311
790
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
312 class DirectiveFactory(object):
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
313 """Base for classes that provide a set of template directives.
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
314
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
315 :since: version 0.6
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
316 """
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
317 __metaclass__ = DirectiveFactoryMeta
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
318
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
319 directives = []
848
6c66e274198d Tiny docstring fix.
cmlenz
parents: 847
diff changeset
320 """A list of ``(name, cls)`` tuples that define the set of directives
790
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
321 provided by this factory.
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
322 """
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
323
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
324 def get_directive(self, name):
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
325 """Return the directive class for the given name.
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
326
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
327 :param name: the directive name as used in the template
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
328 :return: the directive class
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
329 :see: `Directive`
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
330 """
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
331 return self._dir_by_name.get(name)
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
332
847
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
333 def get_directive_index(self, dir_cls):
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
334 """Return a key for the given directive class that should be used to
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
335 sort it among other directives on the same `SUB` event.
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
336
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
337 The default implementation simply returns the index of the directive in
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
338 the `directives` list.
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
339
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
340 :param dir_cls: the directive class
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
341 :return: the sort key
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
342 """
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
343 if dir_cls in self._dir_order:
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
344 return self._dir_order.index(dir_cls)
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
345 return len(self._dir_order)
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
346
790
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
347
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
348 class Template(DirectiveFactory):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
349 """Abstract template base class.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
350
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
351 This class implements most of the template processing model, but does not
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
352 specify the syntax of templates.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
353 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
354
609
237050080827 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
355 EXEC = StreamEventKind('EXEC')
237050080827 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
356 """Stream event kind representing a Python code suite to execute."""
237050080827 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
357
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
358 EXPR = StreamEventKind('EXPR')
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
359 """Stream event kind representing a Python expression."""
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
360
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
361 INCLUDE = StreamEventKind('INCLUDE')
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
362 """Stream event kind representing the inclusion of another template."""
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
363
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
364 SUB = StreamEventKind('SUB')
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
365 """Stream event kind representing a nested stream to which one or more
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
366 directives should be applied.
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
367 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
368
605
bc5faca93699 Text templates now default to rendering as plain text; it is no longer necessary to explicitly specify the "text" method to the `render()` or `serialize()` method of the generated markup stream. See tickets #62 and #118.
cmlenz
parents: 590
diff changeset
369 serializer = None
636
e0f12a6f3612 Follow-up to [751]: applying the optimization to text templates was actually slowing them down, so only do it for markup templates.
cmlenz
parents: 635
diff changeset
370 _number_conv = unicode # function used to convert numbers to event data
605
bc5faca93699 Text templates now default to rendering as plain text; it is no longer necessary to explicitly specify the "text" method to the `render()` or `serialize()` method of the generated markup stream. See tickets #62 and #118.
cmlenz
parents: 590
diff changeset
371
714
7e6496bde18a The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
372 def __init__(self, source, filepath=None, filename=None, loader=None,
606
9ada030ad986 Changed the default error handling mode to "strict".
cmlenz
parents: 605
diff changeset
373 encoding=None, lookup='strict', allow_exec=True):
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
374 """Initialize a template from either a string, a file-like object, or
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
375 an already parsed markup stream.
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
376
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
377 :param source: a string, file-like object, or markup stream to read the
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
378 template from
714
7e6496bde18a The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
379 :param filepath: the absolute path to the template file
7e6496bde18a The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
380 :param filename: the path to the template file relative to the search
7e6496bde18a The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
381 path
492
460b1f0db935 Fix docstring typo.
cmlenz
parents: 475
diff changeset
382 :param loader: the `TemplateLoader` to use for loading included
460b1f0db935 Fix docstring typo.
cmlenz
parents: 475
diff changeset
383 templates
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
384 :param encoding: the encoding of the `source`
606
9ada030ad986 Changed the default error handling mode to "strict".
cmlenz
parents: 605
diff changeset
385 :param lookup: the variable lookup mechanism; either "strict" (the
9ada030ad986 Changed the default error handling mode to "strict".
cmlenz
parents: 605
diff changeset
386 default), "lenient", or a custom lookup class
545
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
387 :param allow_exec: whether Python code blocks in templates should be
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
388 allowed
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
389
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
390 :note: Changed in 0.5: Added the `allow_exec` argument
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
391 """
714
7e6496bde18a The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 700
diff changeset
392 self.filepath = filepath or filename
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
393 self.filename = filename
363
caf7b68ab5dc Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 362
diff changeset
394 self.loader = loader
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 438
diff changeset
395 self.lookup = lookup
545
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
396 self.allow_exec = allow_exec
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
397 self._init_filters()
876
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
398 self._init_loader()
790
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
399 self._prepared = False
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
400
935
705727288d7e Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
401 if not isinstance(source, Stream) and not hasattr(source, 'read'):
705727288d7e Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
402 if isinstance(source, unicode):
705727288d7e Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
403 source = StringIO(source)
705727288d7e Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
404 else:
705727288d7e Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
405 source = BytesIO(source)
434
e065d7906b68 * Better method to propogate the full path to the template file on parse errors. Supersedes r513.
cmlenz
parents: 427
diff changeset
406 try:
790
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
407 self._stream = self._parse(source, encoding)
434
e065d7906b68 * Better method to propogate the full path to the template file on parse errors. Supersedes r513.
cmlenz
parents: 427
diff changeset
408 except ParseError, e:
e065d7906b68 * Better method to propogate the full path to the template file on parse errors. Supersedes r513.
cmlenz
parents: 427
diff changeset
409 raise TemplateSyntaxError(e.msg, self.filepath, e.lineno, e.offset)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
410
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
411 def __getstate__(self):
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
412 state = self.__dict__.copy()
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
413 state['filters'] = []
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
414 return state
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
415
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
416 def __setstate__(self, state):
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
417 self.__dict__ = state
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
418 self._init_filters()
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
419
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
420 def __repr__(self):
860
61d37796da98 A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents: 855
diff changeset
421 return '<%s "%s">' % (type(self).__name__, self.filename)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
422
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
423 def _init_filters(self):
876
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
424 self.filters = [self._flatten, self._include]
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
425
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
426 def _init_loader(self):
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
427 if self.loader is None:
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
428 from genshi.template.loader import TemplateLoader
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
429 if self.filename:
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
430 if self.filepath != self.filename:
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
431 basedir = os.path.normpath(self.filepath)[:-len(
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
432 os.path.normpath(self.filename))
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
433 ]
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
434 else:
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
435 basedir = os.path.dirname(self.filename)
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
436 else:
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
437 basedir = '.'
52d7d6b7b6c1 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents: 860
diff changeset
438 self.loader = TemplateLoader([os.path.abspath(basedir)])
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
439
822
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 817
diff changeset
440 @property
ce5ad2d540b3 Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents: 817
diff changeset
441 def stream(self):
790
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
442 if not self._prepared:
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
443 self._stream = list(self._prepare(self._stream))
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
444 self._prepared = True
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
445 return self._stream
1b6968d31089 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
446
374
ca46dc9c7761 `MarkupTemplate`s can now be instantiated from markup streams, in addition to strings and file-like objects. Thanks to David Fraser for the patch. Closes #69.
cmlenz
parents: 363
diff changeset
447 def _parse(self, source, encoding):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
448 """Parse the template.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
449
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
450 The parsing stage parses the template and constructs a list of
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
451 directives that will be executed in the render stage. The input is
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
452 split up into literal output (text that does not depend on the context
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
453 data) and directives or expressions.
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
454
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
455 :param source: a file-like object containing the XML source of the
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
456 template, or an XML event stream
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
457 :param encoding: the encoding of the `source`
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
458 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
459 raise NotImplementedError
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
460
351
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
461 def _prepare(self, stream):
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
462 """Call the `attach` method of every directive found in the template.
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
463
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
464 :param stream: the event stream of the template
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
465 """
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
466 from genshi.template.loader import TemplateNotFound
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
467
351
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
468 for kind, data, pos in stream:
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
469 if kind is SUB:
362
0910d5978f45 Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents: 361
diff changeset
470 directives = []
0910d5978f45 Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents: 361
diff changeset
471 substream = data[1]
847
4f9e5e6f1aab Backported a couple of templating core changes from the advanced-i18n branch, in particular considering the determination of directive ordering../set
cmlenz
parents: 843
diff changeset
472 for _, cls, value, namespaces, pos in sorted(data[0]):
362
0910d5978f45 Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents: 361
diff changeset
473 directive, substream = cls.attach(self, substream, value,
0910d5978f45 Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents: 361
diff changeset
474 namespaces, pos)
0910d5978f45 Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents: 361
diff changeset
475 if directive:
0910d5978f45 Follow-up to [431]: directives are no longer instantiated directly at parse time, but instead by the `attach()` method of the directive class (which replaces the `prepare()` method).
cmlenz
parents: 361
diff changeset
476 directives.append(directive)
351
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
477 substream = self._prepare(substream)
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
478 if directives:
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
479 yield kind, (directives, list(substream)), pos
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
480 else:
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
481 for event in substream:
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
482 yield event
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
483 else:
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
484 if kind is INCLUDE:
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
485 href, cls, fallback = data
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
486 if isinstance(href, basestring) and \
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
487 not getattr(self.loader, 'auto_reload', True):
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
488 # If the path to the included template is static, and
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
489 # auto-reloading is disabled on the template loader,
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
490 # the template is inlined into the stream
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
491 try:
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
492 tmpl = self.loader.load(href, relative_to=pos[0],
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
493 cls=cls or self.__class__)
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
494 for event in tmpl.stream:
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
495 yield event
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
496 except TemplateNotFound:
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
497 if fallback is None:
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
498 raise
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
499 for event in self._prepare(fallback):
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
500 yield event
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
501 continue
590
880b1a75d046 Fix includes so that they again raise an exception when the included template is not found and no fallback has been provided.
cmlenz
parents: 564
diff changeset
502 elif fallback:
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
503 # Otherwise the include is performed at run time
639
b0cdc457dde9 Fix for XInclude fallbacks when auto-reloading is enabled. Closes #147. Thanks to rintaro@cpan.org for reporting the issue and providing a patch and test case!
cmlenz
parents: 636
diff changeset
504 data = href, cls, list(self._prepare(fallback))
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
505
351
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
506 yield kind, data, pos
50f4e199e3aa The `py:content`, `py:replace`, and `py:strip=""` directives are now expanded when the template is loaded (as opposed to when it's rendered).
cmlenz
parents: 345
diff changeset
507
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
508 def generate(self, *args, **kwargs):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
509 """Apply the template to the given context data.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
510
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
511 Any keyword arguments are made available to the template as context
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
512 data.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
513
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
514 Only one positional argument is accepted: if it is provided, it must be
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
515 an instance of the `Context` class, and keyword arguments are ignored.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
516 This calling style is used for internal processing.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
517
427
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
518 :return: a markup event stream representing the result of applying
68a8308309b9 More API documentation.
cmlenz
parents: 425
diff changeset
519 the template to the context data.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
520 """
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
521 vars = {}
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
522 if args:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
523 assert len(args) == 1
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
524 ctxt = args[0]
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
525 if ctxt is None:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
526 ctxt = Context(**kwargs)
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
527 else:
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
528 vars = kwargs
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
529 assert isinstance(ctxt, Context)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
530 else:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
531 ctxt = Context(**kwargs)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
532
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
533 stream = self.stream
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
534 for filter_ in self.filters:
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
535 stream = filter_(iter(stream), ctxt, **vars)
605
bc5faca93699 Text templates now default to rendering as plain text; it is no longer necessary to explicitly specify the "text" method to the `render()` or `serialize()` method of the generated markup stream. See tickets #62 and #118.
cmlenz
parents: 590
diff changeset
536 return Stream(stream, self.serializer)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
537
813
3047d5d83ccc Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
538 def _flatten(self, stream, ctxt, **vars):
636
e0f12a6f3612 Follow-up to [751]: applying the optimization to text templates was actually slowing them down, so only do it for markup templates.
cmlenz
parents: 635
diff changeset
539 number_conv = self._number_conv
843
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
540 stack = []
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
541 push = stack.append
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
542 pop = stack.pop
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
543 stream = iter(stream)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
544
843
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
545 while 1:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
546 for kind, data, pos in stream:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
547
843
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
548 if kind is START and data[1]:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
549 # Attributes may still contain expressions in start tags at
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
550 # this point, so do some evaluation
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
551 tag, attrs = data
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
552 new_attrs = []
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
553 for name, value in attrs:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
554 if type(value) is list: # this is an interpolated string
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
555 values = [event[1]
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
556 for event in self._flatten(value, ctxt, **vars)
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
557 if event[0] is TEXT and event[1] is not None
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
558 ]
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
559 if not values:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
560 continue
855
9598353ed630 More 2to3 diff size reduction.
cmlenz
parents: 848
diff changeset
561 value = ''.join(values)
843
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
562 new_attrs.append((name, value))
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
563 yield kind, (tag, Attrs(new_attrs)), pos
813
3047d5d83ccc Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
564
843
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
565 elif kind is EXPR:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
566 result = _eval_expr(data, ctxt, vars)
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
567 if result is not None:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
568 # First check for a string, otherwise the iterable test
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
569 # below succeeds, and the string will be chopped up into
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
570 # individual characters
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
571 if isinstance(result, basestring):
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
572 yield TEXT, result, pos
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
573 elif isinstance(result, (int, float, long)):
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
574 yield TEXT, number_conv(result), pos
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
575 elif hasattr(result, '__iter__'):
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
576 push(stream)
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
577 stream = _ensure(result)
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
578 break
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
579 else:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
580 yield TEXT, unicode(result), pos
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
581
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
582 elif kind is SUB:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
583 # This event is a list of directives and a list of nested
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
584 # events to which those directives should be applied
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
585 push(stream)
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
586 stream = _apply_directives(data[1], data[0], ctxt, vars)
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
587 break
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
588
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
589 elif kind is EXEC:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
590 _exec_suite(data, ctxt, vars)
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
591
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
592 else:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
593 yield kind, data, pos
813
3047d5d83ccc Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
594
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
595 else:
843
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
596 if not stack:
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
597 break
004f81b59d97 Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
598 stream = pop()
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
599
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
600 def _include(self, stream, ctxt, **vars):
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
601 """Internal stream filter that performs inclusion of external
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
602 template files.
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
603 """
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
604 from genshi.template.loader import TemplateNotFound
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
605
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
606 for event in stream:
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
607 if event[0] is INCLUDE:
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
608 href, cls, fallback = event[1]
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
609 if not isinstance(href, basestring):
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
610 parts = []
813
3047d5d83ccc Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
611 for subkind, subdata, subpos in self._flatten(href, ctxt,
3047d5d83ccc Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
612 **vars):
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
613 if subkind is TEXT:
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
614 parts.append(subdata)
855
9598353ed630 More 2to3 diff size reduction.
cmlenz
parents: 848
diff changeset
615 href = ''.join([x for x in parts if x is not None])
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
616 try:
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
617 tmpl = self.loader.load(href, relative_to=event[2][0],
610
6a37018199fd * XInclude elements in markup templates now support the `parse` attribute; when set to "xml" (the default), the include is processed as before, but when set to "text", the included template is parsed as a text template using the new syntax (ticket #101).
cmlenz
parents: 609
diff changeset
618 cls=cls or self.__class__)
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
619 for event in tmpl.generate(ctxt, **vars):
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
620 yield event
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
621 except TemplateNotFound:
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
622 if fallback is None:
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
623 raise
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
624 for filter_ in self.filters:
700
8d079cee6822 Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
625 fallback = filter_(iter(fallback), ctxt, **vars)
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
626 for event in fallback:
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
627 yield event
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
628 else:
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
629 yield event
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
630
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
631
609
237050080827 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
632 EXEC = Template.EXEC
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
633 EXPR = Template.EXPR
475
bb939ed3058c Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
634 INCLUDE = Template.INCLUDE
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
635 SUB = Template.SUB
Copyright (C) 2012-2017 Edgewall Software