Customizing layout for trac 0.11b

1,216 views
Skip to first unread message

Andrew Backer

unread,
Oct 18, 2006, 6:57:28 PM10/18/06
to Trac Users
Hello,

Is there a guide out there, or at least some tips, for customizing the
site layout with the new genshi version. In .10 there was
"site_header.cs", "site_css.cs", and others but these have now been
replaced by a "site.html" which simply says
<!--custom match templates go here-->

I know what a match is, but I looked at layout.html and don't see how
to do it.

Thanks,
Andrew

Christopher Lenz

unread,
Oct 19, 2006, 3:24:45 AM10/19/06
to trac-...@googlegroups.com

Say you want to add a link to a custom stylesheet, and then your own
header and footer:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
py:strip="">

<!--! Add site-specific style sheet -->
<head py:match="head" py:attrs="select('@*')">
${select('*')}
<link rel="stylesheet" type="text/css"
href="${href.chrome('site/style.css')}" />
</head>

<body py:match="body" py:attrs="select('@*')">
<!--! Add site-specific header -->
<div id="siteheader">
...
</div>

${select('*|text()')}

<!--! Add site-specific footer -->
<div id="sitefooter">
...
</div>
</body>

</html>


This (and other examples) should go on the TracInterfaceCustomization
page for 0.11.

Cheers,
Chris
--
Christopher Lenz
cmlenz at gmx.de
http://www.cmlenz.net/

Christopher Lenz

unread,
Oct 19, 2006, 7:22:11 AM10/19/06
to trac-...@googlegroups.com
Am 19.10.2006 um 09:24 schrieb Christopher Lenz:
> Am 19.10.2006 um 00:57 schrieb Andrew Backer:
>> Is there a guide out there, or at least some tips, for customizing
>> the
>> site layout with the new genshi version. In .10 there was
>> "site_header.cs", "site_css.cs", and others but these have now been
>> replaced by a "site.html" which simply says
>> <!--custom match templates go here-->
>>
>> I know what a match is, but I looked at layout.html and don't see how
>> to do it.
>
> Say you want to add a link to a custom stylesheet, and then your own
> header and footer:

Figured I should maybe explain some of what's going on there...

> <html xmlns="http://www.w3.org/1999/xhtml"
> xmlns:py="http://genshi.edgewall.org/"
> py:strip="">

You need a top-level element because it's required by XML, and to
declare the Genshi namespace (xmlns:py="http://
genshi.edgewall.org/"). The py:strip="" is needed so that you don't
get to <html> elements in the output.

> <!--! Add site-specific style sheet -->
> <head py:match="head" py:attrs="select('@*')">
> ${select('*')}
> <link rel="stylesheet" type="text/css"
> href="${href.chrome('site/style.css')}" />
> </head>

This is a match template that matches the <head> element. I.e.
whenever Genshi sees a <head> element in the stream, it will be
replaced by this snippet. The select() function (only available
inside match templates) lets you pull in content from the original
<head>.

py:attrs="select('@*')" is used to pull up any attributes defined on
the original <head> element.

${select('*')} is an expression that pulls up any child elements of
the <head>, such as the <title>, <meta> tags, etc.

After that, we add a custom <link> element to reference a site style
sheet. The name and path of the style sheet is entirely up to you...
this example uses a style.css file stored in the project environments
htdocs directory. Also, you can do other stuff here, such as include
javascript files/snippets, meta tags, etc.

> <body py:match="body" py:attrs="select('@*')">
> <!--! Add site-specific header -->
> <div id="siteheader">
> ...
> </div>
>
> ${select('*|text()')}
>
> <!--! Add site-specific footer -->
> <div id="sitefooter">
> ...
> </div>
> </body>

This one matches the <body> element. It does the same py:attrs trick
as before to pull up attributes. It then adds header <div> before any
other content, and a footer <div> after that content. The original
content is pulled in via ${select('*|text()')}, an XPath expression
that selects all child elements and text nodes.

As an additional example, let's assume you wanted to display a
warning on the newticket page, i.e. something you'd do with the
site_newticket.cs template in 0.10. With site.html, you'd add the
following:

<form py:match="form[@id='newticket']" py:attrs="select('@*')">
<div class="warning">
<p>Please make sure to search for existing tickets before
reporting a
new one!</p>
</div>
${select('*')}
</form>

(I just encountered a bug while testing this, the warning is rendered
multiple times... will look into that...)

> </html>

More details can be found in the Genshi documentation:

<http://genshi.edgewall.org/wiki/Documentation>
<http://genshi.edgewall.org/wiki/Documentation/xml-templates.html>

Hope this helps,

Andrew Backer

unread,
Oct 19, 2006, 1:15:39 PM10/19/06
to Trac Users
Thank you! That is an amazing bit of help, and a nice bit of work you
guys have with genshi. I did a small something with webadmin's
tempaltes and was surprised how easy it was.

What we have here all works to some degree, but not completly. I can
get my custom header in there just as I expected (for the style sheet),
but I have issues now with the body. I can get what I want into the
output, but It is all showing up inside the "main" div as declared in
layout.html. Here is what I am using, but it is basically the same
thing as you have :

<body py:match="body" py:attrs="select('@*')">

<div id="navcontainer">
<ul id="navlist">
<li id="active"><a href="/trac/xxx">xxx</a></li>
<li><a href="/trac/yyy">yyy</a></li>
</ul>
</div>
${select('*')|text()}
</body>

Now, inside layout.html's <div id="main> is the same ${select...}
statement. Somehow what I include is getting spit out in that, so it
look like this :

<body>
<div id="banner"> ... </div>
<div id="mainnav"> ... </div>
<div id="main>
<div id="navcontainer"> ...

It seems like the various parts aren't broken out individually very
much as well, so if i wanted to wrap one specific part it might not be
possible. In my case it doens't matter since it is all done through
css, but I do need ot put the "navcontainer" above the "banner" div.

Is this the expected behavior when there are multiple ${select('*')}
commands, and did the stylesheet link just come out in the right
location coincidentally?

Thanks,
Andrew Backer

Matt Good

unread,
Oct 19, 2006, 2:08:39 PM10/19/06
to Trac Users

This was the effect of Trac's "layout.html" used to include Trac's own
header and footer.

I just did an svn update and the ordering of where "site.html" gets
included has been fixed so the site layout gets applied after Trac's
layout.

-- Matt Good

Andrew Backer

unread,
Oct 19, 2006, 3:48:37 PM10/19/06
to Trac Users
That was just lovely. Truly lovely.

svn update
python setup.py build
python setup.py install
refresh browser
simle

Thanks Christopher, I assume the 'entires sorted correctly' solved
this. It wasn't in response to me, but I'll pretend that you read my
mind and fixed it before I could even post :)

- Andrew

Andrew Backer

unread,
Oct 19, 2006, 3:49:38 PM10/19/06
to Trac Users
That was just lovely. Truly lovely.

svn update
python setup.py build
python setup.py install
refresh browser
simle

Thanks Christopher, I assume the 'entires sorted correctly' solved
this. It wasn't in response to me, but I'll pretend that you read my

mind :)

- Andrew

Reply all
Reply to author
Forward
0 new messages