miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

自プロジェクトで編集してそうな Wiki ページだけ一覧で出す Trac マクロ

Trac にはもともと TitleIndex というマクロが用意されていて、ページ一覧(TitleIndex ページ)でもこのマクロが使われているわけですが。TitleIndex マクロは Trac が最初に勝手に作るページ(Wiki* とか Trac* とか)も一覧にして出力してしまいます。この動作は、自分のプロジェクトで作成されたファイルの一覧を見たいだけの場合に結構不便だったりします。

ということで、自分のプロジェクトで編集されてそうなページの一覧だけ出力するマクロを作ってみました。なんとなく勢いで作っちゃいましたけど、似たようなものをご存知な方は教えてください。

(2011-01-04 追記)

同じ名前でほぼ同じマクロを作ってる方がいました・・・。

私の実装は TitleIndexMacro を継承しているので TitleIndex の機能がすべて使える反面、内部実装に依存しているのでいきなり動かなくなる可能性がある、といった感じです。

マクロの作り方

WikiMacros の最後らへんに載ってます。

元にするマクロ

trac/wiki/macros.py に TitleIndexMacro というクラスが用意されているので、これを改造すればよさげ。

作ってみる

ちょっと実装方法で迷ったけど、TitleIndexMacro でページ一覧を取得している処理が

    def expand_macro(self, formatter, name, content):
        #(略)
        wiki = formatter.wiki
        pages = sorted([page for page in wiki.get_pages(prefix) \
                        if 'WIKI_VIEW' in formatter.perm('wiki', page)])

こんなだから、formatter.wiki.get_pages の処理を差し替えて expand_macro を呼び出すサブクラスを作ってやれば楽そう。

ということで、

import re
from trac.wiki.macros import TitleIndexMacro

class MyTitleIndexMacro(TitleIndexMacro):
    STANDARD_RE = re.compile(r"""
        ^
        (?:
            (?:Trac|Wiki|Inter)[A-Z][a-z].*
            |CamelCase
            |PageTemplates
            |RecentChanges
            |TitleIndex
        )
        $
    """, re.VERBOSE)

    def expand_macro(self, formatter, name, content):
        _get_pages = formatter.wiki.get_pages
        def my_get_pages(prefix):
            return [page for page in _get_pages(prefix) \
                    if not self.STANDARD_RE.match(page)]
        formatter.wiki.get_pages = my_get_pages
        html = TitleIndexMacro.expand_macro(self, formatter, name, content)
        formatter.wiki.get_pages = _get_pages
        return html

こんな感じのファイルを plugins/MyTitleIndex.py として配置して、Apache を再起動。

Wiki 中に

[[MyTitleIndex(format=group,min=2)]]

みたいに書いておくと、期待どおりの動作になりました。

注意点というほどでもないですが

Trac が勝手に作るページ」は正規表現で結構いいかげんに引っ掛けています。また、SandBox はプロジェクト内で編集している可能性があるので、除外対象には入れてません。