annotate genshi/template/base.py @ 1012:cdb5d435d237 trunk

Fix assert with side-effect in xi:fallback directive processing (see #565).
author hodgestar
date Mon, 17 Jun 2013 20:52:21 +0000
parents 0f9fe59dfa00
children 6fc92535c888 5dccab13ec85
rev   line source
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
2 #
897
64f04a2c5e66 Update changelog and copyright years.
cmlenz
parents: 876
diff changeset
3 # Copyright (C) 2006-2010 Edgewall Software
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
4 # All rights reserved.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
5 #
7763f7aec949 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
7763f7aec949 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
7763f7aec949 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.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
9 #
7763f7aec949 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
7763f7aec949 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
7763f7aec949 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/.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
13
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
14 """Basic templating functionality."""
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
15
822
70fddd2262f5 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
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
17 import os
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
18 import sys
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
19
935
59463031d904 Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
20 from genshi.compat import StringIO, BytesIO
636
699601cce3cc 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
5692bc32ba5f * 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
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
23
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
24 __all__ = ['Context', 'DirectiveFactory', 'Template', 'TemplateError',
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
25 'TemplateRuntimeError', 'TemplateSyntaxError', 'BadDirectiveError']
425
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 420
diff changeset
26 __docformat__ = 'restructuredtext en'
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
27
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
28
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
29 class TemplateError(Exception):
7763f7aec949 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."""
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
31
610
5e358de79e4c * 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
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
33 """Create the exception.
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
34
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
35 :param message: the error message
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
36 :param filename: the filename of the template
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
37 :param lineno: the number of line in the template at which the error
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
38 occurred
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
39 :param offset: the column number at which the error occurred
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
40 """
610
5e358de79e4c * 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:
5e358de79e4c * 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
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
43 self.msg = message #: the error message string
407
f37d8e6acdf2 Move string interpolation code into separate module (`genshi.template.interpolation`).
cmlenz
parents: 405
diff changeset
44 if filename != '<string>' or lineno >= 0:
f37d8e6acdf2 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
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
46 Exception.__init__(self, message)
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
47 self.filename = filename #: the name of the template file
2c38ec4e2dff 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
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
49 self.offset = offset #: the offset on the line
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
50
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
51
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
52 class TemplateSyntaxError(TemplateError):
7763f7aec949 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
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
54 error, or the template is not well-formed.
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
55 """
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
56
610
5e358de79e4c * 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
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
58 """Create the exception
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
59
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
60 :param message: the error message
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
61 :param filename: the filename of the template
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
62 :param lineno: the number of line in the template at which the error
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
63 occurred
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
64 :param offset: the column number at which the error occurred
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
65 """
336
7763f7aec949 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:
7763f7aec949 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
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
68 TemplateError.__init__(self, message, filename, lineno)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
69
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
70
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
71 class BadDirectiveError(TemplateSyntaxError):
7763f7aec949 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
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
73 a template.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
74
7763f7aec949 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,
7763f7aec949 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.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
77 """
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
78
610
5e358de79e4c * 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
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
80 """Create the exception
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
81
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
82 :param name: the name of the directive
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
83 :param filename: the filename of the template
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
84 :param lineno: the number of line in the template at which the error
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
85 occurred
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
86 """
438
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
87 TemplateSyntaxError.__init__(self, 'bad directive "%s"' % name,
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
88 filename, lineno)
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
89
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
90
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
91 class TemplateRuntimeError(TemplateError):
2c38ec4e2dff 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
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
93 template causes an error.
2c38ec4e2dff Added documentation page on the builtin stream filters.
cmlenz
parents: 435
diff changeset
94 """
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
95
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
96
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
97 class Context(object):
7763f7aec949 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.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
99
7763f7aec949 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).
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
101
7763f7aec949 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
7763f7aec949 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
7763f7aec949 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.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
105
7763f7aec949 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)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
107 >>> ctxt.get('one')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
108 'foo'
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
109 >>> ctxt.get('other')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
110 1
7763f7aec949 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'))
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
112 >>> ctxt.get('one')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
113 'frost'
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
114 >>> ctxt.get('other')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
115 1
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
116 >>> ctxt.pop()
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
117 {'one': 'frost'}
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
118 >>> ctxt.get('one')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
119 'foo'
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
120 """
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
121
7763f7aec949 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
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
123 """Initialize the template context with the given keyword arguments as
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
124 data.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
125 """
336
7763f7aec949 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])
7763f7aec949 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
7763f7aec949 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
7763f7aec949 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
489a47873950 Store state information for py:choose outside of the regular context data.
cmlenz
parents: 548
diff changeset
130 self._choice_stack = []
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
131
442
97544725bb7f 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
97544725bb7f 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):
97544725bb7f 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
97544725bb7f 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."""
97544725bb7f 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
97544725bb7f 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):
97544725bb7f 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.
97544725bb7f 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``."""
97544725bb7f 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)
97544725bb7f 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)
97544725bb7f 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)
97544725bb7f 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
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
144 def __repr__(self):
7763f7aec949 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))
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
146
405
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
147 def __contains__(self, key):
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
148 """Return whether a variable exists in any of the scopes.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
149
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
150 :param key: the name of the variable
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
151 """
405
5340931530e2 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
aeb89e9730df 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
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
154
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
155 def __delitem__(self, key):
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
156 """Remove a variable from all scopes.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
157
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
158 :param key: the name of the variable
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
159 """
405
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
160 for frame in self.frames:
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
161 if key in frame:
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
162 del frame[key]
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
163
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
164 def __getitem__(self, key):
5340931530e2 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
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
166 upward.
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
167
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
168 :param key: the name of the variable
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
169 :return: the variable value
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
170 :raises KeyError: if the requested variable wasn't found in any scope
405
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
171 """
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
172 value, frame = self._find(key)
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
173 if frame is None:
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
174 raise KeyError(key)
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
175 return value
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
176
420
91556138dae5 Add support for `len()` to the `Context` class.
cmlenz
parents: 407
diff changeset
177 def __len__(self):
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
178 """Return the number of distinctly named variables in the context.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
179
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
180 :return: the number of variables in the context
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
181 """
420
91556138dae5 Add support for `len()` to the `Context` class.
cmlenz
parents: 407
diff changeset
182 return len(self.items())
91556138dae5 Add support for `len()` to the `Context` class.
cmlenz
parents: 407
diff changeset
183
336
7763f7aec949 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
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
185 """Set a variable in the current scope.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
186
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
187 :param key: the name of the variable
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
188 :param value: the variable value
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
189 """
336
7763f7aec949 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
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
191
7763f7aec949 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):
7763f7aec949 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.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
194
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
195 Intended primarily for internal use by directives.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
196
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
197 :param key: the name of the variable
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
198 :param default: the default value to return when the variable is not
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
199 found
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
200 """
7763f7aec949 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:
7763f7aec949 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:
7763f7aec949 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
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
204 return default, None
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
205
7763f7aec949 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):
7763f7aec949 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
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
208 upward.
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
209
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
210 :param key: the name of the variable
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
211 :param default: the default value to return when the variable is not
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
212 found
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
213 """
7763f7aec949 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:
7763f7aec949 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:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
216 return frame[key]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
217 return default
405
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
218
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
219 def keys(self):
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
220 """Return the name of all variables in the context.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
221
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
222 :return: a list of variable names
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
223 """
405
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
224 keys = []
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
225 for frame in self.frames:
5340931530e2 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]
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
227 return keys
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
228
5340931530e2 Support for Python code blocks using the `<?python ?>` processing instruction. Closes #84.
cmlenz
parents: 400
diff changeset
229 def items(self):
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
230 """Return a list of ``(name, value)`` tuples for all variables in the
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
231 context.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
232
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
233 :return: a list of variables
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
234 """
405
5340931530e2 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
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
236
731
01bdf155db95 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):
01bdf155db95 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."""
01bdf155db95 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)
01bdf155db95 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
7763f7aec949 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
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
242 """Push a new scope on the stack.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
243
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
244 :param data: the data dictionary to push on the context stack.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
245 """
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
246
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
247 def pop(self):
7763f7aec949 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."""
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
249
947
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
250 def copy(self):
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
251 """Create a copy of this Context object."""
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
252 # required to make f_locals a dict-like object
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
253 # See http://genshi.edgewall.org/ticket/249 for
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
254 # example use case in Twisted tracebacks
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
255 ctxt = Context()
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
256 ctxt.frames.pop() # pop empty dummy context
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
257 ctxt.frames.extend(self.frames)
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
258 ctxt._match_templates.extend(self._match_templates)
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
259 ctxt._choice_stack.extend(self._choice_stack)
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
260 return ctxt
0f9fe59dfa00 Add .copy() function to Context objects. Fixes #249.
hodgestar
parents: 935
diff changeset
261
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
262
827
bebc68529176 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
263 def _apply_directives(stream, directives, ctxt, vars):
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
264 """Apply the given directives to the stream.
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
265
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
266 :param stream: the stream the directives should be applied to
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
267 :param directives: the list of directives to apply
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
268 :param ctxt: the `Context`
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
269 :param vars: additional variables that should be available when Python
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
270 code is executed
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
271 :return: the stream with the given directives applied
be39660919a5 More API doc enhancements.
cmlenz
parents: 434
diff changeset
272 """
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
273 if directives:
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
274 stream = directives[0](iter(stream), directives[1:], ctxt, **vars)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
275 return stream
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
276
827
bebc68529176 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
277
bebc68529176 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
278 def _eval_expr(expr, ctxt, vars=None):
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
279 """Evaluate the given `Expression` object.
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
280
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
281 :param expr: the expression to evaluate
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
282 :param ctxt: the `Context`
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
283 :param vars: additional variables that should be available to the
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
284 expression
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
285 :return: the result of the evaluation
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
286 """
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
287 if vars:
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
288 ctxt.push(vars)
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
289 retval = expr.evaluate(ctxt)
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
290 if vars:
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
291 ctxt.pop()
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
292 return retval
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
293
827
bebc68529176 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
294
bebc68529176 Avoid varargs on internal functions in template processing for slightly better performance.
cmlenz
parents: 825
diff changeset
295 def _exec_suite(suite, ctxt, vars=None):
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
296 """Execute the given `Suite` object.
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
297
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
298 :param suite: the code suite to execute
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
299 :param ctxt: the `Context`
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
300 :param vars: additional variables that should be available to the
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
301 code
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
302 """
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
303 if vars:
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
304 ctxt.push(vars)
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
305 ctxt.push({})
750
52219748e5c1 Remove some cruft for supporting Python 2.3.
cmlenz
parents: 731
diff changeset
306 suite.execute(ctxt)
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
307 if vars:
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
308 top = ctxt.pop()
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
309 ctxt.pop()
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
310 ctxt.frames[0].update(top)
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
311
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
312
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
313 class DirectiveFactoryMeta(type):
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
314 """Meta class for directive factories."""
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
315
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
316 def __new__(cls, name, bases, d):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
317 if 'directives' in d:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
318 d['_dir_by_name'] = dict(d['directives'])
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
319 d['_dir_order'] = [directive[1] for directive in d['directives']]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
320
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
321 return type.__new__(cls, name, bases, d)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
322
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
323
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
324 class DirectiveFactory(object):
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
325 """Base for classes that provide a set of template directives.
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
326
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
327 :since: version 0.6
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
328 """
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
329 __metaclass__ = DirectiveFactoryMeta
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
330
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
331 directives = []
848
c1d317c0df68 Tiny docstring fix.
cmlenz
parents: 847
diff changeset
332 """A list of ``(name, cls)`` tuples that define the set of directives
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
333 provided by this factory.
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
334 """
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
335
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
336 def get_directive(self, name):
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
337 """Return the directive class for the given name.
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
338
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
339 :param name: the directive name as used in the template
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
340 :return: the directive class
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
341 :see: `Directive`
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
342 """
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
343 return self._dir_by_name.get(name)
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
344
847
e16447a9605f 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 def get_directive_index(self, dir_cls):
e16447a9605f 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 """Return a key for the given directive class that should be used to
e16447a9605f 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
347 sort it among other directives on the same `SUB` event.
e16447a9605f 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
348
e16447a9605f 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
349 The default implementation simply returns the index of the directive in
e16447a9605f 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
350 the `directives` list.
e16447a9605f 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
351
e16447a9605f 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
352 :param dir_cls: the directive class
e16447a9605f 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
353 :return: the sort key
e16447a9605f 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
354 """
e16447a9605f 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
355 if dir_cls in self._dir_order:
e16447a9605f 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
356 return self._dir_order.index(dir_cls)
e16447a9605f 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
357 return len(self._dir_order)
e16447a9605f 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
358
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
359
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
360 class Template(DirectiveFactory):
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
361 """Abstract template base class.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
362
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
363 This class implements most of the template processing model, but does not
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
364 specify the syntax of templates.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
365 """
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
366
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
367 EXEC = StreamEventKind('EXEC')
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
368 """Stream event kind representing a Python code suite to execute."""
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
369
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
370 EXPR = StreamEventKind('EXPR')
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
371 """Stream event kind representing a Python expression."""
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
372
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
373 INCLUDE = StreamEventKind('INCLUDE')
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
374 """Stream event kind representing the inclusion of another template."""
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
375
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
376 SUB = StreamEventKind('SUB')
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
377 """Stream event kind representing a nested stream to which one or more
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
378 directives should be applied.
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
379 """
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
380
605
d0345c64da65 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
381 serializer = None
636
699601cce3cc 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
382 _number_conv = unicode # function used to convert numbers to event data
605
d0345c64da65 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
383
714
fc6d9d2a3527 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
384 def __init__(self, source, filepath=None, filename=None, loader=None,
606
37ff75bb4301 Changed the default error handling mode to "strict".
cmlenz
parents: 605
diff changeset
385 encoding=None, lookup='strict', allow_exec=True):
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
386 """Initialize a template from either a string, a file-like object, or
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
387 an already parsed markup stream.
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
388
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
389 :param source: a string, file-like object, or markup stream to read the
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
390 template from
714
fc6d9d2a3527 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
391 :param filepath: the absolute path to the template file
fc6d9d2a3527 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 :param filename: the path to the template file relative to the search
fc6d9d2a3527 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
393 path
492
fd10321bb1ba Fix docstring typo.
cmlenz
parents: 475
diff changeset
394 :param loader: the `TemplateLoader` to use for loading included
fd10321bb1ba Fix docstring typo.
cmlenz
parents: 475
diff changeset
395 templates
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
396 :param encoding: the encoding of the `source`
606
37ff75bb4301 Changed the default error handling mode to "strict".
cmlenz
parents: 605
diff changeset
397 :param lookup: the variable lookup mechanism; either "strict" (the
37ff75bb4301 Changed the default error handling mode to "strict".
cmlenz
parents: 605
diff changeset
398 default), "lenient", or a custom lookup class
545
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
399 :param allow_exec: whether Python code blocks in templates should be
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
400 allowed
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
401
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
402 :note: Changed in 0.5: Added the `allow_exec` argument
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
403 """
714
fc6d9d2a3527 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
404 self.filepath = filepath or filename
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
405 self.filename = filename
363
37e4b4bb0b53 Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 362
diff changeset
406 self.loader = loader
442
97544725bb7f 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
407 self.lookup = lookup
545
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 492
diff changeset
408 self.allow_exec = allow_exec
715
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
409 self._init_filters()
876
124b57282f81 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
410 self._init_loader()
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
411 self._prepared = False
610
5e358de79e4c * 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
412
935
59463031d904 Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
413 if not isinstance(source, Stream) and not hasattr(source, 'read'):
59463031d904 Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
414 if isinstance(source, unicode):
59463031d904 Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
415 source = StringIO(source)
59463031d904 Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
416 else:
59463031d904 Merge r1143 from py3k:
hodgestar
parents: 897
diff changeset
417 source = BytesIO(source)
434
5692bc32ba5f * Better method to propogate the full path to the template file on parse errors. Supersedes r513.
cmlenz
parents: 427
diff changeset
418 try:
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
419 self._stream = self._parse(source, encoding)
434
5692bc32ba5f * Better method to propogate the full path to the template file on parse errors. Supersedes r513.
cmlenz
parents: 427
diff changeset
420 except ParseError, e:
5692bc32ba5f * Better method to propogate the full path to the template file on parse errors. Supersedes r513.
cmlenz
parents: 427
diff changeset
421 raise TemplateSyntaxError(e.msg, self.filepath, e.lineno, e.offset)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
422
715
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
423 def __getstate__(self):
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
424 state = self.__dict__.copy()
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
425 state['filters'] = []
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
426 return state
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
427
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
428 def __setstate__(self, state):
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
429 self.__dict__ = state
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
430 self._init_filters()
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
431
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
432 def __repr__(self):
860
16d55698006a A bit of cleanup of the `Markup` Python implementation.
cmlenz
parents: 855
diff changeset
433 return '<%s "%s">' % (type(self).__name__, self.filename)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
434
715
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
435 def _init_filters(self):
876
124b57282f81 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 self.filters = [self._flatten, self._include]
124b57282f81 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
124b57282f81 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 def _init_loader(self):
124b57282f81 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
439 if self.loader is None:
124b57282f81 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
440 from genshi.template.loader import TemplateLoader
124b57282f81 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
441 if self.filename:
124b57282f81 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
442 if self.filepath != self.filename:
124b57282f81 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
443 basedir = os.path.normpath(self.filepath)[:-len(
124b57282f81 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
444 os.path.normpath(self.filename))
124b57282f81 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
445 ]
124b57282f81 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
446 else:
124b57282f81 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
447 basedir = os.path.dirname(self.filename)
124b57282f81 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
448 else:
124b57282f81 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
449 basedir = '.'
124b57282f81 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
450 self.loader = TemplateLoader([os.path.abspath(basedir)])
715
b5bd8c109209 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 714
diff changeset
451
822
70fddd2262f5 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
452 @property
70fddd2262f5 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
453 def stream(self):
790
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
454 if not self._prepared:
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
455 self._stream = list(self._prepare(self._stream))
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
456 self._prepared = True
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
457 return self._stream
da90cee22560 Merged the custom-directives branch back into trunk.
cmlenz
parents: 750
diff changeset
458
374
b146277eb54a `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
459 def _parse(self, source, encoding):
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
460 """Parse the template.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
461
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
462 The parsing stage parses the template and constructs a list of
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
463 directives that will be executed in the render stage. The input is
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
464 split up into literal output (text that does not depend on the context
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
465 data) and directives or expressions.
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
466
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
467 :param source: a file-like object containing the XML source of the
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
468 template, or an XML event stream
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
469 :param encoding: the encoding of the `source`
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
470 """
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
471 raise NotImplementedError
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
472
351
0cc031745884 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
473 def _prepare(self, stream):
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
474 """Call the `attach` method of every directive found in the template.
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
475
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
476 :param stream: the event stream of the template
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
477 """
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
478 from genshi.template.loader import TemplateNotFound
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
479
351
0cc031745884 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 for kind, data, pos in stream:
0cc031745884 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 if kind is SUB:
362
fe40d34fb71d 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
482 directives = []
fe40d34fb71d 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
483 substream = data[1]
847
e16447a9605f 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
484 for _, cls, value, namespaces, pos in sorted(data[0]):
362
fe40d34fb71d 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
485 directive, substream = cls.attach(self, substream, value,
fe40d34fb71d 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
486 namespaces, pos)
fe40d34fb71d 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
487 if directive:
fe40d34fb71d 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
488 directives.append(directive)
351
0cc031745884 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
489 substream = self._prepare(substream)
0cc031745884 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
490 if directives:
0cc031745884 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
491 yield kind, (directives, list(substream)), pos
0cc031745884 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
492 else:
0cc031745884 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
493 for event in substream:
0cc031745884 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
494 yield event
0cc031745884 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
495 else:
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
496 if kind is INCLUDE:
610
5e358de79e4c * 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
497 href, cls, fallback = data
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
498 if isinstance(href, basestring) and \
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
499 not getattr(self.loader, 'auto_reload', True):
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
500 # If the path to the included template is static, and
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
501 # auto-reloading is disabled on the template loader,
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
502 # the template is inlined into the stream
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
503 try:
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
504 tmpl = self.loader.load(href, relative_to=pos[0],
610
5e358de79e4c * 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
505 cls=cls or self.__class__)
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
506 for event in tmpl.stream:
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
507 yield event
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
508 except TemplateNotFound:
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
509 if fallback is None:
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
510 raise
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
511 for event in self._prepare(fallback):
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
512 yield event
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
513 continue
590
36b5a03534a0 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
514 elif fallback:
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
515 # Otherwise the include is performed at run time
639
8e11a6693bb3 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
516 data = href, cls, list(self._prepare(fallback))
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
517
351
0cc031745884 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
518 yield kind, data, pos
0cc031745884 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
519
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
520 def generate(self, *args, **kwargs):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
521 """Apply the template to the given context data.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
522
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
523 Any keyword arguments are made available to the template as context
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
524 data.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
525
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
526 Only one positional argument is accepted: if it is provided, it must be
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
527 an instance of the `Context` class, and keyword arguments are ignored.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
528 This calling style is used for internal processing.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
529
427
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
530 :return: a markup event stream representing the result of applying
55c574767df2 More API documentation.
cmlenz
parents: 425
diff changeset
531 the template to the context data.
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
532 """
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
533 vars = {}
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
534 if args:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
535 assert len(args) == 1
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
536 ctxt = args[0]
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
537 if ctxt is None:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
538 ctxt = Context(**kwargs)
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
539 else:
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
540 vars = kwargs
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
541 assert isinstance(ctxt, Context)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
542 else:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
543 ctxt = Context(**kwargs)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
544
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
545 stream = self.stream
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
546 for filter_ in self.filters:
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
547 stream = filter_(iter(stream), ctxt, **vars)
605
d0345c64da65 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
548 return Stream(stream, self.serializer)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
549
813
ae8727f7e1e1 Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
550 def _flatten(self, stream, ctxt, **vars):
636
699601cce3cc 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
551 number_conv = self._number_conv
843
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
552 stack = []
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
553 push = stack.append
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
554 pop = stack.pop
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
555 stream = iter(stream)
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
556
843
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
557 while 1:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
558 for kind, data, pos in stream:
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
559
843
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
560 if kind is START and data[1]:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
561 # Attributes may still contain expressions in start tags at
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
562 # this point, so do some evaluation
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
563 tag, attrs = data
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
564 new_attrs = []
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
565 for name, value in attrs:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
566 if type(value) is list: # this is an interpolated string
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
567 values = [event[1]
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
568 for event in self._flatten(value, ctxt, **vars)
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
569 if event[0] is TEXT and event[1] is not None
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
570 ]
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
571 if not values:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
572 continue
855
62c3ffae585d More 2to3 diff size reduction.
cmlenz
parents: 848
diff changeset
573 value = ''.join(values)
843
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
574 new_attrs.append((name, value))
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
575 yield kind, (tag, Attrs(new_attrs)), pos
813
ae8727f7e1e1 Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
576
843
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
577 elif kind is EXPR:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
578 result = _eval_expr(data, ctxt, vars)
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
579 if result is not None:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
580 # First check for a string, otherwise the iterable test
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
581 # below succeeds, and the string will be chopped up into
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
582 # individual characters
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
583 if isinstance(result, basestring):
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
584 yield TEXT, result, pos
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
585 elif isinstance(result, (int, float, long)):
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
586 yield TEXT, number_conv(result), pos
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
587 elif hasattr(result, '__iter__'):
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
588 push(stream)
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
589 stream = _ensure(result)
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
590 break
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
591 else:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
592 yield TEXT, unicode(result), pos
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
593
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
594 elif kind is SUB:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
595 # This event is a list of directives and a list of nested
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
596 # events to which those directives should be applied
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
597 push(stream)
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
598 stream = _apply_directives(data[1], data[0], ctxt, vars)
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
599 break
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
600
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
601 elif kind is EXEC:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
602 _exec_suite(data, ctxt, vars)
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
603
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
604 else:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
605 yield kind, data, pos
813
ae8727f7e1e1 Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
606
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
607 else:
843
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
608 if not stack:
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
609 break
d10e5bceaa1f Refactored the template flattening method to be less recursive.
cmlenz
parents: 827
diff changeset
610 stream = pop()
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
611
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
612 def _include(self, stream, ctxt, **vars):
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
613 """Internal stream filter that performs inclusion of external
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
614 template files.
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
615 """
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
616 from genshi.template.loader import TemplateNotFound
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
617
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
618 for event in stream:
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
619 if event[0] is INCLUDE:
610
5e358de79e4c * 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
620 href, cls, fallback = event[1]
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
621 if not isinstance(href, basestring):
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
622 parts = []
813
ae8727f7e1e1 Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
623 for subkind, subdata, subpos in self._flatten(href, ctxt,
ae8727f7e1e1 Merge the internal template filters `_eval` and `_exec` into the `_flatten` function for slightly better performance.
cmlenz
parents: 790
diff changeset
624 **vars):
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
625 if subkind is TEXT:
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
626 parts.append(subdata)
855
62c3ffae585d More 2to3 diff size reduction.
cmlenz
parents: 848
diff changeset
627 href = ''.join([x for x in parts if x is not None])
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
628 try:
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
629 tmpl = self.loader.load(href, relative_to=event[2][0],
610
5e358de79e4c * 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
630 cls=cls or self.__class__)
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
631 for event in tmpl.generate(ctxt, **vars):
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
632 yield event
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
633 except TemplateNotFound:
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
634 if fallback is None:
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
635 raise
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
636 for filter_ in self.filters:
700
08f22328303d Add option for unbuffered match template processing, which could cause excessive memory usage. Closes #190.
cmlenz
parents: 639
diff changeset
637 fallback = filter_(iter(fallback), ctxt, **vars)
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
638 for event in fallback:
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
639 yield event
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
640 else:
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
641 yield event
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
642
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
643
609
6d4877844e28 Add support for Python code blocks in text templates using the new syntax.
cmlenz
parents: 606
diff changeset
644 EXEC = Template.EXEC
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
645 EXPR = Template.EXPR
475
b373f80f7763 Added include directive for text templates (#115). Thanks to Alastair for the original patch.
cmlenz
parents: 442
diff changeset
646 INCLUDE = Template.INCLUDE
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
647 SUB = Template.SUB
Copyright (C) 2012-2017 Edgewall Software