#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: |
Description
Hello,
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)
Change History (13)
comment:1 by , 17 years ago
Milestone: | → 0.11 |
---|---|
Summary: | Unable to render wiki macro using Genshi template. → Allow macros to return Genshi streams |
Type: | defect → enhancement |
comment:2 by , 17 years ago
Status: | new → assigned |
---|
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 try: @@ -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, strip_whitespace=False) return to_unicode(replacement)
comment:4 by , 17 years ago
Yes, sorry, it was a quick untested attempt… I'm testing a fixed fix now ;-)
comment:6 by , 17 years ago
What should it do now? I'm experiencing still same behavior using mentioned macro code.
comment:7 by , 17 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 , 17 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.
comment:10 by , 17 years ago
You consumed the stream when dumping it for debug ;-)
-
wiki.py
old new 74 74 # Return rendered template. 75 75 content = Chrome(self.env).render_template(formatter.req, template, 76 76 data, 'text/html', True) 77 self.log.debug(content)78 77 return content 79 78 else: 80 79 raise TracError('Not implemented macro %s' % (name))
comment:11 by , 17 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 , 17 years ago
Ooops, my fault aggain, this just caused shapped template function arguments :-), Sorry and thank you.
Refiling this as an enhancement. Seems like a logical feature for us to have, not sure how to do it cleanly though.