| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | |
|---|
| 3 | """ |
|---|
| 4 | 0.11dev rewrite of original ShowPath functionality. Replaces |
|---|
| 5 | the global "Start Page" link with a path of links for |
|---|
| 6 | hierarchical pages. |
|---|
| 7 | e.g., http://mytrac.com/wiki/ParentPage/ChildPage/GrandchildPage |
|---|
| 8 | ..would create a ShowPath of |
|---|
| 9 | Start Page / ParentPage / ChildPage / GrandchildPage |
|---|
| 10 | ..where all are links except for the current, GrandchildPage. |
|---|
| 11 | |
|---|
| 12 | - http://trac.edgewall.org/wiki/MacroBazaar#ShowPath |
|---|
| 13 | - http://trac-hacks.org/wiki/TracShowPathPatch |
|---|
| 14 | |
|---|
| 15 | Just drop in your trac/<projectname>/plugins dir. |
|---|
| 16 | |
|---|
| 17 | Supports one optional trac.ini setting, sep_character, which |
|---|
| 18 | specifies the character to use in the path display: |
|---|
| 19 | [showpath] |
|---|
| 20 | sep_character = » |
|---|
| 21 | The default is a forward slash (/); note that no matter what character |
|---|
| 22 | is specified, it will always be rendered with a single space on |
|---|
| 23 | either side. If you specify a string of more than one character, |
|---|
| 24 | only the first non-whitespace character will be used. |
|---|
| 25 | |
|---|
| 26 | 2007 Morris - gt4329b@pobox.com |
|---|
| 27 | rfmorris on irc://freenode/trac |
|---|
| 28 | |
|---|
| 29 | """ |
|---|
| 30 | |
|---|
| 31 | from pprint import pprint, pformat |
|---|
| 32 | |
|---|
| 33 | from trac.core import * |
|---|
| 34 | #from trac.ticket.query import TicketQueryMacro |
|---|
| 35 | #from trac.wiki.macros import WikiMacroBase |
|---|
| 36 | from trac.wiki.api import parse_args |
|---|
| 37 | from trac.web import IRequestHandler, IRequestFilter, ITemplateStreamFilter |
|---|
| 38 | |
|---|
| 39 | ## genshi imports (genshi.filters.Transformer requires Genshi 0.5+) |
|---|
| 40 | ## http://genshi.edgewall.org/ |
|---|
| 41 | from genshi.builder import tag |
|---|
| 42 | from genshi.filters import Transformer |
|---|
| 43 | from genshi.core import TEXT |
|---|
| 44 | from genshi.input import HTML |
|---|
| 45 | |
|---|
| 46 | _DEFAULT_SEP = '/' |
|---|
| 47 | |
|---|
| 48 | class ShowPath(Component): |
|---|
| 49 | implements(ITemplateStreamFilter) |
|---|
| 50 | |
|---|
| 51 | def __init__(self, *args, **kwargs): |
|---|
| 52 | Component.__init__(self, *args, **kwargs) |
|---|
| 53 | self.sep_character = self.config.get( |
|---|
| 54 | 'showpath', 'sep_character', _DEFAULT_SEP).strip() |
|---|
| 55 | # QA our possibly-user-supplied separator char |
|---|
| 56 | if self.sep_character == '': |
|---|
| 57 | self.sep_character = _DEFAULT_SEP |
|---|
| 58 | self.sep_character = self.sep_character[0] |
|---|
| 59 | |
|---|
| 60 | |
|---|
| 61 | # ITemplateStreamFilter methods |
|---|
| 62 | |
|---|
| 63 | def filter_stream(self, req, method, filename, stream, data): |
|---|
| 64 | page_path = req.args.get('page',None) |
|---|
| 65 | if not page_path or page_path == 'WikiStart': |
|---|
| 66 | return stream |
|---|
| 67 | |
|---|
| 68 | page_paths = page_path.split('/') |
|---|
| 69 | # reverse it so we can .pop() in the necessary order |
|---|
| 70 | page_paths.reverse() |
|---|
| 71 | |
|---|
| 72 | _links = [] |
|---|
| 73 | _base = "/wiki" |
|---|
| 74 | _prev_path = "" |
|---|
| 75 | while page_paths: |
|---|
| 76 | page_path = page_paths.pop() |
|---|
| 77 | _prev_path += "/" + page_path |
|---|
| 78 | _link = None |
|---|
| 79 | if page_paths: |
|---|
| 80 | _link = _base + _prev_path |
|---|
| 81 | t = (page_path, _link) |
|---|
| 82 | _links.append(t) |
|---|
| 83 | # always prepend the default start page link |
|---|
| 84 | _links = [('Start Page','/wiki/WikiStart')] + _links |
|---|
| 85 | |
|---|
| 86 | r = [] |
|---|
| 87 | for link in _links: |
|---|
| 88 | text, _href = link |
|---|
| 89 | if _href: |
|---|
| 90 | r += tag(tag.a(text, href=_href), |
|---|
| 91 | ' %s ' % self.sep_character) |
|---|
| 92 | else: |
|---|
| 93 | # last entry in list |
|---|
| 94 | # ..so _href is None |
|---|
| 95 | # ..so no sep char appended |
|---|
| 96 | r += tag(text) |
|---|
| 97 | |
|---|
| 98 | # http://genshi.edgewall.org/wiki/GenshiRecipes/HtmlTransform |
|---|
| 99 | # http://genshi.edgewall.org/browser/trunk/genshi/filters/transform.py |
|---|
| 100 | t1 = Transformer( |
|---|
| 101 | "//div[@id='ctxtnav']//a[@href='/wiki/WikiStart']") \ |
|---|
| 102 | .replace(r) |
|---|
| 103 | stream |= t1 |
|---|
| 104 | return stream |
|---|