I've made a start at porting Tags to 0.11. It's pretty much feature
equivalent to the 0.10 version as it stands.
To try it out:
easy_install http://trac-hacks.org/svn/tagsplugin/trunk/
It requires Genshi trunk, so it'll probably pull that down as well.
Works for me against current Trac trunk, r5903. Please test and
respond with any issues.
Alec
--
Evolution: Taking care of those too stupid to take care of themselves.
[trac]
default_handler = TagsWikiModule
Remove this line completely if it exists.
Hi Alec -- thanks very much for this! I just updated to the trac trunk and
installed tags as above. Basic things work out of the box.
I got an error with the following tags URL:
http://www/trac/tags/foobar
NameError: global name 'escape' is not defined
I fixed that by importing 'escape' from trac.util.html in web_ui.py.
But then I get another error later on while processing the same URL:
AttributeError: 'NoneType' object has no attribute 'perm'
This is deep in the formatter code. Apparently at tractags/macros.py line
215, there's this code:
htitle = wiki_to_oneliner(title, self.env)
which ends up calling back like this:
"...Trac-0.11dev_r5912-py2.4.egg/trac/wiki/formatter.py":1052
"...Trac-0.11dev_r5912-py2.4.egg/trac/wiki/formatter.py": 881 (format)
... then into python's SRE module, and then back out:
"...Trac-0.11dev_r5912-py2.4.egg/trac/wiki/formatter.py": 735 (replace)
"...Trac-0.11dev_r5912-py2.4.egg/trac/wiki/formatter.py":728 (handle_match)
"...Trac-0.11dev_r5912-py2.4.egg/trac/wiki/api.py": 309 (wikipagename_link)
"...Trac-0.11dev_r5912-py2.4.egg/trac/wiki/api.py":345 (format_link)
and that last function wants a Request object from the formatter, which it
turns out is None:
req = formatter.context.req
context = Context(self.env, req)('wiki', id=page, version=version)
if 'WIKI_VIEW' not in req.perm(context):
So I fixed that by passing the req object into wiki_to_oneliner in both places
in macros.py. Then I'd get the same error when I explicitly call
[[ListTagged('foo')]] in a wiki page:
Error: Macro ListTagged('releaseprocedure') failed
'NoneType' object has no attribute 'perm'
so I just looked around and passed the req object into a few more places. Now
everything seems to be working for me! I'm extremely happy to be able to run
0.11 now!!!
Patch attached. I'll submit it to trac-hacks as well.
-- Gary Oberbrunner
Can't answer the first two, but I think I can speak authoritatively to
the third.
The port will now allow the blog plugin to be ported to 0.11. The port
shouldn't be very hard, though it will include rewriting a couple
templates and probably reworking things to use the request filters.
You could try the blog plugin with the 0.11 version, but I doubt it will
work.
-John
Explicitly setting it to WikiModule is also fine.
> 2) - I have multiple instances of Trac living on the same machine. None of
> them are using Tags currently as they are both built off of 0.11 - if the
> default_handler line isn't present, is your install just making tags a core
> feature or will it show up as a plugin that can be activated/deactivated?
It is still a plugin, it's just using an alternate mechanism to add the tags
features to the Wiki edit and view pages. It can still be enabled and disabled
in the standard fashion:
[component]
tractags.* = enabled
> 3) - Also curious as to whether or not you know how this port affects the
> Blog plugin?
I'm not 100% sure, but I believe blog needs to be ported to 0.11 as well. It
might work though, you never know :)
> Index: tractags/api.py
> ===================================================================
> --- tractags/api.py (revision 2566)
> +++ tractags/api.py (working copy)
> @@ -108,7 +108,7 @@
> """ Remove all tags from a name in a tagspace. """
> self.remove_tags(req, name, self.get_name_tags(name))
>
> - def name_details(self, name):
> + def name_details(self, req, name):
> """ Return a tuple of (href, htmllink, title). eg.
> ("/ticket/1", "<a href="/ticket/1">#1</a>", "Broken links") """
> raise NotImplementedError
> @@ -174,10 +174,10 @@
> cursor.execute('DELETE FROM tags WHERE tagspace=%s AND name=%s', (self.tagspace, name))
> db.commit()
>
> - def name_details(self, name):
> + def name_details(self, req, name):
> from trac.wiki.formatter import wiki_to_oneliner
> return (getattr(self.env.href, self.tagspace),
> - wiki_to_oneliner('[%s:"%s" %s]' % (self.tagspace, name, name), self.env), '')
> + wiki_to_oneliner('[%s:"%s" %s]' % (self.tagspace, name, name), self.env, req=req), '')
>
> class TagspaceProxy:
> """ A convenience for performing operations on a specific tagspace,
> @@ -356,10 +356,10 @@
> return result
>
>
> - def name_details(self, tagspace, name):
> + def name_details(self, tagspace, req, name):
> """ Return a tuple of (href, htmllink, title). eg.
> ("/ticket/1", "<a href="/ticket/1">#1</a>", "Broken links") """
> - return self._get_tagsystem(tagspace).name_details(name)
> + return self._get_tagsystem(tagspace).name_details(req, name)
>
> # ITaggingSystemProvider methods
> def get_tagspaces_provided(self):
> Index: tractags/web_ui.py
> ===================================================================
> --- tractags/web_ui.py (revision 2566)
> +++ tractags/web_ui.py (working copy)
> @@ -6,7 +6,7 @@
> from trac.web.chrome import ITemplateProvider, INavigationContributor, add_stylesheet
> from trac.web.api import ITemplateStreamFilter
> from trac.wiki.api import IWikiPageManipulator
> -from trac.util.html import Markup
> +from trac.util.html import Markup, escape
> from trac.util.compat import set
> from trac.wiki.web_ui import WikiModule
> from trac.wiki.formatter import wiki_to_oneliner
> Index: tractags/ticket.py
> ===================================================================
> --- tractags/ticket.py (revision 2566)
> +++ tractags/ticket.py (working copy)
> @@ -82,12 +82,12 @@
> ticket['keywords'] = ''
> ticket.save_changes(req.authname, None)
>
> - def name_details(self, name):
> + def name_details(self, req, name):
> ticket = model.Ticket(self.env, name)
> href = self.env.href.ticket(name)
> from trac.wiki.formatter import wiki_to_oneliner
> summary = ticket['summary'] or u''
> - return (href, wiki_to_oneliner('#%s' % name, self.env),
> + return (href, wiki_to_oneliner('#%s' % name, self.env, req=req),
> ticket.exists and summary)
>
> class TicketTags(Component):
> Index: tractags/wiki.py
> ===================================================================
> --- tractags/wiki.py (revision 2566)
> +++ tractags/wiki.py (working copy)
> @@ -25,11 +25,11 @@
>
> return (page, title)
>
> - def name_details(self, name):
> + def name_details(self, req, name):
> """ Return a tuple of (href, wikilink, title). eg. ("/ticket/1", "#1", "Broken links") """
> page, title = self.page_info(name)
> href = self.env.href.wiki(name)
> - defaults = DefaultTaggingSystem.name_details(self, name)
> + defaults = DefaultTaggingSystem.name_details(self, req, name)
> return defaults[0:2] + (title,)
>
> class WikiTags(Component):
> Index: tractags/macros.py
> ===================================================================
> --- tractags/macros.py (revision 2566)
> +++ tractags/macros.py (working copy)
> @@ -18,7 +18,8 @@
> titles = {}
> tagspace = TagEngine(self.env).tagspace.wiki
> for pagename in pages:
> - href, link, title = tagspace.name_details(pagename)
> + # XXX: have to pass None for req here; not likely to work!
> + href, link, title = tagspace.name_details(None, pagename)
> titles[pagename] = title
> return titles
>
> @@ -211,8 +212,8 @@
> if tagspace == 'wiki' and unicode(name).startswith('tags/'): continue
> tags = sorted(tags)
> taginfo = self._tag_details(taginfo, tags)
> - href, link, title = engine.name_details(tagspace, name)
> - htitle = wiki_to_oneliner(title, self.env)
> + href, link, title = engine.name_details(tagspace, req, name)
> + htitle = wiki_to_oneliner(title, self.env, req=req)
> name_tags = ['<a href="%s" title="%s">%s</a>'
> % (taginfo[tag][0], taginfo[tag][1], tag)
> for tag in tags]
> @@ -259,7 +260,7 @@
> tag_details = {}
> for tag, names in sorted(engine.get_tags(tagspaces=tagspaces, detailed=True).iteritems()):
> href, title = engine.get_tag_link(tag)
> - htitle = wiki_to_oneliner(title, self.env)
> + htitle = wiki_to_oneliner(title, self.env, req=req)
> out.write('<li><a href="%s" title="%s">%s</a> %s <span class="tagcount">(%i)</span>' % (href, title, tag, htitle, len(names)))
> if showpages == 'true':
> out.write('\n')
trac-admin /path/to/myproject upgrade
I got a failure with the message below:
Command failed: Parent module 'tractags' not loaded
Any patches or workarounds out there?
On Aug 15, 6:50 am, "Alec Thomas" <a...@swapoff.org> wrote:
> I'v"e updated tags with a slightly modified version of Gary's patch.
[components]
tractags.* = enabled
in your trac.ini, and that you *do not* have "default_handler =
TagsWikiModule" anywhere.
Also, ensure that you've completely removed any old versions of tags.
FYI this same combination of Trac 0.11 and Tags works for me. I also
didn't get prompted for any upgrades....or are you saying that you
upgraded trunk, then installed tags?
On Aug 24, 6:31 am, "Alec Thomas" <a...@swapoff.org> wrote:
> That's a new one. Make sure you have:
>
> [components]
> tractags.* = enabled
>
> in your trac.ini, and that you *do not* have "default_handler =
> TagsWikiModule" anywhere.
>
> Also, ensure that you've completely removed any old versions of tags.
>
> FYI this same combination of Trac 0.11 and Tags works for me. I also
> didn't get prompted for any upgrades....or are you saying that you
> upgraded trunk, then installed tags?
>