Starting with version 0.9 , you can develop plugins for Trac that extend the
builtin functionality. The plugin functionality is based on the component architecture , so please
read that document before continuing here.
Extension points¶
扩展点
Trac offers an increasing number of extension points that allow you to
plugin custom extensions for various functions. You can view a list of provided
extension points on the page About Trac/Plugins of your Trac
installation.
Currently we have:
-
目前我们有以下扩展点:
-
Allows plugins to participate in the creation and upgrade of the
environment. Can be used to setup additional database tables or directories
needed for the plugin to operate
- 允许插件参与environment的创建和更新。可用于安装插件所需要的额外的数据表或者目录 trac.web.api.IRequestHandler
-
Allows plugins to add handlers for HTTP requests.
- 允许插件新增响应HTTP请求的。 trac.web.api.IRequestFilter
-
Allows plugins to add filters to the HTTP requests.
- 允许插件添加新的HTTP请求过滤器 trac.web.chrome.INavigationContributor
-
Allows plugins to extend the navigation menus of the web interface.
- 允许插件扩展web界面的导航菜单 trac.web.chrome.ITemplateProvider
-
Extension point interface for components that provide their own
ClearSilver templates and accompanying static resources.
- 这个扩展点接口允许组件提供他们自己的ClearSilver模板 和 附属静态资源。 trac.perm.IPermissionRequestor
-
Plugins can use this extension point to define additional "actions" for the
permission system.
- 插件可以使用这个扩展点来定义permission system的额外的"功能" trac.timeline.ITimelineEventProvider
-
Allows plugins to contribute events to the
timeline .
- 允许插件在timeline发布事件 trac.mimeview.api.IHTMLPreviewRenderer
-
Allows plugins to provide support for rendering specific content of a
specific type as HTML (used for TracSyntaxColoring and image preview)
- 允许插件提供对HTML特殊类型的渲染具体内容的支持(被TracSyntaxColoring和图片预览(image preview)使用) trac.wiki.api.IWikiChangeListener
- Allows plugins to observe creation, modification and deletion of wiki pages.
-
允许插件监听wiki页面的创建、修改和删除。
trac.wiki.api.IWikiMacroProvider
-
Allows plugins to contribute
WikiMacros to Trac.
- 允许插件为Trac贡献WikiMacro trac.wiki.api.IWikiSyntaxProvider
-
Plugins can extend this extension point to add custom syntax rules to the
wiki formatting system. In particular, this allows registration of additional TracLinks types.
- 插件可以扩展这个扩展点,为wiki format system 添加定制的语法规则。尤其,允许注册额外的TracLinks类型。 trac.ticket.api.ITicketChangeListener
-
Extension point interface for components that require notification when
tickets are created, modified, or deleted. - 当传票(tickets)被、修改或删除时,需要被通知的组件需要这个扩展接口。
trac.env.IEnvironmentSetupParticipant
Note that plugins can themselves add new extension points, so the list
above is incomplete by nature.
Writing the plugin code¶
编写插件代码To extend Trac with a custom plugin, you need to implement a
component . For example, to add a new web module to Trac (i.e. a component
that handles HTTP requests and extends the navigation bar), you'd start with
something like the following code:
from trac.core import *
from trac.util.html import html
from trac.web import IRequestHandler
from trac.web.chrome import INavigationContributor
class HelloWorldPlugin ( Component):
implements( INavigationContributor, IRequestHandler)
# INavigationContributor methods
def get_active_navigation_item ( self , req):
return 'helloworld'
def get_navigation_items ( self , req):
yield ( 'mainnav' , 'helloworld' ,
html. A( 'Hello world' , href= req. href. helloworld()))
# IRequestHandler methods
def match_request ( self , req):
return req. path_info == '/helloworld'
def process_request ( self , req):
req. send_response( 200 )
req. send_header( 'Content-Type' , 'text/plain' )
req. end_headers()
req. write( 'Hello world!' )
Look at the API documentation for the extension point interfaces to see what
you're expected to return. See the tutorial
page for more plugin tutorials.
Every component that gets instantiated through the Trac environment gets
three extra member variables for convenience:
- env : The environment, an instance of the
trac.env.Environment class (see trac.env ). - env: 环境,类 trac.env.Environment 的实例
- config : The configuration, an instance of the
trac.config.Configuration class (see trac.config ). - config: 配置,类trac.config.Configuration的实例
- log : The configured logger, see the Python logging
API for more information. - log: 配置日志,阅读python的日志API获取更多信息
These variables can also be accessed from the initializer (__init__ )
of a component.
Storing any other objects as instance variables of your component is probably
a bad idea: remember that a component is only instantiated once for a given
environment; unless your plugin is used in a CGI deployment of Trac, that means
that the same component instance will get invoked for multiple HTTP requests; if
the server is multi-threaded, this will even happen concurrently.
Packaging plugins¶
打包插件TracPlugins are packaged as Python Eggs . You can use setuptools to make a setup.py script that will produce a Python egg for your plugin.
TracPlugins 以 Python Eggs方式打包。 你可以使用 setuptools 来生成 setup.py 脚本,这个脚本会生成你插件的python egg文件。The egg needs to export an entry point group named trac.plugins , listing the
names of the modules that Trac should import for the plugin-provided components
to get registered. For example:
from setuptools import find_packages, setup
setup(
name= 'TracHelloWorld' , version= '1.0' ,
packages= find_packages( exclude= [ '*.tests*' ]),
entry_points = """
[trac.plugins]
helloworld = myplugs.helloworld
""" ,
)
This assumes that the HelloWorldPlugin example above is defined in
the module helloworld.py in the myplugs package. The entry
point name (in this example “helloworld”) is required by the Python egg
runtime, but not currently used by Trac. In most cases, you can simply use the
qualified module name there.
由于 向后兼容原因,Trac仍然支持另一种入口点:你可以在 EGG_INFO 目录下有一个 trac_plugin.txt 文件。这个文件包含了Trac注册你组件所需的所有模块的名字。注意这 个方法不推荐使用,在Trac的未来版本会被移除(最快可能是0.11版本)
For backwards-compatibility reasons, Trac still supports an alternative to
entry points: you can have a file named trac_plugin.txt in the
EGG-INFO directory. This file should contain the names of all modules
that need to be imported by Trac to register your components. Note that this
method is deprecated and will be removed in a future version of
Trac (probably as soon as 0.11 ).
Plugin deployment¶
部署插件A plugin can either be deployed globally, or only for a specific environment.
Global deployment is done by installing the plugin:
一个插件可以全局部署,也可以只对特定的environment部署。 通过安装该插件完成全局部署:
$ cd /path/to/pluginsource
$ python setup.py install
To deploy a plugin only to a specific Trac environment, copy the egg file
into the plugins directory of that environment:
为了仅对某个Trac environment部署插件,把文件file拷贝到environment的plugins目录。
$ cd /path/to/pluginsource
$ python setup.py bdist_egg
$ cp dist/*.egg /path/to/projenv/plugins
During development of a plugin, it is inconvenient to have to install it in
either of the ways described above. Instead, you should use the setuptools
develop command:
在开发插件期间,通过上面两种方法安装插件都是不方便的。 相反,你可以使用 setuptools的develop 命令:
$ cd /path/to/pluginsource
$ python setup.py develop --multi-version --install-dir /path/to/projenv/plugins
or the short version :
或者
$ python setup.py develop -md /path/to/projenv/plugins
You can omit the --install-dir and --multi-version
arguments to make the development version of your plugin available globally.
This will install an .egg-link file instead of the actual egg. That
file is basically a link to the source directory of your plugin, so that Trac
will always see the latest version of your code. In this case you will have to
explicitly enable your plugin in the trac configuration as explained on TracPlugins .
A tutorial to build your own plugins is available here .
一个编译插件的技巧可在这里找到。Sometimes you might want to write a plugin that completely replaces a
built-in component, for example to develop an advanced variant of an existing
module. Trac uses a list of default component to load , as specified in the
default_components list in trac.db_default . These built-in components are always loaded, and might therefore conflict with your replacement plugin.
You can however disable built-in components using a special trac.ini section called [components] . This section contains the qualified name of the components to disable, along with
disabled or off as the value.
For example, to disable the built-in Wiki macro RecentChanges , you'd
include the following in trac.ini :
例如,为了禁止内置的wiki宏 RecentChanges组件,你应该在trac.ini包含下面配置:
[components]
trac.wiki.macros.RecentChangesMacro = disabled
You can also use a wildcard at the end of a name, so you could even disable
the complete Wiki module (although wiki formatting will still work in the
remaining modules, of course):
你也可以在名字后面使用通配符,你可能是禁止wiki所有模块(当然,在余下模块的wiki 格式组件仍然运行)
[components]
trac.wiki.* = disabled
Debugging¶
调试The logging API is very good debugging tool. Simply use this code when you
want to view value of a variable:
日志记录API 是一个非常好用的调试工具。当你想查看一个变量的指时,可以很简单地使用下面的代码:
env.log.info(varname) or self.env.log.info(varname)
You need to turn on logging in the trac.ini file. Info level log is not as
often as debug level. Thus it is very good way to debug the plug-in code.
However, you should use debug method if you want to leave the code when you
finish developing the plug-in.
你需要在trac.ini文件里打开日志功能。 Info级别不像调试级别经常使用。因此,这是一种很好的调试你插件代码的方式。不过, 当你完成开发插件时还想保留代码,应该使用debug方法。