Every HTML page generated by Fossil has the following basic structure:
The header and footer control the "look" of Fossil pages. Those two sections can be customized separately for each repository to develop a new theme.
The header will normally look something like this:
<html> <head> ... </head> <body> ... top banner and menu bar ... <div class='content'>
And the footer will look something like this:
</div> ... bottom material ... </body> </html>
The <head> element in the header will normally reference the /style.css CSS file that Fossil stores internally. (The $stylesheet_url TH1 variable, described below, is useful for accomplishing this.)
The middle "content" section comprised the bulk of most pages and contains the actual Fossil-generated data that the user is interested in seeing. The text of this content section is not normally configurable. The content text can be styled using CSS, but it otherwise fixed. Hence it is the header and footer and the CSS that determine the look of a repository. We call the bundle of built-in CSS, header, and footer a "skin".
Fossil comes with several built-in skins. 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 four files, "css.txt", "details.txt", "footer.txt", and "header.txt", that describe the CSS, rendering options, footer, and header for that skin, respectively.
The skin of a repository can be changed to any of the built-in skins using the web interface by going to the /setup_skin web page (requires Admin privileges) and clicking the appropriate button. Or, the --skin command line option can be used for the fossil ui or fossil server commands to force that particular instance of Fossil to use the specified built-in skin.
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 new repository is initialized to the skin of the repository from which it was cloned.
Header And Footer Processing
The header.txt and footer.txt files of a skin are merely the HTML text of the header and footer. Except, before being prepended and appended to the content, the header and footer text are run through a TH1 interpreter that might adjust the text as follows:
All text within <th1>...</th1> is elided from the output and that text is instead run as a TH1 script. That TH1 script has the opportunity to insert new text in place of itself, or to inhibit or enable the output of subsequent text.
Text for the form "$NAME" or "$<NAME>" is replace with the value of the TH1 variable NAME.
For example, the following is the first few lines of a typical header file:
<html> <head> <base href="$baseurl/$current_page" /> <title>$<project_name>: $<title></title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$home/timeline.rss" /> <link rel="stylesheet" href="$stylesheet_url" type="text/css" media="screen" /> </head>
After variables are substituted by TH1, the final header text delivered to the web browser might look something like this:
<html> <head> <base href="https://www.fossil-scm.org/skin2/timeline" /> <title>Fossil: Timeline</title> <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/skin2/timeline.rss" /> <link rel="stylesheet" href="/skin2/style.css?default" type="text/css" media="screen" /> </head>
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 ≡ button for the hamburger menu is added to the menu bar by the following TH1 command in the default skin header.txt, right before the menu bar links:
html "<a id='hbbtn' href='#'>☰</a>"
The following empty element at the bottom of the default skin header.txt serves as the panel to hold the drop-down menu elements:
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
id='hbdrop'></div> element with a menu structure knitted according to the
<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>
data-anim-ms attribute can be added to the panel element to direct
A faster animation duration of 80-200 ms may be preferred for smaller menus. The
animation is disabled by setting the attribute to
Before expanding the TH1 within the header and footer, Fossil first initializes a number of TH1 variables to values that depend on respository settings and the specific page being generated.
project_name - The project_name variable is filled with the name of the project as configured under the Admin/Configuration menu.
project_description - The project_description variable is filled with the description of the project as configured under the Admin/Configuration menu.
title - The title variable holds the title of the page being generated.
The title variable is special in that it is deleted after the header script runs and before the footer script. This is necessary to avoid a conflict with a variable by the same name used in my ticket-screen scripts.
baseurl - The root of the URL namespace for this server.
secureurl - The same as $baseurl except that if the scheme is "http:" it is changed to "https:"
home - The $baseurl without the scheme and hostname. For example, if the $baseurl is "http://projectX.com/cgi-bin/fossil" then the $home will be just "/cgi-bin/fossil".
index_page - The landing page URI as specified by the Admin/Configuration setup page.
current_page - The name of the page currently being processed, without the leading "/" and without query parameters. Examples: "timeline", "doc/trunk/README.txt", "wiki".
csrf_token - A token used to prevent cross-site request forgery.
release_version - The release version of Fossil. Ex: "1.31"
manifest_version - A prefix on the check-in hash of the specific version of fossil that is running. Ex: "[47bb6432a1]"
manifest_date - The date of the source-code check-in for the version of fossil that is running.
compiler_name - The name and version of the compiler used to build the fossil executable.
login - This variable only exists if the user has logged in. The value is the username of the user.
stylesheet_url - A URL for the internal style-sheet maintained by Fossil.
log_image_url - A URL for the logo image for this project, as configured on the Admin/Logo page.
background_image_url - A URL for a background image for this project, as configured on the Admin/Logo page.
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:
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.
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.
Edit the four 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.
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.