Edgewall Software
Modify

Opened 6 months ago

Closed 6 months ago

#13622 closed defect (worksforme)

No replacement for ITemplateStreamFilter

Reported by: Dirk Stöcker Owned by:
Priority: normal Milestone:
Component: general Version: 1.6
Severity: normal Keywords:
Cc: Branch:
Release Notes:
API Changes:
Internal Changes:

Description

Trac 1.6 dropped the ITemplateStreamFilter from Genshi completely and I'm unable to find ANY replacement to use in spamfilter for the trapfield strategy.

That strategy is one of the major contributors to reject spam.

Please create a new method to access the final templated string

  • a callback for template conversion
  • an Extension which hooks before the the call to req.send()
  • an extension to Request to hook into _send()
  • a possible to extend/override the Request class (probably the best solution with most options for different use)

If there is something I overlooked please tell me. I didn't find anything relevant.

Attachments (0)

Change History (2)

comment:1 by Dirk Stöcker, 6 months ago

A possible solution could look like this:

  • web/chrome.py

    old new  
    120120        files.
    121121        """
    122122
     123class ITemplateModifier(Interface):
     124    """Extension point interface for components that modify Jinja2 templates.
     125    """
     126
     127    def pre_modify_template(req, template, data, metadata):
     128        """Return True or False in case post function should be called or not
     129
     130        Arguments are the request, the template, data for the template and
     131        the metadata.
     132        """
     133
     134    def post_modify_template(req, template, data, stream):
     135        """Returns the stream again or a replacement for it
     136
     137        Arguments are the request, the template and the data for it as
     138        well as the stream of the generated template.
     139
     140        Function is only called when pre function returned True
     141        """
    123142
    124143def accesskey(req, key):
    125144    """Helper function for creating accesskey HTML attribute according
     
    419438
    420439    navigation_contributors = ExtensionPoint(INavigationContributor)
    421440    template_providers = ExtensionPoint(ITemplateProvider)
     441    template_modifiers = ExtensionPoint(ITemplateModifier)
    422442
    423443    shared_templates_dir = PathOption('inherit', 'templates_dir', '',
    424444        """Path to the //shared templates directory//.
     
    13801400
    13811401        template, data = self.prepare_template(req, filename, data, text,
    13821402                                               domain)
     1403        mods = []
     1404        for mod in self.template_modifiers:
     1405            if mod.pre_modify_template(req, template, data, metadata):
     1406                mods.append(mod)
    13831407
    13841408        # TODO (1.5.1) - have another try at simplifying all this...
    13851409        # With Jinja2, it's certainly possible to do things
     
    13991423
    14001424        if fragment or text:
    14011425            if iterable:
    1402                 return self.generate_template_stream(template, data, text,
     1426                return self.generate_template_stream(req, mods, template, data, text,
    14031427                                                     iterable)
    14041428            else:
    14051429                s = self.render_template_string(template, data, text)
     
    14081432        data['chrome']['content_type'] = content_type
    14091433
    14101434        try:
    1411             return self.generate_template_stream(template, data, text,
     1435            return self.generate_template_stream(req, mods, template, data, text,
    14121436                                                 iterable)
    14131437        except Exception:
    14141438            # restore what may be needed by the error template
     
    14371461        """
    14381462        template, data = self.prepare_template(req, filename, data, text,
    14391463                                               domain)
    1440         return self.generate_template_stream(template, data, text)
     1464        return self.generate_template_stream(req, [], template, data, text)
    14411465
    14421466    def render_fragment(self, req, filename, data, text=False, domain=None):
    14431467        """Produces a string from given template *filename* and input *data*,
     
    14891513        data = self.populate_data(req, data)
    14901514        return template, data
    14911515
    1492     def generate_template_stream(self, template, data, text=False,
     1516    def generate_template_stream(self, req, mods, template, data, text=False,
    14931517                                 iterable=None):
    14941518        """Returns the rendered template in a form that can be "sent".
    14951519
     
    15191543        """
    15201544        stream = template.stream(data)
    15211545        stream.enable_buffering(75)  # buffer_size
     1546        for mod in mods:
     1547            stream = mod.post_modify_template(req, template, data, stream)
    15221548        if iterable or iterable is None and self.use_chunked_encoding:
    15231549            return self.iterable_content(stream, text)
    15241550        else:

comment:2 by Dirk Stöcker, 6 months ago

Resolution: worksforme
Status: newclosed

In #13321 there was another solution which works.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The ticket will remain with no owner.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from (none) to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.