diff --git a/TracWikiMacros.md b/TracWikiMacros.md new file mode 100644 index 0000000..8a71414 --- /dev/null +++ b/TracWikiMacros.md @@ -0,0 +1,114 @@ +# Trac Macros + +[PageOutline](PageOutline) + +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](WikiFormatting). + +Another kind of macros are [WikiProcessors](WikiProcessors). They typically deal with alternate markup formats and representation of larger blocks of information (like source code highlighting). + +## Using Macros +Macro calls are enclosed in two *square brackets*. Like Python functions, macros can also have arguments, a comma separated list within parentheses. + +Trac macros can also be written as [TracPlugins](TracPlugins). This gives them some capabilities that macros do not have, such as being able to directly access the HTTP request. + +### Example + +A list of 3 most recently changed wiki pages starting with 'Trac': + +``` + [[RecentChanges(Trac,3)]] +``` + +Display: + [RecentChanges](RecentChanges)(Trac,3) + +## Available Macros + +*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 [mod_python](TracModPython).* + +[MacroList](MacroList) + +## Macros from around the world + +The [Trac Hacks](http://trac-hacks.org/) site provides a wide collection of macros and other Trac [plugins](TracPlugins) 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. + +## Developing Custom Macros +Macros, like Trac itself, are written in the [Python programming language](http://python.org/). + +For more information about developing macros, see the [development resources](TracDev) on the main project site. + + +## Implementation + +Here are 2 simple examples on how to create a Macro with [Trac 0.11](0.11) have a look at source:trunk/sample-plugins/Timestamp.py for an example that shows the difference between old style and new style macros and also source:trunk/wiki-macros/README which provides a little more insight about the transition. + +### Macro without arguments +It should be saved as `TimeStamp.py` as Trac will use the module name as the Macro name +```#!python +from datetime import datetime +# Note: since Trac 0.11, datetime objects are used internally + +from genshi.builder import tag + +from trac.util.datefmt import format_datetime, utc +from trac.wiki.macros import WikiMacroBase + +class TimestampMacro(WikiMacroBase): + """Inserts the current time (in seconds) into the wiki page.""" + + revision = "$Rev$" + url = "$URL$" + + def expand_macro(self, formatter, name, args): + t = datetime.now(utc) + return tag.b(format_datetime(t, '%c')) +``` + +### Macro with arguments +It should be saved as `HelloWorld.py` (in the plugins/ directory) as Trac will use the module name as the Macro name +```#!python +from trac.wiki.macros import WikiMacroBase + +class HelloWorldMacro(WikiMacroBase): + """Simple HelloWorld macro. + + Note that the name of the class is meaningful: + - it must end with "Macro" + - what comes before "Macro" ends up being the macro name + + The documentation of the class (i.e. what you're reading) + will become the documentation of the macro, as shown by + the !MacroList macro (usually used in the TracWikiMacros page). + """ + + revision = "$Rev$" + url = "$URL$" + + def expand_macro(self, formatter, name, args): + """Return some output that will be displayed in the Wiki content. + + `name` is the actual name of the macro (no surprise, here it'll be + `'HelloWorld'`), + `args` is the text enclosed in parenthesis at the call of the macro. + Note that if there are ''no'' parenthesis (like in, e.g. + [[HelloWorld]]), then `args` is `None`. + """ + return 'Hello World, args = ' + unicode(args) + + # Note that there's no need to HTML escape the returned data, + # as the template engine (Genshi) will do it for us. +``` + + +### `expand_macro` details +`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. + +If your macro creates wiki markup instead of HTML, you can convert it to HTML like this: + +```#!python + text = "whatever wiki markup you want, even containing other macros" + # Convert Wiki markup to HTML, new style + out = StringIO() + Formatter(formatter.context).format(text, out) + return Markup(out.getvalue()) +```