Fossil

Skinning the Fossil Web Interface
Login

The Fossil web interface comes with a pre-configured look and feel. The default look and feel works fine in many situations. However, you may want to change the look and feel (the "skin") of Fossil to better suite your own individual tastes. This document provides background information to aid you in that task.

Built-in Skins

Fossil comes with multiple built-in skins. If the default skin does not suite your tastes, perhaps one of the other built-in skins will work better. If nothing else, the built-in skins can serve as examples or templates that you can use to develop your own custom skin.

The sources to these built-ins can be found in the Fossil source tree under the skins/ folder. The skins/ folder contains a separate subfolder for each built-in skin, with each subfolders holding at least these five files:

Try out the built-in skins by using the --skin option on the fossil ui or fossil server commands.

Sharing Skins

The skin of a repository is not part of the versioned state and does not "push" or "pull" like checked-in files. The skin is local to the repository. However, skins can be shared between repositories using the fossil config command. The "fossil config push skin" command will send the local skin to a remote repository and the "fossil config pull skin" command will import a skin from a remote repository. The "fossil config export skin FILENAME" will export the skin for a repository into a file FILENAME. This file can then be imported into a different repository using the "fossil config import FILENAME" command. Unlike "push" and "pull", the "export" and "import" commands are able to move skins between repositories for different projects. So, for example, if you have a group of related repositories, you can develop a skin for one of them, then get a consistent look across all the repositories by exporting the skin from the first repository and importing into all the others.

The file generated by "fossil config export" could be checked into one of your repositories and versioned, if desired. This will not automatically change the skin when looking backwards in time, but it will provide an historical record of what the skin used to be and allow the historical look of the repositories to be recreated if necessary.

When cloning a repository, the skin of the new repository is initialized to the skin of the repository from which it was cloned.

Structure Of A Fossil Web Page

Every HTML page generated by Fossil has the same basic structure:

Fossil-Generated HTML Header
Skin Header
Fossil-Generated Content
Skin Footer
Fossil-Generated HTML Footer

By default, Fossil starts every generated HTML page with this:

<html>
<head>
<base href="...">
<meta http-equiv="Content-Security-Policy" content="....">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>....</title>
<link rel="stylesheet" href="..." type="text/css">
</head>
<body class="FEATURE">

Fossil used to require a static version of this in every skin’s Header area, but over time, we have found good cause to generate multiple elements at runtime.

One such is the FEATURE element, being either the top-level HTTP request routing element (e.g. doc) or an aggregate feature class that groups multiple routes under a single name. A prime example is forum, which groups the /forummain, /forumpost, and /forume2 routes, allowing per-feature CSS. For instance, to style <blockquote> tags specially for forum posts written in Markdown, leaving all other block quotes alone, you could say:

body.forum div.markdown blockquote {
  margin-left: 10px;
}

You can override this generated HTML header by including a “<body>” tag somewhere in the Header area of the skin, but it is almost always best to limit a custom skin’s Header section to something like this:

<header>
  ...
</header>
<nav class="mainmenu" title="Main Menu">
  ...
</nav>
<nav id="hbdrop" class="hbdrop" title="sitemap"></nav>

See the stock skins’ headers for ideas of what to put in place of the ellipses.

The Fossil-generated Content section immediately follows this Header. It will look like this:

<div class="content">
  ... Fossil-generated content here ...
</div>

After the Content is the custom Skin Footer section which should follow this template:

<footer>
  ... skin-specific stuff here ...
</footer>

As with the <header> change called out above, this, too, is a breaking change in Fossil 2.24.

Finally, Fossil always adds its own footer (unless overridden) to close out the generated HTML:

</body>
</html>

Changing the Main Menu Contents

The actual text content of the skin’s main menu is not part of the skin proper if you’re using one of the stock skins. If you look at the Header section of the skin, you’ll find a <div class="mainmenu"> element whose contents are set by a short TH1 script from the contents of the Main Menu section of the Setup → Configuration screen.

This feature allows the main menu contents to stay the same across different skins, so you no longer have to reapply menu customizations when trying different skins.

See the capexpr section of the TH1 docs for help on interpreting the default contents of this block.

Overriding the HTML Header and Footer

Notice that the <html>, <head>, and opening <body> elements at the beginning of the document, and the closing </body> and </html> elements at the end are automatically generated by Fossil. This is recommended.

However, for maximum design flexibility, Fossil allows those elements to be supplied as part of the configurable Skin Header and Skin Footer. If the Skin Header contains the text "<body", then Fossil assumes that the Skin Header and Skin Footer will handle all of the <html>, <head>, and <body> text itself, and the Fossil-generated header and footer will be blank.

