view data/plugin/macro/CollectLists.py @ 490:d89a77a21e55

CollectLists: regex keyword replaced by search_expression. Instead of filtereing of request.rootpage.getPageList now search.searchPages is called.
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Wed, 03 Feb 2010 18:10:22 +0100
parents c00d5e661913
children 435dc7e10d78
line wrap: on
line source
# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - macro to collect data from definition lists from subpages
    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 of a definition list.
    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 definition list from another pagename.
    By setting optional a parser one can use e.g. wikimarkup from a different
    parser than moinmoin.
    By filter_selection you can optional use the filter method of the databrowser
    widget (this needs javascript enabled).
    By using a different filter_column_value than the default, eg. name:: Cohen  you
    get only rows shown where that name was found.
    By using the keyword transpose the table is shown transposed. Until transpose is not part
    of the databrowser widget itselfs we don't support filter_selection by transpose=True.
    
    <<CollectLists(search_expression=title:Examplepage/)>

    @copyright: 2006 by michael cohen <scudette@users.sourceforge.net> (PageDicts)
    @copyright: 2008-2010 by MoinMoin:ReimarBauer (completly rewritten)
    @license: GNU GPL, see COPYING for details.
"""
import re
from MoinMoin import wikiutil, search
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',
                      search_expression=None,
                      filter_selection=u'NeverExistingDefaultFilter'):

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

    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''

    if search_expression is None:
        search_expression = 'title:%s/' % pagename

    search_result = search.searchPages(request, search_expression)
    pages = [title.page_name for title in search_result.hits]

    if not pages:
        return _("Page '%(new_pagename)s' does not exist or you don't have enough rights.") % {"new_pagename": pagename}

    # ignore 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 not subpages:
        return _("Subpage of '%(pagename)s' does not exist or you don't have enough rights.") % {"pagename": pagename}
    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:
        # transpose does not support filter_selection
        if filter_selection:
            filtercols = filter_selection.split(',')
            for key in column_heading_keys:
                key = key.strip()
                if filter_selection != u'NeverExistingDefaultFilter' and 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