45 | | In the following example, we rename the link to the Wiki start "Home", and hide the "Help/Guide". We also make the "View Tickets" entry link to a specific report . |
| 44 | In the environment folder for each Trac project there should be a directory called {{{templates}}}. This folder contains files {{{site_header.cs}}} and {{{site_footer.cs}}}. Users can customize their Trac site by adding the required HTML markup to these files. The content of these two files will be placed immediately following the opening {{{<body>}}} tag and immediately preceding the closing {{{</body>}}} tag of each page in the site, respectively. |
| 45 | |
| 46 | These files may contain static HTML, though if users desire to have dynamically generated content they can make use of the [http://www.clearsilver.net/ ClearSilver] templating language from within the pages as well. When you need to see what variables are available to the template, append the query string `?hdfdump=1` to the URL of your Trac site. This will display a structured view of the template data. |
| 47 | |
| 48 | == Site CSS == |
| 49 | The primary means to adjust the layout of a Trac site is to add [http://www.w3.org/TR/REC-CSS2/ CSS] style rules that overlay the default rules. This is best done by editing the `site_css.cs` file in the enviroment's `templates` directory. The content of that template gets inserted into a `<style type="text/css"></style>` element on every HTML page generated by Trac. |
| 50 | |
| 51 | While you can add your custom style rules directly to the `site_css.cs` file, it is recommended that you simply reference an external style sheet, thereby enabling browsers to cache the CSS file instead of transmitting the rules with every response. |
| 52 | |
| 53 | The following example would import a style sheet located in the `style` root directory of your host: |
55 | | See also TracNavigation for a more detailed explanation of the mainnav and metanav terms. |
56 | | |
57 | | == Site Appearance == #SiteAppearance |
58 | | |
59 | | Trac is using [http://genshi.edgewall.org Genshi] as the templating engine. Documentation is yet to be written, in the meantime the following tip should work. |
60 | | |
61 | | Say you want to add a link to a custom stylesheet, and then your own |
62 | | header and footer. Save the following content as 'site.html' inside your projects templates directory (each Trac project can have their own site.html), e.g. {{{/path/to/env/templates/site.html}}}: |
63 | | |
| 58 | You can use a !ClearSilver variable to reference a style sheet stored in the project environment's `htdocs` directory: |
65 | | #!xml |
66 | | <html xmlns="http://www.w3.org/1999/xhtml" |
67 | | xmlns:py="http://genshi.edgewall.org/" |
68 | | py:strip=""> |
69 | | |
70 | | <!--! Add site-specific style sheet --> |
71 | | <head py:match="head" py:attrs="select('@*')"> |
72 | | ${select('*|comment()|text()')} |
73 | | <link rel="stylesheet" type="text/css" |
74 | | href="${href.chrome('site/style.css')}" /> |
75 | | </head> |
76 | | |
77 | | <body py:match="body" py:attrs="select('@*')"> |
78 | | <!--! Add site-specific header --> |
79 | | <div id="siteheader"> |
80 | | <!--! Place your header content here... --> |
81 | | </div> |
82 | | |
83 | | ${select('*|text()')} |
84 | | |
85 | | <!--! Add site-specific footer --> |
86 | | <div id="sitefooter"> |
87 | | <!--! Place your footer content here... --> |
88 | | </div> |
89 | | </body> |
90 | | </html> |
| 60 | @import url(<?cs var:chrome.href ?>/site/style.css); |
93 | | Those who are familiar with XSLT may notice that Genshi templates bear some similarities. However, there are some Trac specific features - for example '''${href.chrome('site/style.css')}''' attribute references template placed into environment's ''htdocs/'' In a similar fashion '''${chrome.htdocs_location}''' is used to specify common ''htdocs/'' directory from Trac installation. |
94 | | |
95 | | site.html is one file to contain all your modifications. It usually works by the py:match (element of attribute), and it allows you to modify the page as it renders - the matches hook onto specific sections depending on what it tries to find |
96 | | and modify them. A site.html can contain any number of such py:match sections for whatever you need to modify. This is all [http://genshi.edgewall.org/ Genshi], so the docs on the exact syntax can be found there. |
97 | | |
98 | | |
99 | | Example snippet of adding introduction text to the new ticket form (hide when preview): |
100 | | |
101 | | {{{ |
102 | | #!xml |
103 | | <form py:match="div[@id='content' and @class='ticket']/form" py:attrs="select('@*')"> |
104 | | <py:if test="req.environ['PATH_INFO'] == '/newticket' and (not 'preview' in req.args)"> |
105 | | <p>Please make sure to search for existing tickets before reporting a new one!</p> |
106 | | </py:if> |
107 | | ${select('*')} |
108 | | </form> |
109 | | }}} |
110 | | |
111 | | This example illustrates a technique of using '''`req.environ['PATH_INFO']`''' to limit scope of changes to one view only. For instance, to make changes in site.html only for timeline and avoid modifying other sections - use ''`req.environ['PATH_INFO'] == '/timeline'`'' condition in <py:if> test. |
112 | | |
113 | | If the environment is upgraded from 0.10 and a `site_newticket.cs` file already exists, it can actually be loaded by using a workaround - providing it contains no ClearSilver processing. In addition, as only one element can be imported, the content needs some sort of wrapper such as a `<div>` block or other similar parent container. The XInclude namespace must be specified to allow includes, but that can be moved to document root along with the others: |
114 | | {{{ |
115 | | #!xml |
116 | | <form py:match="div[@id='content' and @class='ticket']/form" py:attrs="select('@*')" |
117 | | xmlns:xi="http://www.w3.org/2001/XInclude"> |
118 | | <py:if test="req.environ['PATH_INFO'] == '/newticket' and (not 'preview' in req.args)"> |
119 | | <xi:include href="site_newticket.cs"><xi:fallback /></xi:include> |
120 | | </py:if> |
121 | | ${select('*')} |
122 | | </form> |
123 | | }}} |
124 | | |
125 | | Also note that the `site.html` (despite its name) can be put in a common templates directory - see the `[inherit] templates_dir` option. This could provide easier maintainence (and a migration path from 0.10 for larger installations) as one new global `site.html` file can be made to include any existing header, footer and newticket snippets. |
126 | | |
127 | | == Project List == #ProjectList |
128 | | |
129 | | You can use a custom Genshi template to display the list of projects if you are using Trac with multiple projects. |
| 63 | == Project List == |
| 64 | You can use a custom ClearSilver template to display the list of projects if you are using Trac with multiple projects. |
135 | | <!DOCTYPE html |
136 | | PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
137 | | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
138 | | <html xmlns="http://www.w3.org/1999/xhtml" |
139 | | xmlns:py="http://genshi.edgewall.org/" |
140 | | xmlns:xi="http://www.w3.org/2001/XInclude"> |
141 | | <head> |
142 | | <title>Available Projects</title> |
143 | | </head> |
144 | | <body> |
145 | | <h1>Available Projects</h1> |
146 | | <ul> |
147 | | <li py:for="project in projects" py:choose=""> |
148 | | <a py:when="project.href" href="$project.href" |
149 | | title="$project.description">$project.name</a> |
150 | | <py:otherwise> |
151 | | <small>$project.name: <em>Error</em> <br /> ($project.description)</small> |
152 | | </py:otherwise> |
153 | | </li> |
154 | | </ul> |
155 | | </body> |
| 70 | <html> |
| 71 | <head><title>Available Projects</title></head> |
| 72 | <body> |
| 73 | <h1>Available Projects</h1> |
| 74 | <ul><?cs |
| 75 | each:project = projects ?><li><?cs |
| 76 | if:project.href ?> |
| 77 | <a href="<?cs var:project.href ?>" title="<?cs var:project.description ?>"> |
| 78 | <?cs var:project.name ?></a><?cs |
| 79 | else ?> |
| 80 | <small><?cs var:project.name ?>: <em>Error</em> <br /> |
| 81 | (<?cs var:project.description ?>)</small><?cs |
| 82 | /if ?> |
| 83 | </li><?cs |
| 84 | /each ?> |
| 85 | </ul> |
| 86 | </body> |
196 | | However, do not edit templates or site resources inside the Trac egg - installing Trac again can completely delete your modifications. Instead use one of two alternatives: |
197 | | * For a modification to one project only, copy the template to project `templates` directory. |
198 | | * For a modification shared by several projects, copy the template to a shared location and have each project point to this location using the `[inherit] templates_dir =` trac.ini option. |
199 | | |
200 | | Trac resolves requests for a template by first looking inside the project, then in any inherited templates location, and finally inside the Trac egg. |
201 | | |
202 | | Trac caches templates in memory by default to improve performance. To apply a template you need to restart the server. |