When overriding the HTML Header in this way, you will probably want to use some of the TH1 variables documented below such as $stylesheet_url to avoid hand-writing code that Fossil can generate for you.

Designing, Debugging, and Installing A Custom Skin

It is possible to develop a new skin from scratch. But a better and easier approach is to use one of the existing built-in skins as a baseline and make incremental modifications, testing after each step, to obtain the desired result.

The skin is controlled by five files:

css.txt

The css.txt file is the text of the CSS for Fossil. Fossil might add additional CSS elements after the css.txt file, if it sees that the css.txt omits some CSS components that Fossil needs. But for the most part, the content of the css.txt is the CSS for the page.

details.txt

The details.txt file is short list of settings that control the look and feel, mostly of the timeline. The default details.txt file looks like this:

pikchr-background:          ""
pikchr-fontscale:           ""
pikchr-foreground:          ""
pikchr-scale:               ""
timeline-arrowheads:        1
timeline-circle-nodes:      1
timeline-color-graph-lines: 1
white-foreground:           0

The three "timeline-" settings in details.txt control the appearance of certain aspects of the timeline graph. The number on the right is a boolean - "1" to activate the feature and "0" to disable it. The "white-foreground:" setting should be set to "1" if the page color has light-color text on a darker background, and "0" if the page has dark text on a light-colored background.

If the "pikchr-foreground" setting is defined and is not an empty string then it specifies a foreground color to use for pikchr diagrams. The default pikchr foreground color is black, or white if the "white-foreground" boolean is set. The "pikchr-background" settings does the same for the pikchr diagram background color. If the "pikchr-fontscale" and "pikchr-scale" values are not empty strings, then they should be floating point values (close to 1.0) that specify relative scaling of the fonts in pikchr diagrams and other elements of the diagrams, respectively.

footer.txt and header.txt

The footer.txt and header.txt files contain the Skin Footer and Skin Header respectively. Of these, the Skin Header is the most important, as it contains the markup used to generate the banner and menu bar for each page.

Both the footer.txt and header.txt file are processed using TH1 prior to being output as part of the overall web page.

js.txt

The js.txt file is optional. It is intended to be javascript. The complete text of this javascript might be inserted into the Skin Footer, after being processed using TH1, using code like the following in the "footer.txt" file:

<script nonce="$nonce">
  <th1>styleScript</th1>
</script>

The js.txt file was originally used to insert javascript that controls the hamburger menu in the default skin. More recently, the javascript for the hamburger menu was moved into a separate built-in file. Skins that use the hamburger menu typically cause the javascript to be loaded by including the following TH1 code in the "header.txt" file:

<th1>builtin_request_js hbmenu.js</th1>

The difference between styleScript and builtin_request_js is that the styleScript command interprets the file using TH1 and injects the content directly into the output stream, whereas the builtin_request_js command inserts the Javascript verbatim and does so at some unspecified future time down inside the Fossil-generated footer. You can use either approach in custom skins that you create.

Note that the "js.txt" file is not automatically inserted into the generate HTML for a page. You, the skin designer, must cause the javascript to be inserted by issuing appropriate TH1 commands in the "header.txt" or "footer.txt" files.

Developing a new skin is simply a matter of creating appropriate versions of these five control files.

Skin Development Using The Web Interface

Users with admin privileges can use the Admin/Skin configuration page on the web interface to develop a new skin. The development of a new skin occurs without disrupting the existing skin. So you can work on a new skin for a Fossil instance while the existing skin is still in active use.

The new skin is a "draft" skin. You initialize one of 9 draft skins to either the current skin or to one of the built-in skins. Then use forms to edit the 5 control files described above. The new skin can be tested after each edit. Finally, once the new skin is working as desired, the draft skin is "published" and becomes the new live skin that most users see.

Skin Development Using A Local Text Editor

An alternative approach is to copy the five control files for your baseline skin into a temporary working directory (here called "./newskin") and then launch the fossil ui command with the "--skin ./newskin" option. If the argument to the --skin option contains a "/" character, then the five control files are read out of the directory named. You can then edit the control files in the ./newskin folder using you favorite text editor, and press "Reload" on your browser to see the effects.

Disabling The Web Browser Cache During Development

Fossil is aggressive about asking the web browser to cache resources. While developing a new skin, it is often helpful to put your web browser into developer mode and disable the cache. If you fail to do this, then you might make some change to your skin under development and press "Reload" only to find that the display did not change. After you have finished work your skin, the caches should synchronize with your new design and you can reactivate your web browser's cache and take it out of developer mode.

Header and Footer Processing

