Edgewall Software

Changes between Version 22 and Version 23 of GenshiTutorial


Ignore:
Timestamp:
Aug 29, 2007, 10:18:09 PM (17 years ago)
Author:
cmlenz
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GenshiTutorial

    v22 v23  
    516516from genshi.core import Stream
    517517from genshi.output import encode, get_serializer
    518 from genshi.template import TemplateLoader
     518from genshi.template import Context, TemplateLoader
    519519
    520520loader = TemplateLoader(
     
    523523)
    524524
    525 def output(filename, method=None, encoding='utf-8', **options):
     525def output(filename, method='html', encoding='utf-8', **options):
    526526    """Decorator for exposed methods to specify what template the should use
    527527    for rendering, and which serialization method and options should be
     
    531531        def wrapper(*args, **kwargs):
    532532            cherrypy.thread_data.template = loader.load(filename)
     533            if method == 'html':
     534                options.setdefault('doctype', 'html')
    533535            serializer = get_serializer(method, **options)
    534536            stream = func(*args, **kwargs)
     
    550552    else:
    551553        template = cherrypy.thread_data.template
    552     return template.generate(**kwargs)
     554    ctxt = Context(url=cherrypy.url)
     555    ctxt.push(kwargs)
     556    return template.generate(ctxt)
    553557}}}
    554558
     
    570574
    571575    @cherrypy.expose
    572     @template.output('index.html', method='html', doctype='html')
     576    @template.output('index.html')
    573577    def index(self):
    574578        return template.render(submissions=self.data)
    575579
    576580    @cherrypy.expose
    577     @template.output('submit.html', method='html', doctype='html')
     581    @template.output('submit.html')
    578582    def submit(self, cancel=False, **data):
    579583        if cherrypy.request.method == 'POST':
     
    594598}}}
    595599
    596 There's still some duplication of code in the decorators: the need to specify the serialization method and the doctype over and over again is suboptimal, and should ideally be made configurable in a central location.
     600As you can see here, the code is now less repetitive: there's a simple decorator to define which template should be used, and the `render()` produces the template out stream which can then be further processed if necessary.
    597601
    598602== Adding a Layout Template ==
     
    600604But there's also duplication in the template files themselves: each template has to redefine the complete header and footer, and any other “decoration” markup that we may want to apply to the complete site. Now, we could simply put those commonly used markup snippets into separate HTML files and [wiki:Documentation/xml-templates.html#includes include] them in the templates where they are needed. But Genshi provides a more elegant way to apply a common structure to different templates: [wiki:Documentation/xml-templates.html#match-templates match templates].
    601605
    602 Most template languages provide an inheritance mechanism to allow different templates to share some kind of common structure, such as a common header, navigation, and footer. Using this mechanism, you create a “master template” in which you declare slots that “derived templates” can fill in. The problem with this approach is that it is fairly rigid: the master needs to now which content the templates will produce, and what kind of slots need to be provided for them to stuff their content in. And derived templates need to know exactly how the master  Also, a derived template is itself not a well-formed or even valid HTML file, and can not be easily previewed or edited in a WYSIWYG authoring tool.
     606Most template languages provide an inheritance mechanism to allow different templates to share some kind of common structure, such as a common header, navigation, and footer. Using this mechanism, you create a “master template” in which you declare slots that “derived templates” can fill in. The problem with this approach is that it is fairly rigid: the master needs to now which content the templates will produce, and what kind of slots need to be provided for them to stuff their content in. Also, a derived template is itself not a valid or even well-formed HTML file, and can not be easily previewed or edited in a WYSIWYG authoring tool.
    603607
    604608Match templates in Genshi turn this up side down. They are conceptually similar to running an XSLT transformation over your template output: you create rules that match elements in the template output stream based on XPath patterns. Whenever there is a match, the matched content is replaced by what the match template produces. This sounds complicated in theory, but is fairly intuitive in practice, so let's look at a concrete example.