Hey everyone (again),
I have updated the Navigation macro to include some new things,
including a Tree navigation.
Features of this new macro:
Will work just like the old Navigation macro
[[Navigation(help)]] will print a help table
new types, tree navigation, both children, siblings, and root
new format bulleted list (only applies to siblings and children)
can show full name of page
can pass in a rootpage
can turn off the table around the output
Feel free to include it in MoinMoin.
Newest Stuff:
I added the roottree type since the last update. Several people asked me
why [[Navigation(childtree, rootpage=/)]] or [[Navigation(tree,
rootpage=FrontPage]] didn't work. That is because / is not really a
page in the wiki internals, merely a pointer to somewhere else.
Thanks,
Eric
The Help:
[[Navigation(args)]]: navigate slides or children and sibling pages
Arg Number and/or keyword Argument Definition
---------------------------------------------------
0 \ type the type of navigation valid types are: children,
siblings, tree, roottree, childtree, slideshow,
slides (default: children)
1 \ maxdepth the maximum depth to search (default: No limit)
format the format of the list (only for siblings, children),
valid: bullet, string (default: string)
fullname flag to show the full name of the page, True of False
(default: False)
navtable flag to wrap the output in the navtable, True or False
(default: True)
rootpage the root page to start from, (default: current page)
showsys flag to show system pages, only for roottree, True or
False (default: False)
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Navigation Macro
@copyright: 2003 by J�rgen Hermann <[EMAIL PROTECTED]>
@license: GNU GPL, see COPYING for details.
"""
import re
from MoinMoin import config
from MoinMoin.Page import Page
from MoinMoin import wikiutil
Dependencies = ["namespace"]
# helpers
#!!! refactor these to an util module?
def _getParent(pagename):
""" Return parent of pagename.
"""
pos = pagename.rfind('/')
if pos >= 0:
return pagename[:pos]
return None
def _getPages(request, filter_regex=None):
""" Return a (filtered) list of pages names.
"""
filter = None
if filter_regex:
filter = re.compile(filter_regex).match
pages = request.rootpage.getPageList(filter=filter)
pages.sort()
return pages
def _getLinks(request, pagename, filter_regex=None):
""" Return pagename for up, first, prev, next, last; each can be None.
"""
pos, size, first, prev, next, last = 0, 0, None, None, None, None
all_pages = _getPages(request, filter_regex)
size = len(all_pages)
if all_pages:
try:
pos = all_pages.index(pagename)
except ValueError:
# this should never happen in theory, but let's be sure
pass
else:
if pos > 0:
first = all_pages[0]
prev = all_pages[pos-1]
if pos+1 < len(all_pages):
next = all_pages[pos+1]
last = all_pages[-1]
return pos, size, (first, prev, next, last)
class Navigation:
""" Dispatcher class implementing the navigation schemes.
"""
# querystring for slideshow links
PROJECTION = 'action=print&media=projection'
def __init__(self, macro, args):
""" Prepare common values used during processing.
"""
self.keywordhelp = {}
self.keywordhelp['0 \ type'] = """the type of navigation
valid types are: children, siblings, tree, roottree, childtree,
slideshow, slides (default: children)
"""
self.keywordhelp['1 \ maxdepth'] = """the maximum depth to search
(default: No limit) """
self.keywordhelp['format'] = """the format of the list (only for
children, siblings), valid:
bullet, string (default: string)"""
self.keywordhelp['navtable'] = """flag to wrap the output in the
navtable, True or False
(default: True)"""
self.keywordhelp['rootpage'] = """the root page to start from,
(default: current page)"""
self.keywordhelp['fullname'] = """flag to show the full name of the
page, True of False
(default: False)"""
self.keywordhelp['showsys'] = """flag to show system pages, only for
roottree, True or False
(default: False)"""
self.macro = macro
self.args = {}
self.maxdepth = None
self.ntype = None
self.fullname = None
self.navtable = None
self.showsys = None
self.rootpage = None
self.parse_args(args)
self._ = self.macro.request.getText
self.pagename = self.macro.formatter.page.page_name
self.print_mode = self.macro.request.form.has_key('action') \
and self.macro.request.form['action'][0] == 'print'
self.media = self.macro.request.form.get('media', [None])[0]
self.querystr = self.print_mode and self.PROJECTION or ''
def parse_args(self, args):
""" parse the arguments passes
"""
argstemp = args.split(',')
for i in range(len(argstemp)):
arg = argstemp[i].strip()
self.args[i] = arg
if '=' in arg:
argname, argvalue = arg.split('=')
self.args[argname.strip()] = argvalue.strip()
self.get_maxdepth()
self.get_fullname()
self.get_navtable()
self.get_ntype()
self.get_showsys()
if 'rootpage' in self.args:
self.rootpage = self.args['rootpage']
def get_maxdepth(self):
""" get the depth
"""
if not self.maxdepth is None:
return self.maxdepth
if 'maxdepth' in self.args:
deptht = self.args['maxdepth']
elif 1 in self.args:
deptht = self.args[1]
else:
deptht = 0
try:
depth = int(deptht)
except (IndexError, TypeError, ValueError, KeyError):
depth = 0
self.maxdepth = depth
return self.maxdepth
def get_ntype(self):
""" get the navigation type
"""
if self.ntype:
return self.ntype
if 'type' in self.args:
ntype = self.args['type']
elif 0 in self.args:
ntype = self.args[0]
else:
ntype = 'children'
self.ntype = ntype
return self.ntype
def get_fullname(self):
""" get the fullname argument
"""
if not self.fullname is None:
return self.fullname
self.fullname = False
if 'fullname' in self.args:
fulltemp = self.args['fullname']
if fulltemp == '1' or fulltemp == 'True' or fulltemp == 'true' \
or fulltemp == 'On' or fulltemp == 'on':
self.fullname = True
return self.fullname
def get_showsys(self):
""" get the fullname argument
"""
if not self.showsys is None:
return self.showsys
self.showsys = False
if 'showsys' in self.args:
showsys = self.args['showsys']
if showsys == '1' or showsys == 'True' or showsys == 'true' \
or showsys == 'On' or showsys == 'on':
self.showsys = True
return self.showsys
def get_navtable(self):
""" get the navtable argument
"""
if not self.navtable is None:
return self.navtable
self.navtable = True
if 'navtable' in self.args:
navtemp = self.args['navtable']
if navtemp == '0' or navtemp == 'False' or navtemp == 'false'\
or navtemp == 'Off' or navtemp == 'off':
self.navtable = False
return self.navtable
def do_help(self):
""" return the formatted help
"""
macro = self.macro
result = []
result.append(macro.formatter.table(1))
result.append(macro.formatter.table_row(1))
result.append(macro.formatter.table_cell(1, {'colspan' : '2'}))
result.append("""[[Navigation(args)]]: navigate slides or \
children and sibling pages""")
result.append(macro.formatter.table_cell(0))
result.append(macro.formatter.table_row(0))
result.append(macro.formatter.table_row(1))
result.append(macro.formatter.table_cell(1, {'colspan' : '2'}))
result.append("""Examples: [[Navigation(roottree, maxdepth=3)]]\
[[Navigation(children, format=bullet, rootpage=HelpOnMacros)]]""")
result.append(macro.formatter.table_cell(0))
result.append(macro.formatter.table_row(0))
result.append(macro.formatter.table_row(1))
result.append(macro.formatter.table_cell(1))
result.append('Arg Number and/or keyword')
result.append(macro.formatter.table_cell(0))
result.append(macro.formatter.table_cell(1))
result.append('Argument Definition')
result.append(macro.formatter.table_cell(0))
result.append(macro.formatter.table_row(0))
keys = self.keywordhelp.keys()
keys.sort()
for item in keys:
result.append(macro.formatter.table_row(1))
result.append(macro.formatter.table_cell(1))
result.append(item)
result.append(macro.formatter.table_cell(0))
result.append(macro.formatter.table_cell(1))
result.append(self.keywordhelp[item])
result.append(macro.formatter.table_cell(0))
result.append(macro.formatter.table_row(0))
result.append(macro.formatter.table(0))
return ''.join(result)
def format(self, plist):
""" dispatch to the correct formatting function
"""
if 'format' in self.args:
format = self.args['format']
else:
format = 'string'
result2 = []
if self.fullname:
for item in plist:
result2.append((item[0], item[0]))
else:
result2 = plist
fformat = getattr(self, 'format_' + format)
return fformat(result2)
def format_bullet(self, plist):
""" format the result as bulleted list
"""
plist.sort()
# send list of template pages
result = self.macro.formatter.bullet_list(1)
for child, shortname in plist:
result = result + \
self.macro.formatter.listitem(1) + \
Page(self.macro.request, child).link_to(
self.macro.request, text=shortname,
querystr=self.querystr) + \
self.macro.formatter.listitem(0)
result = result + self.macro.formatter.bullet_list(0)
return result
def format_string(self, plist):
""" format the result as a string
"""
result = []
for child, shortname in plist:
result.append(Page(self.macro.request, child).link_to(
self.macro.request, text=shortname,
querystr=self.querystr))
result.append(' ')
return ''.join(result)
def dispatch(self):
""" Return None if in plain print mode (no navigational
elements in printouts), else the proper HTML code.
"""
if self.print_mode and self.media != 'projection':
return None
if self.ntype == 'help':
return self.do_help()
links = getattr(self, 'do_'+self.ntype, self.badscheme)(self.rootpage)
if links and self.navtable:
return '<table class="navigation"><tr><td>%s</td></tr></table>' % \
links
elif links:
return links
else:
return None
def badscheme(self, root=None):
""" Bad scheme argument.
"""
_ = self._
scheme = self.args[0]
return (self.macro.formatter.sysmsg(1) +
self.macro.formatter.text(
_("Unsupported navigation scheme '%(scheme)s'!") %
{'scheme': scheme}) +
self.macro.formatter.sysmsg(0))
def do_children(self, root=None):
""" Navigate to subpages from a parent page.
"""
# delegate to siblings code, setting the parent explicitely
return self.do_siblings(root or self.pagename)
def do_siblings(self, root=None):
""" Navigate from a subpage to its siblings.
"""
_ = self._
# get parent page name
if self.rootpage and self.ntype == 'siblings':
root = _getParent(self.rootpage)
parent = root or _getParent(self.pagename)
if not parent:
return (self.macro.formatter.sysmsg(1) +
self.macro.formatter.text(_('No parent page found!'))+
self.macro.formatter.sysmsg(0))
# iterate over children, adding links to all of them
result = []
children = _getPages(self.macro.request, '^%s/' % parent)
for child in children:
# display short page name, leaving out the parent path
# (and make sure the name doesn't get wrapped)
shortname = child[len(parent):]
# possibly limit depth
if self.maxdepth and shortname.count('/') > self.maxdepth:
continue
if not child == self.pagename:
# link to sibling / child
result.append((child, shortname))
return self.format(result)
def do_childtree(self, root=None):
""" navigate to the subpages of the current page
"""
return self.do_tree(root or self.pagename, currentdepth=0, parents={})
def do_roottree(self, root=None):
""" do a tree from the root
"""
result = []
if self.showsys:
pages = _getPages(self.macro.request)
else:
def filter(name):
return not wikiutil.isSystemPage(self.macro.request, name)
pages = self.macro.request.rootpage.getPageList(filter=filter)
if self.maxdepth > 0:
self.maxdepth -= 1
result.append('<ul>')
for item in pages:
if (not self.showsys and item == 'SystemPagesGroup') or '/' in item:
continue
result.append('<li>')
result.append(Page(self.macro.request, item).link_to(
self.macro.request, text=item,
querystr=self.querystr))
result.append('</li>')
if self.maxdepth == 0:
continue
result.append(self.do_childtree(root=item))
result.append('</ul>')
return '\n'.join(result)
def do_tree(self, root=None, currentdepth=0, parents={}):
""" Navigate to subpages from a parent page.
"""
_ = self._
# get parent page name if no root was specified
if root and self.ntype == 'tree' and currentdepth == 0:
root = _getParent(root)
parent = root or _getParent(self.pagename)
if not parent:
return (self.macro.formatter.sysmsg(1) +
self.macro.formatter.text(_('No parent page found!'))+
self.macro.formatter.sysmsg(0))
else:
parents[parent] = 1
# limit depth if a depth was specified
if self.maxdepth and currentdepth >= self.maxdepth:
return ''
# iterate over children, adding links to all of them
result = []
result.append('<ul>')
children = _getPages(self.macro.request, '^%s/' % parent)
for child in children:
# display short page name, leaving out the parent path
# (and make sure the name doesn't get wrapped)
shortname = child[len(parent)+1:]
if shortname.count('/') > 0:
shortname = re.sub('/.*$', '', shortname)
child = parent + '/' + shortname
if parents.has_key(child):
continue
result.append('<li>')
if child == self.pagename:
# do not link to focus
result.append(self.macro.formatter.text(shortname))
else:
# link to child
if self.fullname:
shortname = child
else:
shortname = child[len(parent)+1:]
result.append(Page(self.macro.request, child).link_to(
self.macro.request, text=shortname,
querystr=self.querystr))
result.append('</li>')
result.append(self.do_tree(root=child,
currentdepth=currentdepth+1,
parents=parents))
result.append('</ul>')
return ''.join(result)
def do_slideshow(self, focus=None):
""" Slideshow master page links.
If `focus` is set, it is the name of a slide page; these only
get the mode toggle and edit links.
"""
_ = self._
curpage = focus or self.pagename
result = []
if self.print_mode:
# projection mode
label = _('Wiki')
toggle = ''
result.append(Page(self.macro.request, curpage).link_to(
self.macro.request, text=_('Edit'),
querystr='action=edit'))
result.append(' ')
else:
# wiki mode
label = _('Slideshow')
toggle = self.PROJECTION
# add mode toggle link
result.append(Page(self.macro.request, curpage).link_to(
self.macro.request, text=label,
querystr=toggle))
# leave out the following on slide pages
if focus is None:
children = _getPages(self.macro.request, '^%s/' % self.pagename)
if children:
# add link to first child if one exists
result.append(' ')
result.append(Page(self.macro.request, children[0]).link_to(
self.macro.request, text=_('Start'),
querystr=self.querystr))
return ''.join(result)
def do_slides(self, root=None):
""" Navigate within a slide show.
"""
_ = self._
parent = root or _getParent(self.pagename)
if not parent:
return (self.macro.formatter.sysmsg(1) +
self.macro.formatter.text(_('No parent page found!')) +
self.macro.formatter.sysmsg(0))
# prepare link generation
result = []
labels = ['^', '|<', '<<', '>>', '>|']
filter_regex = '^%s/' % re.escape(parent)
pos, size, links = _getLinks(self.macro.request, self.pagename,
filter_regex)
pos += 1
links = zip(labels, (parent,) + links)
# generate links to neighborhood
for label, name in links:
result.append(' ')
if name:
# active link
result.append(Page(self.macro.request, name).link_to(
self.macro.request, text=label,
querystr=self.querystr))
else:
# ghosted link
result.append(self.macro.formatter.text(label))
result.append(' ')
# position indicator in the middle
if label == labels[2]:
result.append(_('Slide %(pos)d of %(size)d') % {'pos': pos,
'size': size})
return self.do_slideshow(focus=self.pagename) + ''.join(result)
def execute(macro, args):
# get HTML code with the links
navi = Navigation(macro, args or '').dispatch()
if navi:
return navi
# navigation disabled in plain print mode
return ''
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Moin-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/moin-user