The header.txt and footer.txt control files of a skin are the HTML text of the Skin Header and Skin Footer, except that before being inserted into the output stream, the text is run through a TH1 interpreter that might adjust the text as follows:

For example, first few lines of a typical Skin Header will look like this:

<div class="header">
  <div class="title"><h1>$<project_name></h1>$<title>/div>

After variables are substituted by TH1, that will look more like this:

<div class="header">
  <div class="title"><h1>Project Name</h1>Page Title</div>

As you can see, two TH1 variable substitutions were done.

The same TH1 interpreter is used for both the header and the footer and for all scripts contained within them both. Hence, any global TH1 variables that are set by the header are available to the footer.

Customizing the ≡ Hamburger Menu

The menu bar of the default skin has an entry to open a drop-down menu with additional navigation links, represented by the ≡ button (hence the name "hamburger menu"). The Javascript logic to open and close the hamburger menu when the button is clicked is usually handled by a script named "hbmenu.js" that is one of the built-in resource files that are part of Fossil.

The ≡ button for the hamburger menu is added to the menu bar by the following TH1 commands in the header.txt file, right before the menu bar links:

html "<a id='hbbtn' href='$home/sitemap'>&#9776;</a>"
builtin_request_js hbmenu.js

The hamburger button can be repositioned between the other menu links (but the drop-down menu is always left-aligned with the menu bar), or it can be removed by deleting the above statements. The "html" statement inserts the appropriate <a> for the hamburger menu button (some skins require something slightly different - for example the ardoise skins wants "<li><a>"). The "builtin_request_js hbmenu.js" asks Fossil to include the "hbmenu.js" resource files in the Fossil-generated footer.

The hbmenu.js script requires the following <div> element somewhere in your header, in which to build the hamburger menu.

<div id='hbdrop'></div>

Out of the box, the contents of the panel is populated with the Site Map, but only if the panel does not already contain any HTML elements (that is, not just comments, plain text or non-presentational white space). So the hamburger menu can be customized by replacing the empty <div id='hbdrop'></div> element with a menu structure knitted according to the following template:

<div id="hbdrop" data-anim-ms="400">
 <ul class="columns" style="column-width: 20em; column-count: auto">
  <!-- NEW GROUP WITH HEADING LINK -->
  <li>
   <a href="$home$index_page">Link: Home</a>
   <ul>
    <li><a href="$home/timeline">Link: Timeline</a></li>
    <li><a href="$home/dir?ci=tip">Link: File List</a></li>
   </ul>
  </li>
  <!-- NEW GROUP WITH HEADING TEXT -->
  <li>
   Heading Text
   <ul>
    <li><a href="$home/doc/trunk/www/customskin.md">Link: Theming</a></li>
    <li><a href="$home/doc/trunk/www/th1.md">Link: TH1 Scripts</a></li>
   </ul>
  </li>
  <!-- NEXT GROUP GOES HERE -->
 </ul>
</div>

The custom data-anim-ms attribute can be added to the panel element to direct the Javascript logic to override the default menu animation duration of 400 ms. A faster animation duration of 80-200 ms may be preferred for smaller menus. The animation is disabled by setting the attribute to "0".

TH1 Variables

Before expanding the TH1 within the header and footer, Fossil first initializes a number of TH1 variables to values that depend on repository settings and the specific page being generated.

All of the above are variables in the sense that either the header or the footer is free to change or erase them. But they should probably be treated as constants. New predefined values are likely to be added in future releases of Fossil.

Suggested Skin Customization Procedure

Developers are free, of course, to develop new skins using any method they want, but the following is a technique that has worked well in the past and can serve as a starting point for future work:

  1. Select a built-in skin that is closest to the desired look. Make copies of the css, footer, and header into files name "css.txt", "details.txt", "footer.txt", and "header.txt" in some temporary directory.

    If the Fossil source code is available, then these three files can be copied directly out of one of the subdirectories under skins. If sources are not easily at hand, then a copy/paste out of the CSS, footer, and header editing screens under the Admin menu will work just as well. The important point is that the three files be named exactly "css.txt", "footer.txt", and "header.txt" and that they all be in the same directory.

  2. Run the fossil ui command with an extra option "--skin SKINDIR" where SKINDIR is the name of the directory in which the three txt files were stored in step 1. This will bring up the Fossil website using the tree files in SKINDIR.

  3. Edit the *.txt files in SKINDIR. After making each small change, press Reload on the web browser to see the effect of that change. Iterate until the desired look is achieved.

  4. Copy/paste the resulting css.txt, details.txt, header.txt, and footer.txt files into the CSS, details, header, and footer configuration screens under the Admin/Skins menu.

See Also