License New BSD license
Lines 80
Keywords
arbitrary options (2) plugin (2) project info (1) project management (2) trac (2) trac plugin (1)
Permissions
Viewable by Everyone
Editable by All Siafoo Users
Hide
Bored? Check out the Recent Activity on Siafoo Join Siafoo Now or Learn More

Pass arbitrary options from conf.ini to templates in Trac Atom Feed 0

In Brief This is the meat for an arbitrary options plugin for Trac. You put whatever options you'd like in a [project_info] stanza inside your trac's .ini file. These are passed to the template as key-value pairs inside the dictionary 'project_info'.... more
# 's
 1# Copyright 2009 David Isaacson
2# Modified BSD License
3
4from trac.core import Component, implements
5from trac.env import open_environment
6from trac.web.main import get_environments
7from trac.web.api import IRequestFilter, RequestDone
8from trac.util.text import to_unicode
9
10class ArbitraryOptionsPlugin(Component):
11 implements(IRequestFilter)
12
13 #magic self variables: env, config, log
14
15 def __init__(self):
16 self.env.project_info = dict(self.config.options('project_info'))
17
18 #IRequestFilter
19 """Extension point interface for components that want to filter HTTP
20 requests, before and/or after they are processed by the main handler."""
21
22 def pre_process_request(self, req, handler):
23 """Called after initial handler selection, and can be used to change
24 the selected handler or redirect request.
25
26 Always returns the request handler, even if unchanged.
27 """
28 return handler
29
30 # for ClearSilver templates
31 def post_process_request(self, req, template, content_type):
32 """Do any post-processing the request might need; typically adding
33 values to req.hdf, or changing template or mime type.
34
35 Always returns a tuple of (template, content_type), even if
36 unchanged.
37
38 Note that `template`, `content_type` will be `None` if:
39 - called when processing an error page
40 - the default request handler did not return any result
41
42 (for 0.10 compatibility; only used together with ClearSilver templates)
43 """
44 return (template, content_type)
45
46 # for Genshi templates
47 def post_process_request(self, req, template, data, content_type):
48 """Do any post-processing the request might need; typically adding
49 values to the template `data` dictionary, or changing template or
50 mime type.
51
52 `data` may be update in place.
53
54 Always returns a tuple of (template, data, content_type), even if
55 unchanged.
56
57 Note that `template`, `data`, `content_type` will be `None` if:
58 - called when processing an error page
59 - the default request handler did not return any result
60
61 (Since 0.11)
62 """
63
64 data['project_info'] = self.env.project_info
65
66 _get_project_index(req, data)
67
68 return (template, data, content_type)
69
70
71# Modified from trac's web.main.send_project_index
72def _get_project_index(req, data):
73
74 environ = req.environ
75
76 try:
77 #href = Href(req.base_path)
78 projects = []
79 for env_name, env_path in get_environments(environ).items():
80 try:
81 env = open_environment(env_path, use_cache=not environ['wsgi.run_once'])
82 proj = {
83 'name': env.project_name,
84 'description': env.project_description,
85 'href': env_name,
86 'info': env.project_info
87 }
88 except Exception, e:
89 proj = {'name': env_name, 'description': to_unicode(e), 'info': {}}
90 projects.append(proj)
91
92 projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))
93
94 data['projects'] = projects
95
96 except RequestDone:
97 pass

This is the meat for an arbitrary options plugin for Trac. You put whatever options you'd like in a [project_info] stanza inside your trac's .ini file. These are passed to the template as key-value pairs inside the dictionary 'project_info'.

You can also access data for other projects in your trac env under the list 'projects'. That list will have a dictionary with keys 'name', 'description', 'href', and 'info', where the first three are the same as in a project list, and the 'info' is the dictionary of arbitrary options you've passed for that project.

This is also a great super-simple example of a Trac plugin.

For example, if your .ini had this:

# 's
1[project_info]
2short_name = my_project
3status = active
4order = 3

You could access it in your Trac's Genshi templates like this:

# 's
1<p>
2 Short name is ${project_info.get('short_name')}. Status is ${project_info.get('status')}. Order is ${project_info.get('order')}.
3</p>

Note that this isn't implemented for clearsilver templates, but there's no reason it couldn't be. If you'd like a usage example head over to http://projects.icapsid.net.

Project Lists

You can include arbitrary per-project info inside your project list page, too. However trac doesn't call plugins when generating this page, so you'll have to apply the patch Patch Trac to allow arbitrary project properties. Note that the top half isn't strictly necessary, as this plugin does the same thing, but this way nothing will crash if you don't have the plugin installed.

This will pass a 'projects' list to your list page, the same list that is passed to each regular Trac page as described above.

Download

You can download the entire plugin For the time being, you can download the entire plugin or check it out from SVN.

You can also just run easy_install TracArbitraryOptionsPlugin.

Build

Or, you can build it. Here's the setup.py I've used:

# 's
 1#!/usr/bin/env python
2
3from setuptools import setup, find_packages
4
5setup(
6 name='TracArbitraryOptionsPlugin',
7 version='1.0',
8 packages=find_packages(),
9 author='David Isaacson',
10 author_email='david@icapsid.net',
11 description='Allows arbitrary options to be added to configuration files and accessed via the templates. Allows data from all projects to be accessed in each.',
12 url='http://projects.icapsid.net/',
13 license='Modified BSD',
14 entry_points = {
15 'trac.plugins': [
16 'plugin = tracarbitraryoptions'
17 ]
18 }
19)

Just create a folder hierarchy with:

  • setup.py

  • tracarbitraryoptions
    • __init__.py (contains only from arbitrary_options import *)
    • arbitrary_options.py (this snippet).

Browse the entire project

More information