| 1 | = Trac マクロ = #TracMacros |
| 2 | |
| 3 | [[PageOutline]] |
| 4 | |
| 5 | Trac マクロとは、 Python で書かれた 'カスタム関数' によって Trac の Wiki エンジンを拡張するプラグインです。 WikiFormatting エンジンが利用可能なあらゆるコンテキストにおいて、マクロを使用することによって、動的な HTML データが挿入されます。 |
| 6 | |
| 7 | もう 1 種類のマクロは WikiProcessors です。これは通常、 Wiki 以外のマークアップ形式と表示を取り扱うために使用し、多くは、 (ソースコードハイライトのような) より大きいブロックに使用します。 |
| 8 | |
| 9 | == マクロの利用 == #UsingMacros |
| 10 | マクロ呼び出しは、二つの ''角括弧 (square brackets) '' で括られた箇所です。 Python 関数のように、マクロは引数を取ることができ、括弧 (parenthesis) の中に、カンマで区切ったリストで表記します。 |
| 11 | |
| 12 | Trac マクロは、 TracPlugins としても作成することができます。 TracPlugins として Trac マクロを作成することで「直接 HTTP リクエストにアクセスする。」といった通常の Trac マクロでは実現できない機能を実装することができます。 |
| 13 | |
| 14 | === 利用例 === #Example |
| 15 | |
| 16 | 'Trac' で始まる Wiki ページの最近の変更履歴 3 件分を表示するマクロです: |
| 17 | |
| 18 | {{{ |
| 19 | [[RecentChanges(Trac,3)]] |
| 20 | }}} |
| 21 | |
| 22 | は、以下のように表示されます: |
| 23 | [[RecentChanges(Trac,3)]] |
| 24 | |
| 25 | == マクロ一覧 == #AvailableMacros |
| 26 | |
| 27 | ''Note: 以下に示すリストはマクロドキュメントを含むものだけです。 `-OO` による最適化や、 [wiki:TracModPython mod_python] での `PythonOptimize` オプションが設定されていると表示されません。'' |
| 28 | |
| 29 | [[MacroList]] |
| 30 | |
| 31 | == 世界のマクロを共有 == #Macrosfromaroundtheworld |
| 32 | |
| 33 | [http://trac-hacks.org/ Trac Hacks] というサイトは、コミュニティに寄稿されたマクロと [TracPlugins プラグイン] を収集し提供しています。新しいマクロを探している、共有したいマクロを作成した、などの場合は遠慮なく Trac Hacks のサイトを訪問してください。 |
| 34 | |
| 35 | == カスタムマクロを開発する == #DevelopingCustomMacros |
| 36 | マクロは、 Trac 自身と同じように [http://www.python.org/ Python] で書かれています。 |
| 37 | |
| 38 | マクロの開発についての詳しい情報は [http://trac.edgewall.org/wiki/TracDev リソースの開発] を参照してください。 |
| 39 | |
| 40 | |
| 41 | == マクロの実装 == #Implementation |
| 42 | |
| 43 | Trac 0.11 でマクロを作成する簡単な例を 2 つ紹介します。 |
| 44 | |
| 45 | 古いマクロと新しいマクロの違いを示す例は [http://trac.edgewall.org/browser/tags/trac-0.11/sample-plugins/Timestamp.py Timestamp.py] を参照してください。また、古いマクロから新しいマクロに移行するための情報は [http://trac.edgewall.org/browser/tags/trac-0.11/wiki-macros/README macros/README] を参照してください。 |
| 46 | |
| 47 | === 引数なしのマクロ === #Macrowithoutarguments |
| 48 | Trac は マクロ名としてモジュール名を使用するので以下のサンプルは (TracEnvironment 配下の `plugins/` ディレクトリに) `TimeStamp.py` という名前で保存しなければなりません。 |
| 49 | {{{ |
| 50 | #!python |
| 51 | from datetime import datetime |
| 52 | # Note: since Trac 0.11, datetime objects are used internally |
| 53 | |
| 54 | from genshi.builder import tag |
| 55 | |
| 56 | from trac.util.datefmt import format_datetime, utc |
| 57 | from trac.wiki.macros import WikiMacroBase |
| 58 | |
| 59 | class TimeStampMacro(WikiMacroBase): |
| 60 | """Inserts the current time (in seconds) into the wiki page.""" |
| 61 | |
| 62 | revision = "$Rev$" |
| 63 | url = "$URL$" |
| 64 | |
| 65 | def expand_macro(self, formatter, name, args): |
| 66 | t = datetime.now(utc) |
| 67 | return tag.b(format_datetime(t, '%c')) |
| 68 | }}} |
| 69 | |
| 70 | === 引数付きのマクロ === #Macrowitharguments |
| 71 | Trac は マクロ名としてモジュール名を使用するので以下のサンプルは `HelloWorld.py` という名前で (TracEnvironemnt 配下の `plugins/` ディレクトリに) 保存しなければなりません。 |
| 72 | {{{ |
| 73 | #!python |
| 74 | from trac.wiki.macros import WikiMacroBase |
| 75 | |
| 76 | class HelloWorldMacro(WikiMacroBase): |
| 77 | """Simple HelloWorld macro. |
| 78 | |
| 79 | Note that the name of the class is meaningful: |
| 80 | - it must end with "Macro" |
| 81 | - what comes before "Macro" ends up being the macro name |
| 82 | |
| 83 | The documentation of the class (i.e. what you're reading) |
| 84 | will become the documentation of the macro, as shown by |
| 85 | the !MacroList macro (usually used in the WikiMacros page). |
| 86 | """ |
| 87 | |
| 88 | revision = "$Rev$" |
| 89 | url = "$URL$" |
| 90 | |
| 91 | def expand_macro(self, formatter, name, args): |
| 92 | """Return some output that will be displayed in the Wiki content. |
| 93 | |
| 94 | `name` is the actual name of the macro (no surprise, here it'll be |
| 95 | `'HelloWorld'`), |
| 96 | `args` is the text enclosed in parenthesis at the call of the macro. |
| 97 | Note that if there are ''no'' parenthesis (like in, e.g. |
| 98 | [[HelloWorld]]), then `args` is `None`. |
| 99 | """ |
| 100 | return 'Hello World, args = ' + unicode(args) |
| 101 | |
| 102 | # Note that there's no need to HTML escape the returned data, |
| 103 | # as the template engine (Genshi) will do it for us. |
| 104 | }}} |
| 105 | |
| 106 | {{{ |
| 107 | #!div class=important |
| 108 | 訳注 '''重要''': |
| 109 | |
| 110 | Wiki マクロが引数を持つ場合、引数は必ずサニタイズしてください。 |
| 111 | expand_macro の戻り値は `<script>` タグやイベントハンドラなどもそのまま出力するので、入力をチェックせずに、そのまま戻り値に使用するのは極めて危険です。 |
| 112 | Genshi の tag オブジェクトにラップすれば、エスケープ機構が働きますので、通常はこれを使うとよいでしょう。 |
| 113 | `HelloWorld.py` は、以下の通り書き直すことができます: |
| 114 | {{{ |
| 115 | #!python |
| 116 | from trac.wiki.macros import WikiMacroBase |
| 117 | from genshi.builder import tag |
| 118 | class HelloWorldMacro(WikiMacroBase): |
| 119 | def expand_macro(self, formatter, name, args): |
| 120 | return tag.div(u'Hello World, args = ', unicode(args)) |
| 121 | }}} |
| 122 | }}} |
| 123 | |
| 124 | === {{{expand_macro}}} について === #expand_macrodetails |
| 125 | {{{expand_macro}}} は HTML として解釈できる単純な文字列か Markup オブジェクト ({{{from trac.util.html import Markup}}} を使用する ) のどちらかを返さなければなりません。 {{{Markup(string)}}} はそのまま `string` を解釈するので、 HTML 文字列はエスケープされずに、そのとおり表示されます。 Wiki フォーマッタを使用した場合は {{{from trac.wiki import Formatter}}} のように import してください。 |
| 126 | |
| 127 | マクロで HTML ではなく Wiki マークアップを使用したい場合、以下のように HTML に変換します: |
| 128 | |
| 129 | {{{ |
| 130 | #!python |
| 131 | text = "whatever wiki markup you want, even containing other macros" |
| 132 | # Convert Wiki markup to HTML, new style |
| 133 | out = StringIO() |
| 134 | Formatter(self.env, formatter.context).format(text, out) |
| 135 | return Markup(out.getvalue()) |
| 136 | }}} |