Edgewall Software

Opened 15 years ago

Closed 15 years ago

Last modified 15 years ago

#5603 closed enhancement (fixed)

Allow macros to return Genshi streams

Reported by: Blackhex Owned by: Christian Boos
Priority: normal Milestone: 0.11
Component: wiki system Version: devel
Severity: normal Keywords: wiki macro genshi
Cc: blackhex@… Branch:
Release Notes:
API Changes:
Internal Changes:



using trunk version I did't find out a way how to render macro content in IWikiMacroProvider.expand_macro() using full XHTML Genshi template. Using this code snipplet:

  return Chrome(self.env).render_template(formatter.req, 'template.html',
                                          data, 'text/html', True)

returns full XHTML document (with <html>, <head> and <body> tags) which is present in returned page but browser didn't shows the macro content.

When using:

  return Chrome(self.env).render_template(formatter.req, 'template.html',
                                          data, 'text/html', False)

the stream object is returned according to web/chrome.py:

583:        if fragment:
584:            return stream

This results that macro returns no content. Printing result of that content do debug log return full XHTML document too.

Attachments (1)

discussion.tar.gz (19.8 KB ) - added by Blackhex 15 years ago.
DiscussionPlugin for Trac 0.11

Download all attachments as: .zip

Change History (13)

comment:1 by Noah Kantrowitz, 15 years ago

Milestone: 0.11
Summary: Unable to render wiki macro using Genshi template.Allow macros to return Genshi streams
Type: defectenhancement

Refiling this as an enhancement. Seems like a logical feature for us to have, not sure how to do it cleanly though.

comment:2 by Christian Boos, 15 years ago

Status: newassigned

Can you please try this?

Index: formatter.py
--- formatter.py	(revision 5756)
+++ formatter.py	(working copy)
@@ -24,6 +24,7 @@
 from StringIO import StringIO
+from genshi.core import Stream
 from genshi.builder import tag
 from trac.context import Context
@@ -95,7 +96,6 @@
     def _html_processor(self, text):
         if WikiSystem(self.env).render_unsafe_content:
             return Markup(text)
-        from genshi import Stream
         from genshi.input import HTMLParser, ParseError
         from genshi.filters import HTMLSanitizer
@@ -725,7 +725,7 @@
         """Replace one match with its corresponding expansion"""
         replacement = self.handle_match(fullmatch)
         if replacement:
-            if isinstance(replacement, Element):
+            if isinstance(replacement, (Element, Stream)):
                 return replacement.generate().render('xhtml', encoding=None,
             return to_unicode(replacement)

comment:3 by Blackhex, 15 years ago

I've checked twice but does the same for me.

comment:4 by Christian Boos, 15 years ago

Yes, sorry, it was a quick untested attempt… I'm testing a fixed fix now ;-)

comment:5 by Christian Boos, 15 years ago

Resolution: fixed
Status: assignedclosed

Should be OK with r5757.

comment:6 by Blackhex, 15 years ago

What should it do now? I'm experiencing still same behavior using mentioned macro code.

comment:7 by Christian Boos, 15 years ago

Try this simple single file plugin:

from trac.wiki.macros import WikiMacroBase
from genshi.template import MarkupTemplate
#from genshi.builder import tag

class TestStreamMacro(WikiMacroBase):
    """Try out with: [[TestStream(xxx)]] in your wiki text."""

    def render_macro(self, formatter, name, args):
        # return tag.b('Hello World, args = ', tag.em(unicode(args)))
        tmpl = MarkupTemplate("""<b>Hello World!!! args=<em>$args</em></b>""")
        return tmpl.generate(args=args)

Doesn't that work for you now with r5757?

In your case, as you're using Chrome.render_template, don't forget to set the fragment argument to True.

comment:8 by Blackhex, 15 years ago

This one works, but it is not exactly my case. I'm attaching DiscussionPlugin partially ported to 0.11. If you want to try it just create a new topic with name "WikiStart" and put at WikiStart wiki page macro ViewTopic.

by Blackhex, 15 years ago

Attachment: discussion.tar.gz added

DiscussionPlugin for Trac 0.11

comment:9 by Blackhex, 15 years ago

Ooops: [[ViewTopic]]

comment:10 by Christian Boos, 15 years ago

You consumed the stream when dumping it for debug ;-)

  • wiki.py

    old new  
    7474            # Return rendered template.
    7575            content = Chrome(self.env).render_template(formatter.req, template,
    7676              data, 'text/html', True)
    77             self.log.debug(content)
    7877            return content
    7978        else:
    8079            raise TracError('Not implemented macro %s' % (name))

comment:11 by Blackhex, 15 years ago

Who would imagine that :-). But unfortunatelly there is an another problem. Is it possible that lists in data dictionary are threaten differently by wiki formatter than by IRequestHandler one? Here is weird behavior I'm experiencing:

The same template in DisucssionCore (IRequestHandler) works just fine but in DiscussionWiki (IWikiMacroProvider) it returns

Error: Macro ViewTopic(None) failed
len() of unsized object

Data passed to template are:

 {'discussion': {'topic': {'body': <Markup u'<p>\nEnter your message here...
\n</p>\n'>, 'forum': 1, 'author': <Markup u'Blackhex'>, 'time': u'27.06.2007
16:06:05', 'id': 3, 'subject': <Markup u'<a class="wiki"
href="/Test-0.11/wiki/WikiStart">WikiStart</a>'>}, 'group': None, 'forum': {'group':
1, 'name': <Markup u'<a class="wiki" href="/Test-0.11/wiki/WikiStart">WikiStart</a>'>,
'description': <Markup u'<a
class="wiki" href="/Test-0.11/wiki/WikiStart">WikiStart</a>'>, 'moderators':
[u'Blackhex'], 'time': u'25.06.2007 19:43:35', 'id': 1, 'subject': <Markup u'<a
class="wiki" href="/Test-0.11/wiki/WikiStart">WikiStart</a>'>}, 'time': u'27.06.2007
16:16:09', 'messages': [{'replyto': -1, 'body': <Markup
u'<p>\ngdfgdfgd\n</p>\n'>, 'author': <Markup u'Blackhex'>, 'id': 1, 'time':
u'27.06.2007 16:08:44'}], 'is_moderator' :
True, 'mode': 'wiki-message-list', 'authname': u'Blackhex', 'message':
None, 'display': u'flat-desc'}}

Note that data["discussion"]["messages"] is list with one item (a dictionary). Template line throwing an error is:

<div py:if="len(discussion.messages) or str(req.args.message) == '-1'"
 class="replies ${discussion.topic.new and 'new' or None}">

And finally the weird thing here is what is returned after template rendeding when ${discussion.messages} is used:

<function <lambda> at 0x2aaaad879410>

which I understand that Chrome.render_template makes a function object from that list. Why is this possible just only in expand_macro context?

comment:12 by Blackhex, 15 years ago

Ooops, my fault aggain, this just caused shapped template function arguments :-), Sorry and thank you.

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain Christian Boos.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Christian Boos 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.