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