Edgewall Software

Changes between Version 2 and Version 3 of GenshiRecipes/Localization


Ignore:
Timestamp:
Nov 9, 2006, 2:39:43 PM (17 years ago)
Author:
David Fraser <davidf@…>
Comment:

added derived localization template classes

Legend:

Unmodified
Added
Removed
Modified
  • GenshiRecipes/Localization

    v2 v3  
    268268
    269269}}}
     270
     271== Page Generation with Localized Templates ==
     272
     273In order to use the modified Template stream, we basically need to do some processing before the normal Genshi mechanism takes over...
     274
     275This class allows inclusion of "prefilters" that operate before the Template stream's standard filters (you can't just use a filter to do this, it causes problems):
     276{{{
     277#!python
     278class PrefilterMarkupTemplate(genshi.template.MarkupTemplate):
     279    """Derived markup template that can receive prefilters in its generate method"""
     280    # TODO: try and upstream this into genshi
     281    def generate(self, prefilters, *args, **kwargs):
     282        """Apply the template to the given context data.
     283       
     284        Any keyword arguments are made available to the template as context
     285        data.
     286       
     287        Only one positional argument is accepted: if it is provided, it must be
     288        an instance of the `Context` class, and keyword arguments are ignored.
     289        This calling style is used for internal processing.
     290       
     291        @return: a markup event stream representing the result of applying
     292            the template to the context data.
     293        """
     294        if args:
     295            assert len(args) == 1
     296            ctxt = args[0]
     297            if ctxt is None:
     298                ctxt = genshi.template.Context(**kwargs)
     299            assert isinstance(ctxt, genshi.template.Context)
     300        else:
     301            ctxt = genshi.template.Context(**kwargs)
     302
     303        stream = self.stream
     304        for prefilter in prefilters:
     305            # TODO: add support for context in prefilters
     306            stream = prefilter(iter(stream))
     307        for filter_ in self.filters:
     308            stream = filter_(iter(stream), ctxt)
     309        return genshi.core.Stream(stream)
     310}}
     311
     312This derived class then allows you to call the above localization function as a prefilter on templates. It uses the domain_name as a parameter (this corresponds to which PO/MO file to use for translation, but assumes you can construct or retrieve a translation object for the current user on the fly using a get_translation function (not described here):
     313{{
     314#!python
     315class LocalizeMarkupTemplate(PrefilterMarkupTemplate):
     316    """Derived markup template that can handle localizing before stream generation"""
     317    def __init__(self, source, basedir=None, filename=None, loader=None,
     318                 encoding=None, domain_name=None):
     319        """Initialize a template from either a string or a file-like object."""
     320        super(LocalizeMarkupTemplate, self).__init__(source, basedir=basedir, filename=filename, loader=loader, encoding=encoding)
     321        self.domain_name = domain_name
     322
     323    def localize_prefilter(self, stream):
     324        """prefilter for localizing..."""
     325        translation = get_translation(self.domain_name)
     326        stream = genshi.core.Stream(stream)
     327        localized_stream = genshigettext.localize_template(stream, translation.ugettext)
     328        return list(iter(localized_stream))
     329
     330    # TODO: try and persuade genshi to accept a stream directly here instead of using self.stream - or accept prefilters
     331    # then we won't use such fragile copied code...
     332    def generate(self, prefilters, *args, **kwargs):
     333        """Apply the template to the given context data.
     334       
     335        Any keyword arguments are made available to the template as context
     336        data.
     337       
     338        Only one positional argument is accepted: if it is provided, it must be
     339        an instance of the `Context` class, and keyword arguments are ignored.
     340        This calling style is used for internal processing.
     341       
     342        @return: a markup event stream representing the result of applying
     343            the template to the context data.
     344        """
     345        return super(LocalizeMarkupTemplate, self).generate(prefilters + [self.localize_prefilter], *args, **kwargs)
     346}}