view data/plugin/macro/CollectLists.py @ 353:51772c48c3eb

CollectLists: replaced filter_pattern by filter_column_value. You can preselect rows to show up only if a key value pair is equal to a given definition e.g. filter_column_value=project:: 1.7-extensions
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Thu, 05 Feb 2009 08:38:49 +0100
parents 2b139cd6c4d7
children 8b431b302c79
line wrap: on
line source
# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - macro to collect data from definition lists from subpages pages
    into a databrowser widget table

    <<CollectLists>>
    will create a table column for every subpage of the current page and fills in
    the data from each key value pair
    optional you can give the template page the definition list page depends on
    or the column_heading. In the latter case the order is used. Also it can optionally use
    another pagename. By setting optional a parser one can use e.g. wikimarkup. By
    filter_selection you can optional use the filter method of the databrowser widget.
    By using a different filter_column_value than '', eg. name:: Cohen  you get only rows shown where that
    name was found.

    @copyright: 2006 by michael cohen <scudette@users.sourceforge.net> (PageDicts)
    @copyright: 2008-2009 by MoinMoin:ReimarBauer (completly rewritten)
    @license: GNU GPL, see COPYING for details.
"""
import re
from MoinMoin import wikiutil
from MoinMoin.Page import Page
from MoinMoin.util.dataset import TupleDataset, Column
from MoinMoin.wikidicts import Dict
from MoinMoin.widget.browser import DataBrowserWidget

Dependencies = ["pages"]

def macro_CollectLists(macro, pagename=unicode,
                      align=("left", "center", "right"),
                      column_heading=u'', template=u'',
                      transpose=False,
                      filter_column_value=u'',
                      parser=u'text_moin_wiki',
                      filter_selection=u'NeverExistingDefaultFilter'):

    """
    currently we don't support transpose together with filter_selection
    """
    request = macro.request
    formatter = macro.formatter

    try:
        WikiParser = wikiutil.importPlugin(request.cfg, 'parser', parser, function="Parser")
    except wikiutil.PluginMissingError:
        WikiParser = None

    if not pagename:
        pagename = formatter.page.page_name
        
    if filter_column_value and ':: ' in filter_column_value:
        filter_key, filter_word = filter_column_value.split('::')
        filter_key = filter_key.strip()
        filter_word = filter_word.strip()
    else:
        # Don't filter if syntax was wrong
        filter_column_value = u''

    needle = '^%s/(.*)' % pagename
    filterfn = re.compile(needle).search
    pages = request.rootpage.getPageList(exists=1, filter=filterfn)
    if not pages:
        return ""
    # only one level of subpages is used (no Template pages)
    filterfn = request.cfg.cache.page_template_regexact.search
    templates = request.rootpage.getPageList(filter=filterfn)
    subpages = [page for page in pages if page not in templates]
    if subpages:
        subpages.sort()

    # use selection and order
    if column_heading:
        column_heading_keys = [key.strip() for key in column_heading.split(',')]
    # use keys from template page
    elif Page(request, template).exists():
        page = Page(request, template)
        page_dict = Dict(request, template)
        column_heading_keys = page_dict.keys()
    else:
        # fallback use the keys of the first subpage
        page = Page(request, subpages[0])
        page_dict = Dict(request, subpages[0])
        column_heading_keys = page_dict.keys()

    data = TupleDataset()
    data.columns = []
    data.columns.extend([Column(pagename.strip('/'), label=pagename.strip('/'), align=align)])
    # may be transpose should be moved into the databrowser widget
    if transpose:
        data.addRow([pagename.strip('/')] + column_heading_keys)

    for name in subpages:
        page = Page(request, name)
        page_dict = Dict(request, name)
        if filter_column_value and page_dict.get(filter_key, '') != filter_word:
            continue
        row = []
        keep = False
        for key in column_heading_keys:
            if key in page_dict.keys():
                value = page_dict.get(key, '')
                if WikiParser:
                    # xxx check how our brand new Image class solves this
                    if parser == u'text_moin_wiki':
                        value = value.replace('attachment:', 'attachment:%s/' % name)
                    row.append((wikiutil.renderText(request, WikiParser, value), wikiutil.escape(value, 1)))
                else:
                    row.append((wikiutil.escape(value, 1), wikiutil.escape(value, 1)))
            else:
                row.append('')
        parent, child = name.split('/', 1)
        link = page.link_to(request, text="/%s" % child)
        data.addRow([link] + row)
        if transpose:
            data.columns.extend([Column(link, label=link, align=align)])

    if transpose:
        data.data = map(None, zip(*data.data))
        data.data = data.data[1:]
    else:
        if filter_selection and not transpose:
            filtercols = filter_selection.split(',')
            for key in column_heading_keys:
                key = key.strip()
                if key in filtercols:
                    data.columns.append(Column(key, autofilter=(key in filtercols)))
                else:
                    data.columns.extend([Column(key, label=key, align=align)])

    table = DataBrowserWidget(request)
    table.setData(data)
    html = ''.join(table.format(method='GET'))
    # seems to work together with
    # http://moinmo.in/FeatureRequests/SortableTables?action=AttachFile&do=view&target=common.js.patch
    # html = html.replace('id="dbw.table"', 'class="sortable" id="dbw.table"')
    return html