The hgweb interface is completely themable. All output is generated from templates, nothing is hardcoded. Here's how it works:

The Map File

The hgweb engine looks up templates in a file named templates/map (or templates/map-<style> if a style is specified). It looks something like this:

default = "changelog"
header = header.tmpl
footer = footer.tmpl
search = search.tmpl
changelog = changelog.tmpl
naventry = "<a href="?cmd=changelog;rev={rev}">{label}</a> "
filedifflink = "<a href="?cmd=filediff;node={node};file={file}">{file}</a> "
filenodelink = "<a href="?cmd=file;filenode={filenode};file=[file}">{file}</a> "
...

This maps a template name to either a file (for example 'header' is found in header.tmpl) or a simple quoted string (eg naventry). The latter is used for small templates where a separate file would be awkward.

A style is simply a separate map file and possibly some additional template files. Mercurial comes with a few styles already, including the default HTML style, an XML style for RSS feeds, and a 'raw' style that allows getting patches and source files as plain text, as well as a gitweb-lookalike style

Templates

Each template is simply a file or string with a number of tags of the form {variable} that get replaced with the appropriate text when the template gets processed. For example, here's the template for the tags page in the default theme:

{header}
<title>{repo}: tags</title>
</head>
<body>

<div class="buttons">
<a href="?cmd=changelog;rev={rev}">changelog</a>
<a href="?cmd=manifest;manifest={manifest};path=/">manifest</a>
</div>

<h2>tags:</h2>

<ul id="tagEntries">
{entries%tagentry}
</ul>

{footer}

Interpolations

Note the {entries%tagentry} line above. The entries variable is actually a list of variable mappings, and the % syntax instructs the template engine to apply the tagentry format to each of them.

Filters

There is also a set of filters that can be applied to replacements, for example:

<title>{repo|escape}: changeset {node|short}</title>

This applies the 'escape' filter to the 'repo' variable and the 'short' filter to the node variable. Multiple filters can be applied to a single variable:

<h2>changeset: {repo|escape|firstline}</h2>

The available filters include:

Creating your own theme

Now that you know how the templates work, creating your own theme is simply a matter of copying the stock map file to map-mytheme, modifying it, and copying any template files you modify. Then you can add the following to your .hg/hgrc file:

[web]
style = mytheme


CategoryWeb