# Skinning the Fossil Web Interface

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

<blockquote><table border=1 cellpadding=10><tbody>
<tr><td style='background-color:lightblue;text-align:center;'>Header</td></tr>
<tr><td style='background-color:lightgreen;text-align:center;'>
Fossil-Generated Content</td></tr>
<tr><td style='background-color:lightblue;text-align:center;'>Footer</td></tr>
<tr><td style='background-color:lightyellow;text-align:center;'>Javascript (optional)</td></tr>
</tbody></table></blockquote>

The default header looks something like this:

        <div class="header">
          <div class="title"><h1>$<project_name></h1>$<title></div>
          ... top banner and menu bar ...

The Fossil-generated content section looks like this:

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

And the footer looks like this:

        <div class="footer">
          ... skin-specific stuff here ...
        </div>
        <script nonce=$nonce>
          <th1>styleScript</th1>
        </script>

Notice that there are no `<html>` or `<head>` elements in the header,
nor is there an `</html>` closing tag in the footer.  Fossil generates
this material automatically unless it sees that you have provided your
own HTML document header within the skin’s Header section.

This design lets most users get the benefit of Fossil’s automatic HTML
document header, which takes care of quite a few different things for
you, while still allowing you to [override if at need](#headfoot).

When overriding the default document header, you might want to use some
of the [TH1 variables documented below](#vars) such as `$stylesheet_url`
to avoid hand-writing code that Fossil can generate for you.

The middle "content" section comprises 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 is otherwise fixed.  Hence it is the header, the footer,
and the CSS that determine the look of a repository.
We call the bundle of built-in CSS, header, and footer a "skin".


## <a name="builtin"></a>Built-in Skins

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](../../../help?cmd=ui) or
[fossil server](../../../help?cmd=server) commands to force that particular
instance of Fossil to use the specified built-in skin.


## <a name="sharing"></a>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](../../../help?cmd=configuration) 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.


## <a name="headfoot"></a>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 that before being prepended and appended to
the content, their text content is run through a
[TH1 interpreter](./th1.md) that might adjust the text as follows:

  *  All text within &lt;th1&gt;...&lt;/th1&gt; 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 of the form "$NAME" or "$&lt;NAME&gt;" is replaced with
     the value of the TH1 variable NAME.

Above, we saw the first few lines of a typical Fossil skin header:

        <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.

Fossil provides the HTML
document container tags `<html>`, `<head>`, and their inner content when
your skin’s header and footer don’t include them. This default header
declares the repository’s Content Security Policy (CSP) which is well
worth understanding, but since it is not strictly about skinning, we
cover that in [a separate document](./defcsp.md).


## <a name="menu"></a>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 contained in the optional Javascript part (js.txt)
of the default skin. Out of the box, the drop-down menu shows the [Site
Map](../../../sitemap), loaded by an AJAX request prior to the first display.

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='#'>&#9776;</a>"

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 statement (the Javascript logic detects this case and
remains idle, so it's not necessary to modify the default skin js.txt).

The following empty element at the bottom of the default skin header.txt serves
as the panel to hold the drop-down menu elements:

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

Out of the box, the contents of the panel is populated with the [Site
Map](../../../sitemap), 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"`.


## <a name="vars"></a>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.

   *   **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.

   *   **default_csp** - [Fossil’s default CSP](./defcsp.md) unless
       [overridden by custom TH1 code](./defcsp.md#th1). Useful within
       the skin for inserting the CSP into a `<meta>` tag within [a
       custom `<head>` element](#headfoot).

   *   **nonce** - The value of the cryptographic nonce for the request
       being processed.

   *   **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.


## <a name="procedure"></a>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](../../../help?cmd=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 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.

   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

*   [Customizing the Timeline Graph](customgraph.md)
