|   | 1 | = Trac Macros =  | 
                  
                          |   | 2 |   | 
                  
                          |   | 3 | [[PageOutline]]  | 
                  
                          |   | 4 |   | 
                  
                          |   | 5 | Trac macros are plugins to extend the Trac engine with custom 'functions' written in Python. A macro inserts dynamic HTML data in any context supporting WikiFormatting.  | 
                  
                          |   | 6 |   | 
                  
                          |   | 7 | Another kind of macros are WikiProcessors. They typically deal with alternate markup formats and representation of larger blocks of information (like source code highlighting).  | 
                  
                          |   | 8 |   | 
                  
                          |   | 9 | == Using Macros ==  | 
                  
                          |   | 10 | Macro calls are enclosed in two ''square brackets''. Like Python functions, macros can also have arguments, a comma separated list within parentheses.   | 
                  
                          |   | 11 |   | 
                  
                          |   | 12 | Trac macros can also be written as TracPlugins. This gives them some capabilities that macros do not have, such as being able to directly access the HTTP request.  | 
                  
                          |   | 13 |   | 
                  
                          |   | 14 | === Example ===  | 
                  
                          |   | 15 |   | 
                  
                          |   | 16 | A list of 3 most recently changed wiki pages starting with 'Trac':  | 
                  
                          |   | 17 |   | 
                  
                          |   | 18 | {{{  | 
                  
                          |   | 19 |  [[RecentChanges(Trac,3)]]  | 
                  
                          |   | 20 | }}}  | 
                  
                          |   | 21 |   | 
                  
                          |   | 22 | Display:  | 
                  
                          |   | 23 |  [[RecentChanges(Trac,3)]]  | 
                  
                          |   | 24 |   | 
                  
                          |   | 25 | == Available Macros ==  | 
                  
                          |   | 26 |   | 
                  
                          |   | 27 | ''Note that the following list will only contain the macro documentation if you've not enabled `-OO` optimizations, or not set the `PythonOptimize` option for [wiki:TracModPython mod_python].''  | 
                  
                          |   | 28 |   | 
                  
                          |   | 29 | [[MacroList]]  | 
                  
                          |   | 30 |   | 
                  
                          |   | 31 | == Macros from around the world ==  | 
                  
                          |   | 32 |   | 
                  
                          |   | 33 | The [http://trac-hacks.org/ Trac Hacks] site provides a wide collection of macros and other Trac [TracPlugins plugins] contributed by the Trac community. If you're looking for new macros, or have written one that you'd like to share with the world, please don't hesitate to visit that site.  | 
                  
                          |   | 34 |   | 
                  
                          |   | 35 | == Developing Custom Macros ==  | 
                  
                          |   | 36 | Macros, like Trac itself, are written in the [http://python.org/ Python programming language].  | 
                  
                          |   | 37 |   | 
                  
                          |   | 38 | For more information about developing macros, see the [trac:TracDev development resources] on the main project site.  | 
                  
                          |   | 39 |   | 
                  
                          |   | 40 |   | 
                  
                          |   | 41 | == Implementation ==  | 
                  
                          |   | 42 |   | 
                  
                          |   | 43 | Here are 2 simple examples showing how to create a Macro with Trac 0.11.   | 
                  
                          |   | 44 |   | 
                  
                          |   | 45 | Also, have a look at [trac:source:tags/trac-0.11/sample-plugins/Timestamp.py Timestamp.py] for an example that shows the difference between old style and new style macros and at the [trac:source:tags/trac-0.11/wiki-macros/README macros/README] which provides a little more insight about the transition.  | 
                  
                          |   | 46 |   | 
                  
                          |   | 47 | === Macro without arguments ===  | 
                  
                          |   | 48 | It should be saved as `TimeStamp.py` as Trac will use the module name as the Macro name  | 
                  
                          |   | 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 | === Macro with arguments ===  | 
                  
                          |   | 71 | It should be saved as `HelloWorld.py` (in the plugins/ directory) as Trac will use the module name as the Macro name  | 
                  
                          |   | 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 | === {{{expand_macro}}} details ===  | 
                  
                          |   | 108 | {{{expand_macro}}} should return either a simple Python string which will be interpreted as HTML, or preferably a Markup object (use {{{from trac.util.html import Markup}}}).  {{{Markup(string)}}} just annotates the string so the renderer will render the HTML string as-is with no escaping. You will also need to import Formatter using {{{from trac.wiki import Formatter}}}.  | 
                  
                          |   | 109 |   | 
                  
                          |   | 110 | If your macro creates wiki markup instead of HTML, you can convert it to HTML like this:  | 
                  
                          |   | 111 |   | 
                  
                          |   | 112 | {{{  | 
                  
                          |   | 113 | #!python  | 
                  
                          |   | 114 |   text = "whatever wiki markup you want, even containing other macros"  | 
                  
                          |   | 115 |   # Convert Wiki markup to HTML, new style  | 
                  
                          |   | 116 |   out = StringIO()  | 
                  
                          |   | 117 |   Formatter(self.env, formatter.context).format(text, out)  | 
                  
                          |   | 118 |   return Markup(out.getvalue())  | 
                  
                          |   | 119 | }}}  |