| 1 | from trac.core import * |
|---|
| 2 | from tractags.api import DefaultTaggingSystem, ITaggingSystemProvider, TagEngine |
|---|
| 3 | from trac.wiki.api import IWikiChangeListener, IWikiSyntaxProvider |
|---|
| 4 | from trac.util import Markup |
|---|
| 5 | import re |
|---|
| 6 | |
|---|
| 7 | class WikiTaggingSystem(DefaultTaggingSystem): |
|---|
| 8 | """ Subclass of DefaultTaggingSystem that knows how to retrieve wiki page |
|---|
| 9 | titles. """ |
|---|
| 10 | def __init__(self, env): |
|---|
| 11 | DefaultTaggingSystem.__init__(self, env, 'wiki') |
|---|
| 12 | |
|---|
| 13 | def page_info(self, page): |
|---|
| 14 | from trac.wiki import model |
|---|
| 15 | """ Return tuple of (model.WikiPage, title) """ |
|---|
| 16 | page = model.WikiPage(self.env, page) |
|---|
| 17 | |
|---|
| 18 | title = '' |
|---|
| 19 | |
|---|
| 20 | if page.exists: |
|---|
| 21 | text = page.text |
|---|
| 22 | ret = re.search('=\s+([^=]*)=',text) |
|---|
| 23 | title = ret and ret.group(1) or '' |
|---|
| 24 | |
|---|
| 25 | return (page, title) |
|---|
| 26 | |
|---|
| 27 | def name_details(self, name): |
|---|
| 28 | """ Return a tuple of (href, wikilink, title). eg. ("/ticket/1", "#1", "Broken links") """ |
|---|
| 29 | page, title = self.page_info(name) |
|---|
| 30 | href = self.env.href.wiki(name) |
|---|
| 31 | defaults = DefaultTaggingSystem.name_details(self, name) |
|---|
| 32 | return defaults[0:2] + (title,) |
|---|
| 33 | |
|---|
| 34 | class WikiTags(Component): |
|---|
| 35 | """ Implement tags in the Wiki system, a tag:<tag> link resolver and |
|---|
| 36 | correctly deletes tags from Wiki pages that are removed. """ |
|---|
| 37 | |
|---|
| 38 | implements(ITaggingSystemProvider, IWikiChangeListener, IWikiSyntaxProvider) |
|---|
| 39 | |
|---|
| 40 | # ITaggingSystemProvider methods |
|---|
| 41 | def get_tagspaces_provided(self): |
|---|
| 42 | yield 'wiki' |
|---|
| 43 | |
|---|
| 44 | def get_tagging_system(self, tagspace): |
|---|
| 45 | return WikiTaggingSystem(self.env) |
|---|
| 46 | |
|---|
| 47 | # IWikiChangeListener methods |
|---|
| 48 | def wiki_page_added(self, page): |
|---|
| 49 | pass |
|---|
| 50 | |
|---|
| 51 | def wiki_page_changed(self, page, version, t, comment, author, ipnr): |
|---|
| 52 | pass |
|---|
| 53 | |
|---|
| 54 | def wiki_page_deleted(self, page): |
|---|
| 55 | # No point having tags on a non-existent page. |
|---|
| 56 | self.env.log.debug("Removing all tags from 'wiki:%s'" % page.name) |
|---|
| 57 | TagEngine(self.env).tagspace.wiki.remove_all_tags(None, page.name) |
|---|
| 58 | |
|---|
| 59 | def wiki_page_version_deleted(self, page): |
|---|
| 60 | # Wiki tags are not versioned. If they were, we'd delete them here. |
|---|
| 61 | pass |
|---|
| 62 | |
|---|
| 63 | # IWikiSyntaxProvider methods |
|---|
| 64 | def get_wiki_syntax(self): |
|---|
| 65 | return [] |
|---|
| 66 | |
|---|
| 67 | def get_link_resolvers(self): |
|---|
| 68 | yield ('tag', self._tag_formatter) |
|---|
| 69 | |
|---|
| 70 | def _tag_formatter(self, formatter, ns, target, label): |
|---|
| 71 | if '?' in target: |
|---|
| 72 | target, args = target.split('?')[0:2] |
|---|
| 73 | args = '?' + args |
|---|
| 74 | else: |
|---|
| 75 | args = '' |
|---|
| 76 | href, title = TagEngine(self.env).get_tag_link(target) |
|---|
| 77 | return Markup('<a href="%s%s" title="%s">%s</a>' % (href, args, title, label)) |
|---|
| 78 | |
|---|