Changeset 726
- Timestamp:
- Aug 28, 2007, 1:20:47 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
-
ChangeLog (modified) (1 diff)
-
doc/xml-templates.txt (modified) (2 diffs)
-
genshi/template/base.py (modified) (10 diffs)
-
genshi/template/markup.py (modified) (4 diffs)
-
genshi/template/tests/markup.py (modified) (1 diff)
-
genshi/template/tests/text.py (modified) (3 diffs)
-
genshi/template/text.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ChangeLog
r725 r726 30 30 necessary to explicitly specify the "text" method to the `render()` or 31 31 `serialize()` method of the generated markup stream. 32 * XInclude elements in markup templates now support the `parse` attribute; when 33 set to "xml" (the default), the include is processed as before, but when set 34 to "text", the included template is parsed as a text template using the new 35 syntax (ticket #101). 36 * If an include is found when parsing a template, but no template loader has 37 been specified, a `TemplateSyntaxError` is raised. 32 38 33 39 -
trunk/doc/xml-templates.txt
r718 r726 602 602 .. _`xinclude specification`: http://www.w3.org/TR/xinclude/ 603 603 604 605 Dynamic Includes 606 ================ 607 604 608 Incudes in Genshi are fully dynamic: Just like normal attributes, the `href` 605 609 attribute accepts expressions, and directives_ can be used on the … … 613 617 614 618 619 Including Text Templates 620 ======================== 621 622 The ``parse`` attribute of the ``<xi:include>`` element can be used to specify 623 whether the included template is an XML template or a text template (using the 624 new syntax added in Genshi 0.5): 625 626 .. code-block:: genshi 627 628 <xi:include href="myscript.js" parse="text" /> 629 630 This example would load the ``myscript.js`` file as a ``NewTextTemplate``. See 631 `text templates`_ for details on the syntax of text templates. 632 633 .. _`text templates`: text-templates.html 634 635 615 636 .. _comments: 616 637 -
trunk/genshi/template/base.py
r725 r726 40 40 """Base exception class for errors related to template processing.""" 41 41 42 def __init__(self, message, filename= '<string>', lineno=-1, offset=-1):42 def __init__(self, message, filename=None, lineno=-1, offset=-1): 43 43 """Create the exception. 44 44 … … 49 49 :param offset: the column number at which the error occurred 50 50 """ 51 if filename is None: 52 filename = '<string>' 51 53 self.msg = message #: the error message string 52 54 if filename != '<string>' or lineno >= 0: … … 63 65 """ 64 66 65 def __init__(self, message, filename= '<string>', lineno=-1, offset=-1):67 def __init__(self, message, filename=None, lineno=-1, offset=-1): 66 68 """Create the exception 67 69 … … 85 87 """ 86 88 87 def __init__(self, name, filename= '<string>', lineno=-1):89 def __init__(self, name, filename=None, lineno=-1): 88 90 """Create the exception 89 91 … … 334 336 self.allow_exec = allow_exec 335 337 338 self.filters = [self._flatten, self._eval, self._exec] 339 if loader: 340 self.filters.append(self._include) 341 336 342 if isinstance(source, basestring): 337 343 source = StringIO(source) … … 342 348 except ParseError, e: 343 349 raise TemplateSyntaxError(e.msg, self.filepath, e.lineno, e.offset) 344 self.filters = [self._flatten, self._eval, self._exec]345 if loader:346 self.filters.append(self._include)347 350 348 351 def __repr__(self): … … 387 390 else: 388 391 if kind is INCLUDE: 389 href, fallback = data392 href, cls, fallback = data 390 393 if isinstance(href, basestring) and \ 391 394 not getattr(self.loader, 'auto_reload', True): … … 395 398 try: 396 399 tmpl = self.loader.load(href, relative_to=pos[0], 397 cls= self.__class__)400 cls=cls or self.__class__) 398 401 for event in tmpl.stream: 399 402 yield event … … 514 517 for event in stream: 515 518 if event[0] is INCLUDE: 516 href, fallback = event[1]519 href, cls, fallback = event[1] 517 520 if not isinstance(href, basestring): 518 521 parts = [] … … 523 526 try: 524 527 tmpl = self.loader.load(href, relative_to=event[2][0], 525 cls= self.__class__)528 cls=cls or self.__class__) 526 529 for event in tmpl.generate(ctxt): 527 530 yield event -
trunk/genshi/template/markup.py
r725 r726 25 25 from genshi.template.interpolation import interpolate 26 26 from genshi.template.directives import * 27 from genshi.template.text import NewTextTemplate 27 28 28 29 __all__ = ['MarkupTemplate'] … … 142 143 143 144 if tag in self.XINCLUDE_NAMESPACE: 145 if self._include not in self.filters: 146 raise TemplateSyntaxError('Include found but no ' 147 'template loader specified', 148 self.filepath, *pos[1:]) 144 149 if tag.localname == 'include': 145 150 include_href = new_attrs.get('href') … … 148 153 'attribute "href"', 149 154 self.filepath, *pos[1:]) 150 includes.append( include_href)155 includes.append((include_href, new_attrs.get('parse'))) 151 156 streams.append([]) 152 157 elif tag.localname == 'fallback': … … 171 176 # and the fallback element 172 177 stream = streams[-1] 173 stream.append((INCLUDE, (includes.pop(), fallback), pos)) 178 href, parse = includes.pop() 179 try: 180 cls = { 181 'xml': MarkupTemplate, 182 'text': NewTextTemplate 183 }[parse or 'xml'] 184 except KeyError: 185 raise TemplateSyntaxError('Invalid value for "parse" ' 186 'attribute of include', 187 self.filepath, *pos[1:]) 188 stream.append((INCLUDE, (href, cls, fallback), pos)) 174 189 else: 175 190 stream.append((kind, data, pos)) -
trunk/genshi/template/tests/markup.py
r704 r726 245 245 </Test>""", str(tmpl.generate())) 246 246 247 def test_include_without_loader(self): 248 xml = """<html xmlns:xi="http://www.w3.org/2001/XInclude"> 249 <xi:include href="oops.html" /> 250 </html>""" 251 self.assertRaises(TemplateSyntaxError, MarkupTemplate, xml) 252 247 253 def test_include_in_loop(self): 248 254 dirname = tempfile.mkdtemp(suffix='genshi_test') -
trunk/genshi/template/tests/text.py
r725 r726 18 18 import unittest 19 19 20 from genshi.template.base import TemplateSyntaxError 20 21 from genshi.template.loader import TemplateLoader 21 22 from genshi.template.text import OldTextTemplate, NewTextTemplate … … 111 112 ----- Included data above this line -----""", 112 113 tmpl.generate().render()) 114 115 def test_include_without_loader(self): 116 text = '#include "oops.html"' 117 self.assertRaises(TemplateSyntaxError, OldTextTemplate, text) 113 118 114 119 … … 232 237 ----- Included data above this line -----""", tmpl.generate().render()) 233 238 239 def test_include_without_loader(self): 240 text = '{% include "oops.html" %}' 241 self.assertRaises(TemplateSyntaxError, NewTextTemplate, text) 242 234 243 235 244 def suite(): -
trunk/genshi/template/text.py
r725 r726 29 29 import re 30 30 31 from genshi.template.base import BadDirectiveError, Template, EXEC, INCLUDE, SUB 31 from genshi.template.base import BadDirectiveError, Template, \ 32 TemplateSyntaxError, EXEC, INCLUDE, SUB 32 33 from genshi.template.eval import Suite 33 34 from genshi.template.directives import * … … 187 188 188 189 if command == 'include': 190 if self._include not in self.filters: 191 raise TemplateSyntaxError('Include found but no template ' 192 'loader specified', self.filepath, 193 lineno) 189 194 pos = (self.filename, lineno, 0) 190 stream.append((INCLUDE, (value.strip(), []), pos))195 stream.append((INCLUDE, (value.strip(), None, []), pos)) 191 196 192 197 elif command == 'python': … … 307 312 (self.filepath, lineno, 0))] 308 313 elif command == 'include': 314 if self._include not in self.filters: 315 raise TemplateSyntaxError('Include found but no template ' 316 'loader specified', self.filepath, 317 lineno) 309 318 pos = (self.filename, lineno, 0) 310 stream.append((INCLUDE, (value.strip(), []), pos))319 stream.append((INCLUDE, (value.strip(), None, []), pos)) 311 320 elif command != '#': 312 321 cls = self._dir_by_name.get(command)
Note: See TracChangeset
for help on using the changeset viewer.
