# HG changeset patch # User Ludovic Chabant # Date 1358020446 28800 # Node ID 0c2e7c26f93c5b48e37a8ea86bde1322f0a7ef9c # Parent f6721f283a569356fb11474de7626ccb0e819717 Added naive implementation of page queries. Added support for multiple values for a property. diff -r f6721f283a56 -r 0c2e7c26f93c wikked/wiki.py --- a/wikked/wiki.py Wed Jan 09 22:01:31 2013 -0800 +++ b/wikked/wiki.py Sat Jan 12 11:54:06 2013 -0800 @@ -67,16 +67,18 @@ meta_name = str(m.group(1)) meta_value = str(m.group(3)) if meta_value is not None and len(meta_value) > 0: - ctx.meta[meta_name] = meta_value + if meta_name not in ctx.meta: + ctx.meta[meta_name] = meta_value + elif ctx.meta[meta_name] is list: + ctx.meta[meta_name].append(meta_value) + else: + ctx.meta[meta_name] = [ ctx.meta[meta_name], meta_value ] else: ctx.meta[meta_name] = True if meta_name == 'include': - # TODO: handle self-includes or cyclic includes. - abs_included_url = Page.get_absolute_url(ctx.urldir, meta_value) - abs_included_url = Page.title_to_url(abs_included_url) - included_page = self.wiki.getPage(abs_included_url) - ctx.included_pages.append(abs_included_url) - return included_page.formatted_text + return self._processInclude(ctx, meta_value) + elif meta_name == 'query': + return self._processQuery(ctx, meta_value) return '' text = re.sub(r'^\[\[((__|\+)?[a-zA-Z][a-zA-Z0-9_\-]+):\s*(.*)\]\]\s*$', repl, text, flags=re.MULTILINE) @@ -99,6 +101,54 @@ return text + def _processInclude(self, ctx, value): + # TODO: handle self-includes or cyclic includes. + abs_included_url = Page.get_absolute_url(ctx.urldir, value) + abs_included_url = Page.title_to_url(abs_included_url) + included_page = self.wiki.getPage(abs_included_url) + ctx.included_pages.append(abs_included_url) + return included_page.formatted_text + + def _processQuery(self, ctx, query): + parameters = { + 'header': "", + 'item': "
  • {{title}}
  • ", + 'empty': "

    No page matches the query.

    " + } + meta_query = {} + arg_pattern = r"(^|\|)(?P[a-zA-Z][a-zA-Z0-9_\-]+)=(?P[^\|]+)" + for m in re.findall(arg_pattern, query): + if m[1] not in parameters: + meta_query[m[1]] = m[2] + else: + parameters[m[1]] = m[2] + + matched_pages = [] + for p in self.wiki.getPages(): + if p.url == ctx.url: + continue + for key, value in meta_query.iteritems(): + actual = p.getUserMeta(key) + if (type(actual) is list and value in actual) or (actual == value): + matched_pages.append(p) + if len(matched_pages) == 0: + return parameters['empty'] + + text = parameters['header'] + for p in matched_pages: + item_str = parameters['item'] + tokens = { + 'url': p.url, + 'title': p.title + } + for tk, tv in tokens.iteritems(): + item_str = item_str.replace('{{%s}}' % tk, tv) + text += item_str + text += parameters['footer'] + + return text + def _formatWikiLink(self, ctx, display, url): abs_url = Page.get_absolute_url(ctx.urldir, url) slug = Page.title_to_url(abs_url) @@ -175,6 +225,10 @@ meta[name] = self._coerce_promoted_meta[name](meta[name]) return meta + def getUserMeta(self, key): + self._ensureMeta() + return self._meta['user'].get(key) + def getHistory(self): self._ensureMeta() return self.wiki.scm.getHistory(self._meta['path'])