|
4e6d36d…
|
wyoung
|
1 |
# Skinning the Fossil Web Interface |
|
4e6d36d…
|
wyoung
|
2 |
|
|
2698c16…
|
drh
|
3 |
The Fossil web interface comes with a pre-configured look and feel. The default |
|
2698c16…
|
drh
|
4 |
look and feel works fine in many situations. However, you may want to change |
|
2698c16…
|
drh
|
5 |
the look and feel (the "skin") of Fossil to better suite your own individual tastes. |
|
2698c16…
|
drh
|
6 |
This document provides background information to aid you in that task. |
|
2698c16…
|
drh
|
7 |
|
|
93cee1f…
|
wyoung
|
8 |
## <a id="builtin"></a>Built-in Skins |
|
2698c16…
|
drh
|
9 |
|
|
f08466d…
|
drh
|
10 |
Fossil comes with [multiple built-in skins](/skins). If the default skin does not |
|
2698c16…
|
drh
|
11 |
suite your tastes, perhaps one of the other built-in skins will work better. |
|
48a4be5…
|
drh
|
12 |
If nothing else, the built-in skins can serve as examples or templates that |
|
2698c16…
|
drh
|
13 |
you can use to develop your own custom skin. |
|
2698c16…
|
drh
|
14 |
|
|
2698c16…
|
drh
|
15 |
The sources to these built-ins can |
|
fd1282e…
|
drh
|
16 |
be found in the Fossil source tree under the skins/ folder. The |
|
2698c16…
|
drh
|
17 |
[skins/](/dir?ci=trunk&name=skins) |
|
e214a57…
|
drh
|
18 |
folder contains a separate subfolder for each built-in skin, with each |
|
2698c16…
|
drh
|
19 |
subfolders holding at least these five files: |
|
2698c16…
|
drh
|
20 |
|
|
2698c16…
|
drh
|
21 |
* css.txt |
|
2698c16…
|
drh
|
22 |
* details.txt |
|
2698c16…
|
drh
|
23 |
* footer.txt |
|
2698c16…
|
drh
|
24 |
* header.txt |
|
2698c16…
|
drh
|
25 |
* js.txt |
|
2698c16…
|
drh
|
26 |
|
|
2698c16…
|
drh
|
27 |
Try out the built-in skins by using the --skin option on the |
|
c64f28d…
|
drh
|
28 |
[fossil ui](/help/ui) or [fossil server](/help/server) commands. |
|
2698c16…
|
drh
|
29 |
|
|
93cee1f…
|
wyoung
|
30 |
## <a id="sharing"></a>Sharing Skins |
|
e214a57…
|
drh
|
31 |
|
|
e214a57…
|
drh
|
32 |
The skin of a repository is not part of the versioned state and does not |
|
4db19dc…
|
jan.nijtmans
|
33 |
"push" or "pull" like checked-in files. The skin is local to the |
|
e214a57…
|
drh
|
34 |
repository. However, skins can be shared between repositories using |
|
c64f28d…
|
drh
|
35 |
the [fossil config](/help/configuration) command. |
|
c397fe5…
|
drh
|
36 |
The "fossil config push skin" command will send the local skin to a remote |
|
e214a57…
|
drh
|
37 |
repository and the "fossil config pull skin" command will import a skin |
|
e214a57…
|
drh
|
38 |
from a remote repository. The "fossil config export skin FILENAME" |
|
e214a57…
|
drh
|
39 |
will export the skin for a repository into a file FILENAME. This file |
|
e214a57…
|
drh
|
40 |
can then be imported into a different repository using the |
|
e214a57…
|
drh
|
41 |
"fossil config import FILENAME" command. Unlike "push" and "pull", |
|
e214a57…
|
drh
|
42 |
the "export" and "import" commands are able to move skins between |
|
e214a57…
|
drh
|
43 |
repositories for different projects. So, for example, if you have a |
|
e214a57…
|
drh
|
44 |
group of related repositories, you can develop a skin for one of them, |
|
e214a57…
|
drh
|
45 |
then get a consistent look across all the repositories by exporting |
|
e214a57…
|
drh
|
46 |
the skin from the first repository and importing into all the others. |
|
e214a57…
|
drh
|
47 |
|
|
e214a57…
|
drh
|
48 |
The file generated by "fossil config export" could be checked into |
|
e214a57…
|
drh
|
49 |
one of your repositories and versioned, if desired. This will not |
|
e214a57…
|
drh
|
50 |
automatically change the skin when looking backwards in time, but it |
|
e214a57…
|
drh
|
51 |
will provide an historical record of what the skin used to be and |
|
e214a57…
|
drh
|
52 |
allow the historical look of the repositories to be recreated if |
|
e214a57…
|
drh
|
53 |
necessary. |
|
e214a57…
|
drh
|
54 |
|
|
2698c16…
|
drh
|
55 |
When cloning a repository, the skin of the new repository is initialized to |
|
e214a57…
|
drh
|
56 |
the skin of the repository from which it was cloned. |
|
e214a57…
|
drh
|
57 |
|
|
2698c16…
|
drh
|
58 |
# Structure Of A Fossil Web Page |
|
c397fe5…
|
drh
|
59 |
|
|
2698c16…
|
drh
|
60 |
Every HTML page generated by Fossil has the same basic structure: |
|
4e6d36d…
|
wyoung
|
61 |
|
|
8a1ba49…
|
wyoung
|
62 |
| Fossil-Generated HTML Header | |
|
b3f449e…
|
wyoung
|
63 |
| Skin Header | |
|
8a1ba49…
|
wyoung
|
64 |
| Fossil-Generated Content | |
|
b3f449e…
|
wyoung
|
65 |
| Skin Footer | |
|
8a1ba49…
|
wyoung
|
66 |
| Fossil-Generated HTML Footer | |
|
8a1ba49…
|
wyoung
|
67 |
|
|
b3f449e…
|
wyoung
|
68 |
By default, Fossil starts every generated HTML page with this: |
|
8a1ba49…
|
wyoung
|
69 |
|
|
8a1ba49…
|
wyoung
|
70 |
<html> |
|
8a1ba49…
|
wyoung
|
71 |
<head> |
|
8a1ba49…
|
wyoung
|
72 |
<base href="..."> |
|
8a1ba49…
|
wyoung
|
73 |
<meta http-equiv="Content-Security-Policy" content="...."> |
|
8a1ba49…
|
wyoung
|
74 |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
8a1ba49…
|
wyoung
|
75 |
<title>....</title> |
|
8a1ba49…
|
wyoung
|
76 |
<link rel="stylesheet" href="..." type="text/css"> |
|
8a1ba49…
|
wyoung
|
77 |
</head> |
|
8a1ba49…
|
wyoung
|
78 |
<body class="FEATURE"> |
|
8a1ba49…
|
wyoung
|
79 |
|
|
b3f449e…
|
wyoung
|
80 |
Fossil used to require a static version of this in every skin’s Header |
|
b3f449e…
|
wyoung
|
81 |
area, but over time, we have found good cause to generate multiple |
|
b3f449e…
|
wyoung
|
82 |
elements at runtime. |
|
b3f449e…
|
wyoung
|
83 |
|
|
b3f449e…
|
wyoung
|
84 |
One such is the `FEATURE` element, being either the top-level HTTP |
|
b3f449e…
|
wyoung
|
85 |
request routing element (e.g. `doc`) or an aggregate feature class that |
|
b3f449e…
|
wyoung
|
86 |
groups multiple routes under a single name. A prime example is `forum`, |
|
b3f449e…
|
wyoung
|
87 |
which groups the `/forummain`, `/forumpost`, and `/forume2` routes, |
|
b3f449e…
|
wyoung
|
88 |
allowing per-feature CSS. For instance, to style `<blockquote>` tags |
|
b3f449e…
|
wyoung
|
89 |
specially for forum posts written in Markdown, leaving all other block |
|
b3f449e…
|
wyoung
|
90 |
quotes alone, you could say: |
|
b3f449e…
|
wyoung
|
91 |
|
|
b6fa99e…
|
wyoung
|
92 |
body.forum div.markdown blockquote { |
|
b6fa99e…
|
wyoung
|
93 |
margin-left: 10px; |
|
b6fa99e…
|
wyoung
|
94 |
} |
|
b3f449e…
|
wyoung
|
95 |
|
|
b3f449e…
|
wyoung
|
96 |
You can [override this generated HTML header](#override) by including a |
|
b3f449e…
|
wyoung
|
97 |
“`<body>`” tag somewhere in the Header area of the skin, but it is |
|
b3f449e…
|
wyoung
|
98 |
almost always best to limit a custom skin’s Header section to something |
|
b3f449e…
|
wyoung
|
99 |
like this: |
|
b3f449e…
|
wyoung
|
100 |
|
|
b3f449e…
|
wyoung
|
101 |
<div class="sidebar" id="version-2.24">Prior to Fossil 2.24, we used |
|
b3f449e…
|
wyoung
|
102 |
generic `<div>` elements to mark up these sections of the header, but we |
|
b3f449e…
|
wyoung
|
103 |
switched to these semantic tag names to give browser accessibility |
|
b3f449e…
|
wyoung
|
104 |
features more freedom to do intelligent things with the page content. |
|
b3f449e…
|
wyoung
|
105 |
Those who made custom skins based on the old way of doing things will |
|
b3f449e…
|
wyoung
|
106 |
need to track this change when upgrading, else the corresponding CSS |
|
b3f449e…
|
wyoung
|
107 |
will mistarget the page header elements. Also, if you’re using Fossil’s |
|
b3f449e…
|
wyoung
|
108 |
chat feature, failing to track this change will cause it to miscalculate |
|
b3f449e…
|
wyoung
|
109 |
the message area size, resulting in double scrollbars. Simply diffing |
|
b3f449e…
|
wyoung
|
110 |
your custom header in the skin editor against the stock version should |
|
b3f449e…
|
wyoung
|
111 |
be sufficient to show what you need to change.</div> |
|
b3f449e…
|
wyoung
|
112 |
|
|
b3f449e…
|
wyoung
|
113 |
|
|
b3f449e…
|
wyoung
|
114 |
<header> |
|
b3f449e…
|
wyoung
|
115 |
... |
|
b3f449e…
|
wyoung
|
116 |
</header> |
|
b3f449e…
|
wyoung
|
117 |
<nav class="mainmenu" title="Main Menu"> |
|
b3f449e…
|
wyoung
|
118 |
... |
|
b3f449e…
|
wyoung
|
119 |
</nav> |
|
b3f449e…
|
wyoung
|
120 |
<nav id="hbdrop" class="hbdrop" title="sitemap"></nav> |
|
b3f449e…
|
wyoung
|
121 |
|
|
b3f449e…
|
wyoung
|
122 |
See the stock skins’ headers for ideas of what to put in place of the |
|
b3f449e…
|
wyoung
|
123 |
ellipses. |
|
b3f449e…
|
wyoung
|
124 |
|
|
b3f449e…
|
wyoung
|
125 |
The Fossil-generated Content section immediately follows this Header. |
|
b3f449e…
|
wyoung
|
126 |
It will look like this: |
|
8a1ba49…
|
wyoung
|
127 |
|
|
8a1ba49…
|
wyoung
|
128 |
<div class="content"> |
|
8a1ba49…
|
wyoung
|
129 |
... Fossil-generated content here ... |
|
8a1ba49…
|
wyoung
|
130 |
</div> |
|
8a1ba49…
|
wyoung
|
131 |
|
|
b3f449e…
|
wyoung
|
132 |
After the Content is the custom Skin Footer section which should |
|
9e871e0…
|
stephan
|
133 |
follow this template: |
|
9e871e0…
|
stephan
|
134 |
|
|
b3f449e…
|
wyoung
|
135 |
<footer> |
|
8a1ba49…
|
wyoung
|
136 |
... skin-specific stuff here ... |
|
b3f449e…
|
wyoung
|
137 |
</footer> |
|
48a4be5…
|
drh
|
138 |
|
|
b3f449e…
|
wyoung
|
139 |
As with the `<header>` change called out above, this, too, is a breaking |
|
b3f449e…
|
wyoung
|
140 |
change in Fossil 2.24. |
|
2698c16…
|
drh
|
141 |
|
|
2698c16…
|
drh
|
142 |
Finally, Fossil always adds its own footer (unless overridden) |
|
2698c16…
|
drh
|
143 |
to close out the generated HTML: |
|
2698c16…
|
drh
|
144 |
|
|
8a1ba49…
|
wyoung
|
145 |
</body> |
|
8a1ba49…
|
wyoung
|
146 |
</html> |
|
2698c16…
|
drh
|
147 |
|
|
93cee1f…
|
wyoung
|
148 |
## <a id="mainmenu"></a>Changing the Main Menu Contents |
|
da22910…
|
wyoung
|
149 |
|
|
ad47a44…
|
wyoung
|
150 |
The actual text content of the skin’s main menu is not |
|
ad47a44…
|
wyoung
|
151 |
part of the skin proper if you’re using one of the stock skins. |
|
da22910…
|
wyoung
|
152 |
If you look at the Header section of the skin, you’ll find a |
|
da22910…
|
wyoung
|
153 |
`<div class="mainmenu">` element whose contents are set by a short |
|
da22910…
|
wyoung
|
154 |
[TH1](./th1.md) script from the contents of the **Main Menu** section of |
|
da22910…
|
wyoung
|
155 |
the Setup → Configuration screen. |
|
da22910…
|
wyoung
|
156 |
|
|
da22910…
|
wyoung
|
157 |
This feature allows the main menu contents to stay the same across |
|
da22910…
|
wyoung
|
158 |
different skins, so you no longer have to reapply menu customizations |
|
da22910…
|
wyoung
|
159 |
when trying different skins. |
|
da22910…
|
wyoung
|
160 |
|
|
da22910…
|
wyoung
|
161 |
See the [`capexpr`](./th1.md#capexpr) section of the TH1 docs for help |
|
da22910…
|
wyoung
|
162 |
on interpreting the default contents of this block. |
|
da22910…
|
wyoung
|
163 |
|
|
da22910…
|
wyoung
|
164 |
|
|
93cee1f…
|
wyoung
|
165 |
## <a id="override"></a>Overriding the HTML Header and Footer |
|
fd1282e…
|
drh
|
166 |
|
|
fd1282e…
|
drh
|
167 |
Notice that the `<html>`, `<head>`, and opening `<body>` |
|
2698c16…
|
drh
|
168 |
elements at the beginning of the document, |
|
2698c16…
|
drh
|
169 |
and the closing `</body>` and `</html>` elements at the end are automatically |
|
2698c16…
|
drh
|
170 |
generated by Fossil. This is recommended. |
|
2698c16…
|
drh
|
171 |
|
|
2698c16…
|
drh
|
172 |
However, for maximum design flexibility, Fossil allows those elements to be |
|
b3f449e…
|
wyoung
|
173 |
supplied as part of the configurable Skin Header and Skin Footer. |
|
b3f449e…
|
wyoung
|
174 |
If the Skin Header contains the text "`<body`", then Fossil assumes that |
|
b3f449e…
|
wyoung
|
175 |
the Skin Header and Skin Footer will handle all of the `<html>`, |
|
2698c16…
|
drh
|
176 |
`<head>`, and `<body>` text itself, and the Fossil-generated header and |
|
2698c16…
|
drh
|
177 |
footer will be blank. |
|
2698c16…
|
drh
|
178 |
|
|
2698c16…
|
drh
|
179 |
When overriding the HTML Header in this way, you will probably want to use some |
|
2698c16…
|
drh
|
180 |
of the [TH1 variables documented below](#vars) such as `$stylesheet_url` |
|
2698c16…
|
drh
|
181 |
to avoid hand-writing code that Fossil can generate for you. |
|
2698c16…
|
drh
|
182 |
|
|
2698c16…
|
drh
|
183 |
# Designing, Debugging, and Installing A Custom Skin |
|
2698c16…
|
drh
|
184 |
|
|
2698c16…
|
drh
|
185 |
It is possible to develop a new skin from scratch. But a better and easier |
|
2698c16…
|
drh
|
186 |
approach is to use one of the existing built-in skins as a baseline and |
|
2698c16…
|
drh
|
187 |
make incremental modifications, testing after each step, to obtain the |
|
2698c16…
|
drh
|
188 |
desired result. |
|
2698c16…
|
drh
|
189 |
|
|
2698c16…
|
drh
|
190 |
The skin is controlled by five files: |
|
2698c16…
|
drh
|
191 |
|
|
8a1ba49…
|
wyoung
|
192 |
<dl> |
|
1fd407f…
|
wyoung
|
193 |
<dt><b>css.txt</b></dt> |
|
2698c16…
|
drh
|
194 |
|
|
1fd407f…
|
wyoung
|
195 |
<dd>The css.txt file is the text of the CSS for Fossil. |
|
e755561…
|
danield
|
196 |
Fossil might add additional CSS elements after |
|
2698c16…
|
drh
|
197 |
the css.txt file, if it sees that the css.txt omits some |
|
2698c16…
|
drh
|
198 |
CSS components that Fossil needs. But for the most part, |
|
2698c16…
|
drh
|
199 |
the content of the css.txt is the CSS for the page.</dd> |
|
2698c16…
|
drh
|
200 |
|
|
1fd407f…
|
wyoung
|
201 |
<dt><b>details.txt</b><dt> |
|
2698c16…
|
drh
|
202 |
|
|
1fd407f…
|
wyoung
|
203 |
<dd>The details.txt file is short list of settings that control |
|
2698c16…
|
drh
|
204 |
the look and feel, mostly of the timeline. The default |
|
2698c16…
|
drh
|
205 |
details.txt file looks like this: |
|
2698c16…
|
drh
|
206 |
|
|
8a1ba49…
|
wyoung
|
207 |
<pre> |
|
48a4be5…
|
drh
|
208 |
pikchr-background: "" |
|
48a4be5…
|
drh
|
209 |
pikchr-fontscale: "" |
|
75668f4…
|
drh
|
210 |
pikchr-foreground: "" |
|
48a4be5…
|
drh
|
211 |
pikchr-scale: "" |
|
2698c16…
|
drh
|
212 |
timeline-arrowheads: 1 |
|
2698c16…
|
drh
|
213 |
timeline-circle-nodes: 1 |
|
2698c16…
|
drh
|
214 |
timeline-color-graph-lines: 1 |
|
2698c16…
|
drh
|
215 |
white-foreground: 0 |
|
8a1ba49…
|
wyoung
|
216 |
</pre> |
|
2698c16…
|
drh
|
217 |
|
|
75668f4…
|
drh
|
218 |
The three "timeline-" settings in details.txt control the appearance |
|
2698c16…
|
drh
|
219 |
of certain aspects of the timeline graph. The number on the |
|
2698c16…
|
drh
|
220 |
right is a boolean - "1" to activate the feature and "0" to |
|
2698c16…
|
drh
|
221 |
disable it. The "white-foreground:" setting should be set to |
|
2698c16…
|
drh
|
222 |
"1" if the page color has light-color text on a darker background, |
|
75668f4…
|
drh
|
223 |
and "0" if the page has dark text on a light-colored background. |
|
1fd407f…
|
wyoung
|
224 |
|
|
ad47a44…
|
wyoung
|
225 |
If the "pikchr-foreground" setting |
|
9650c73…
|
wyoung
|
226 |
is defined and is not an empty string then it specifies a |
|
75668f4…
|
drh
|
227 |
foreground color to use for [pikchr diagrams](./pikchr.md). The |
|
75668f4…
|
drh
|
228 |
default pikchr foreground color is black, or white if the |
|
48a4be5…
|
drh
|
229 |
"white-foreground" boolean is set. The "pikchr-background" |
|
48a4be5…
|
drh
|
230 |
settings does the same for the pikchr diagram background color. |
|
48a4be5…
|
drh
|
231 |
If the "pikchr-fontscale" and "pikchr-scale" values are not |
|
48a4be5…
|
drh
|
232 |
empty strings, then they should be floating point values (close |
|
48a4be5…
|
drh
|
233 |
to 1.0) that specify relative scaling of the fonts in pikchr |
|
48a4be5…
|
drh
|
234 |
diagrams and other elements of the diagrams, respectively. |
|
75668f4…
|
drh
|
235 |
</dd> |
|
2698c16…
|
drh
|
236 |
|
|
1fd407f…
|
wyoung
|
237 |
<dt><b>footer.txt</b> and <b>header.txt</b></dt> |
|
75668f4…
|
drh
|
238 |
|
|
b3f449e…
|
wyoung
|
239 |
<dd>The footer.txt and header.txt files contain the Skin Footer |
|
b3f449e…
|
wyoung
|
240 |
and Skin Header respectively. Of these, the Skin Header is |
|
2698c16…
|
drh
|
241 |
the most important, as it contains the markup used to generate |
|
2698c16…
|
drh
|
242 |
the banner and menu bar for each page. |
|
2698c16…
|
drh
|
243 |
|
|
1fd407f…
|
wyoung
|
244 |
Both the footer.txt and header.txt file are |
|
fd1282e…
|
drh
|
245 |
[processed using TH1](#headfoot) prior to being output as |
|
2698c16…
|
drh
|
246 |
part of the overall web page.</dd> |
|
2698c16…
|
drh
|
247 |
|
|
1fd407f…
|
wyoung
|
248 |
<dt><b>js.txt</b></dt> |
|
2698c16…
|
drh
|
249 |
|
|
1fd407f…
|
wyoung
|
250 |
<dd>The js.txt file is optional. It is intended to be javascript. |
|
3fec387…
|
drh
|
251 |
The complete text of this javascript might be inserted into |
|
b3f449e…
|
wyoung
|
252 |
the Skin Footer, after being processed using TH1, using |
|
48a4be5…
|
drh
|
253 |
code like the following in the "footer.txt" file: |
|
2698c16…
|
drh
|
254 |
|
|
8a1ba49…
|
wyoung
|
255 |
<pre> |
|
2698c16…
|
drh
|
256 |
<script nonce="$nonce"> |
|
2698c16…
|
drh
|
257 |
<th1>styleScript</th1> |
|
2698c16…
|
drh
|
258 |
</script> |
|
8a1ba49…
|
wyoung
|
259 |
</pre> |
|
2698c16…
|
drh
|
260 |
|
|
1fd407f…
|
wyoung
|
261 |
The js.txt file was originally used to insert javascript |
|
48a4be5…
|
drh
|
262 |
that controls the hamburger menu in the default skin. More |
|
48a4be5…
|
drh
|
263 |
recently, the javascript for the hamburger menu was moved into |
|
48a4be5…
|
drh
|
264 |
a separate built-in file. Skins that use the hamburger menu |
|
48a4be5…
|
drh
|
265 |
typically cause the javascript to be loaded by including the |
|
48a4be5…
|
drh
|
266 |
following TH1 code in the "header.txt" file: |
|
48a4be5…
|
drh
|
267 |
|
|
8a1ba49…
|
wyoung
|
268 |
<pre> |
|
48a4be5…
|
drh
|
269 |
<th1>builtin_request_js hbmenu.js</th1> |
|
8a1ba49…
|
wyoung
|
270 |
</pre> |
|
48a4be5…
|
drh
|
271 |
|
|
ad47a44…
|
wyoung
|
272 |
The difference between `styleScript` and `builtin_request_js` |
|
ad47a44…
|
wyoung
|
273 |
is that the `styleScript` command interprets the file |
|
48a4be5…
|
drh
|
274 |
using TH1 and injects the content directly into the output |
|
ad47a44…
|
wyoung
|
275 |
stream, whereas the `builtin_request_js` command inserts the |
|
ad47a44…
|
wyoung
|
276 |
Javascript verbatim and does so at some unspecified future time |
|
ad47a44…
|
wyoung
|
277 |
down inside the Fossil-generated footer. |
|
ad47a44…
|
wyoung
|
278 |
You can use either |
|
ad47a44…
|
wyoung
|
279 |
approach in custom skins that you create. |
|
48a4be5…
|
drh
|
280 |
|
|
48a4be5…
|
drh
|
281 |
Note that the "js.txt" file is *not* automatically inserted into |
|
48a4be5…
|
drh
|
282 |
the generate HTML for a page. You, the skin designer, must |
|
48a4be5…
|
drh
|
283 |
cause the javascript to be inserted by issuing appropriate |
|
48a4be5…
|
drh
|
284 |
TH1 commands in the "header.txt" or "footer.txt" files.</dd> |
|
8a1ba49…
|
wyoung
|
285 |
</dl> |
|
2698c16…
|
drh
|
286 |
|
|
2698c16…
|
drh
|
287 |
Developing a new skin is simply a matter of creating appropriate |
|
2698c16…
|
drh
|
288 |
versions of these five control files. |
|
2698c16…
|
drh
|
289 |
|
|
2698c16…
|
drh
|
290 |
### Skin Development Using The Web Interface |
|
2698c16…
|
drh
|
291 |
|
|
2698c16…
|
drh
|
292 |
Users with admin privileges can use the Admin/Skin configuration page |
|
2698c16…
|
drh
|
293 |
on the web interface to develop a new skin. The development of a new |
|
2698c16…
|
drh
|
294 |
skin occurs without disrupting the existing skin. So you can work on |
|
7874664…
|
drh
|
295 |
a new skin for a Fossil instance while the existing skin is still in |
|
2698c16…
|
drh
|
296 |
active use. |
|
2698c16…
|
drh
|
297 |
|
|
7874664…
|
drh
|
298 |
The new skin is a "draft" skin. You initialize one of 9 draft skins |
|
2698c16…
|
drh
|
299 |
to either the current skin or to one of the built-in skins. Then |
|
2698c16…
|
drh
|
300 |
use forms to edit the 5 control files described above. The new |
|
2698c16…
|
drh
|
301 |
skin can be tested after each edit. Finally, once the new skin is |
|
2698c16…
|
drh
|
302 |
working as desired, the draft skin is "published" and becomes the |
|
2698c16…
|
drh
|
303 |
new live skin that most users see. |
|
2698c16…
|
drh
|
304 |
|
|
2698c16…
|
drh
|
305 |
### Skin Development Using A Local Text Editor |
|
2698c16…
|
drh
|
306 |
|
|
2698c16…
|
drh
|
307 |
An alternative approach is to copy the five control files for your |
|
2698c16…
|
drh
|
308 |
baseline skin into a temporary working directory (here called |
|
c64f28d…
|
drh
|
309 |
"./newskin") and then launch the [fossil ui](/help/ui) command |
|
2698c16…
|
drh
|
310 |
with the "--skin ./newskin" option. If the argument to the --skin |
|
2698c16…
|
drh
|
311 |
option contains a "/" character, then the five control files are |
|
2698c16…
|
drh
|
312 |
read out of the directory named. You can then edit the control |
|
2698c16…
|
drh
|
313 |
files in the ./newskin folder using you favorite text editor, and |
|
2698c16…
|
drh
|
314 |
press "Reload" on your browser to see the effects. |
|
37e2705…
|
stephan
|
315 |
|
|
48a4be5…
|
drh
|
316 |
|
|
48a4be5…
|
drh
|
317 |
### Disabling The Web Browser Cache During Development |
|
48a4be5…
|
drh
|
318 |
|
|
48a4be5…
|
drh
|
319 |
Fossil is aggressive about asking the web browser to cache |
|
48a4be5…
|
drh
|
320 |
resources. While developing a new skin, it is often helpful to |
|
48a4be5…
|
drh
|
321 |
put your web browser into developer mode and disable the cache. |
|
48a4be5…
|
drh
|
322 |
If you fail to do this, then you might make some change to your skin |
|
48a4be5…
|
drh
|
323 |
under development and press "Reload" only to find that the display |
|
48a4be5…
|
drh
|
324 |
did not change. After you have finished work your skin, the |
|
48a4be5…
|
drh
|
325 |
caches should synchronize with your new design and you can reactivate |
|
48a4be5…
|
drh
|
326 |
your web browser's cache and take it out of developer mode. |
|
48a4be5…
|
drh
|
327 |
|
|
93cee1f…
|
wyoung
|
328 |
## <a id="headfoot"></a>Header and Footer Processing |
|
2698c16…
|
drh
|
329 |
|
|
2698c16…
|
drh
|
330 |
The `header.txt` and `footer.txt` control files of a skin are the HTML text |
|
b3f449e…
|
wyoung
|
331 |
of the Skin Header and Skin Footer, except that before being inserted |
|
2698c16…
|
drh
|
332 |
into the output stream, the text is run through a |
|
c397fe5…
|
drh
|
333 |
[TH1 interpreter](./th1.md) that might adjust the text as follows: |
|
c397fe5…
|
drh
|
334 |
|
|
2698c16…
|
drh
|
335 |
* All text within <th1>...</th1> is omitted from the |
|
2698c16…
|
drh
|
336 |
output and is instead run as a TH1 script. That TH1 |
|
c397fe5…
|
drh
|
337 |
script has the opportunity to insert new text in place of itself, |
|
c397fe5…
|
drh
|
338 |
or to inhibit or enable the output of subsequent text. |
|
c397fe5…
|
drh
|
339 |
|
|
9044fd2…
|
wyoung
|
340 |
* Text of the form "$NAME" or "$<NAME>" is replaced with |
|
2a02993…
|
florian
|
341 |
the value of the TH1 variable NAME. See the [TH1 Variables](#vars) |
|
2a02993…
|
florian
|
342 |
section for more information on the two possible variable formats. |
|
9044fd2…
|
wyoung
|
343 |
|
|
b3f449e…
|
wyoung
|
344 |
For example, first few lines of a typical Skin Header will look |
|
2698c16…
|
drh
|
345 |
like this: |
|
9044fd2…
|
wyoung
|
346 |
|
|
8a1ba49…
|
wyoung
|
347 |
<div class="header"> |
|
8a1ba49…
|
wyoung
|
348 |
<div class="title"><h1>$<project_name></h1>$<title>/div> |
|
9044fd2…
|
wyoung
|
349 |
|
|
9044fd2…
|
wyoung
|
350 |
After variables are substituted by TH1, that will look more like this: |
|
9044fd2…
|
wyoung
|
351 |
|
|
8a1ba49…
|
wyoung
|
352 |
<div class="header"> |
|
8a1ba49…
|
wyoung
|
353 |
<div class="title"><h1>Project Name</h1>Page Title</div> |
|
9044fd2…
|
wyoung
|
354 |
|
|
9044fd2…
|
wyoung
|
355 |
As you can see, two TH1 variable substitutions were done. |
|
e214a57…
|
drh
|
356 |
|
|
e214a57…
|
drh
|
357 |
The same TH1 interpreter is used for both the header and the footer |
|
e214a57…
|
drh
|
358 |
and for all scripts contained within them both. Hence, any global |
|
e214a57…
|
drh
|
359 |
TH1 variables that are set by the header are available to the footer. |
|
e214a57…
|
drh
|
360 |
|
|
93cee1f…
|
wyoung
|
361 |
## <a id="menu"></a>Customizing the ≡ Hamburger Menu |
|
724a9b8…
|
drh
|
362 |
|
|
724a9b8…
|
drh
|
363 |
The menu bar of the default skin has an entry to open a drop-down menu with |
|
724a9b8…
|
drh
|
364 |
additional navigation links, represented by the ≡ button (hence the name |
|
724a9b8…
|
drh
|
365 |
"hamburger menu"). The Javascript logic to open and close the hamburger menu |
|
48a4be5…
|
drh
|
366 |
when the button is clicked is usually handled by a script named |
|
3fec387…
|
drh
|
367 |
"hbmenu.js" that is one of the [built-in resource files](/test-builtin-files) |
|
48a4be5…
|
drh
|
368 |
that are part of Fossil. |
|
724a9b8…
|
drh
|
369 |
|
|
724a9b8…
|
drh
|
370 |
The ≡ button for the hamburger menu is added to the menu bar by the following |
|
48a4be5…
|
drh
|
371 |
TH1 commands in the `header.txt` file, right before the menu bar links: |
|
724a9b8…
|
drh
|
372 |
|
|
8a1ba49…
|
wyoung
|
373 |
html "<a id='hbbtn' href='$home/sitemap'>☰</a>" |
|
8a1ba49…
|
wyoung
|
374 |
builtin_request_js hbmenu.js |
|
724a9b8…
|
drh
|
375 |
|
|
724a9b8…
|
drh
|
376 |
The hamburger button can be repositioned between the other menu links (but the |
|
724a9b8…
|
drh
|
377 |
drop-down menu is always left-aligned with the menu bar), or it can be removed |
|
48a4be5…
|
drh
|
378 |
by deleting the above statements. The "html" statement inserts the appropriate |
|
48a4be5…
|
drh
|
379 |
`<a>` for the hamburger menu button (some skins require something slightly |
|
48a4be5…
|
drh
|
380 |
different - for example the ardoise skins wants "`<li><a>`"). The |
|
48a4be5…
|
drh
|
381 |
"builtin_request_js hbmenu.js" asks Fossil to include the "hbmenu.js" |
|
48a4be5…
|
drh
|
382 |
resource files in the Fossil-generated footer. |
|
724a9b8…
|
drh
|
383 |
|
|
48a4be5…
|
drh
|
384 |
The hbmenu.js script requires |
|
48a4be5…
|
drh
|
385 |
the following `<div>` element somewhere in your header, in which to build |
|
48a4be5…
|
drh
|
386 |
the hamburger menu. |
|
724a9b8…
|
drh
|
387 |
|
|
8a1ba49…
|
wyoung
|
388 |
<div id='hbdrop'></div> |
|
724a9b8…
|
drh
|
389 |
|
|
724a9b8…
|
drh
|
390 |
Out of the box, the contents of the panel is populated with the [Site |
|
48a4be5…
|
drh
|
391 |
Map](/sitemap), but only if the panel does not already contain any HTML |
|
724a9b8…
|
drh
|
392 |
elements (that is, not just comments, plain text or non-presentational white |
|
724a9b8…
|
drh
|
393 |
space). So the hamburger menu can be customized by replacing the empty `<div |
|
724a9b8…
|
drh
|
394 |
id='hbdrop'></div>` element with a menu structure knitted according to the |
|
724a9b8…
|
drh
|
395 |
following template: |
|
724a9b8…
|
drh
|
396 |
|
|
8a1ba49…
|
wyoung
|
397 |
<div id="hbdrop" data-anim-ms="400"> |
|
8a1ba49…
|
wyoung
|
398 |
<ul class="columns" style="column-width: 20em; column-count: auto"> |
|
8a1ba49…
|
wyoung
|
399 |
<!-- NEW GROUP WITH HEADING LINK --> |
|
8a1ba49…
|
wyoung
|
400 |
<li> |
|
8a1ba49…
|
wyoung
|
401 |
<a href="$home$index_page">Link: Home</a> |
|
8a1ba49…
|
wyoung
|
402 |
<ul> |
|
8a1ba49…
|
wyoung
|
403 |
<li><a href="$home/timeline">Link: Timeline</a></li> |
|
8a1ba49…
|
wyoung
|
404 |
<li><a href="$home/dir?ci=tip">Link: File List</a></li> |
|
8a1ba49…
|
wyoung
|
405 |
</ul> |
|
8a1ba49…
|
wyoung
|
406 |
</li> |
|
8a1ba49…
|
wyoung
|
407 |
<!-- NEW GROUP WITH HEADING TEXT --> |
|
8a1ba49…
|
wyoung
|
408 |
<li> |
|
8a1ba49…
|
wyoung
|
409 |
Heading Text |
|
8a1ba49…
|
wyoung
|
410 |
<ul> |
|
8a1ba49…
|
wyoung
|
411 |
<li><a href="$home/doc/trunk/www/customskin.md">Link: Theming</a></li> |
|
8a1ba49…
|
wyoung
|
412 |
<li><a href="$home/doc/trunk/www/th1.md">Link: TH1 Scripts</a></li> |
|
8a1ba49…
|
wyoung
|
413 |
</ul> |
|
8a1ba49…
|
wyoung
|
414 |
</li> |
|
8a1ba49…
|
wyoung
|
415 |
<!-- NEXT GROUP GOES HERE --> |
|
8a1ba49…
|
wyoung
|
416 |
</ul> |
|
8a1ba49…
|
wyoung
|
417 |
</div> |
|
724a9b8…
|
drh
|
418 |
|
|
724a9b8…
|
drh
|
419 |
The custom `data-anim-ms` attribute can be added to the panel element to direct |
|
724a9b8…
|
drh
|
420 |
the Javascript logic to override the default menu animation duration of 400 ms. |
|
724a9b8…
|
drh
|
421 |
A faster animation duration of 80-200 ms may be preferred for smaller menus. The |
|
724a9b8…
|
drh
|
422 |
animation is disabled by setting the attribute to `"0"`. |
|
724a9b8…
|
drh
|
423 |
|
|
4e6d36d…
|
wyoung
|
424 |
|
|
93cee1f…
|
wyoung
|
425 |
## <a id="vars"></a>TH1 Variables |
|
e214a57…
|
drh
|
426 |
|
|
e214a57…
|
drh
|
427 |
Before expanding the TH1 within the header and footer, Fossil first |
|
4db19dc…
|
jan.nijtmans
|
428 |
initializes a number of TH1 variables to values that depend on |
|
79c2cb0…
|
wyoung
|
429 |
repository settings and the specific page being generated. |
|
79c2cb0…
|
wyoung
|
430 |
|
|
2a02993…
|
florian
|
431 |
Variables holding text that is loaded from "external, potentially untrusted" |
|
2a02993…
|
florian
|
432 |
sources (including the repository settings) are treated as [tainted strings] |
|
2a02993…
|
florian
|
433 |
(./th1.md#taint) and must be noted in the `$<NAME>` form, instead of `$NAME`, |
|
12036a3…
|
florian
|
434 |
or they may trigger an error (see the linked document for details). The |
|
12036a3…
|
florian
|
435 |
`$<NAME>` form corresponds to the TH1 statement `puts [ htmlize "$NAME" ]`, |
|
12036a3…
|
florian
|
436 |
where the [htmlize](./th1.md#htmlize) function escapes the tainted string, |
|
12036a3…
|
florian
|
437 |
making it safe for output in HTML code. |
|
12036a3…
|
florian
|
438 |
|
|
2a02993…
|
florian
|
439 |
|
|
3b505e6…
|
wyoung
|
440 |
* **`project_name`** - The project_name variable is filled with the |
|
e214a57…
|
drh
|
441 |
name of the project as configured under the Admin/Configuration |
|
2a02993…
|
florian
|
442 |
menu. This is a [tainted string](./th1.md#taint) variable and must |
|
2a02993…
|
florian
|
443 |
be used as `$<project_name>`. |
|
cd219d3…
|
mistachkin
|
444 |
|
|
3b505e6…
|
wyoung
|
445 |
* **`project_description`** - The project_description variable is |
|
cd219d3…
|
mistachkin
|
446 |
filled with the description of the project as configured under |
|
2a02993…
|
florian
|
447 |
the Admin/Configuration menu. This is a [tainted string] |
|
2a02993…
|
florian
|
448 |
(./th1.md#taint) variable and must be used as `$<project_description>`. |
|
12036a3…
|
florian
|
449 |
|
|
12036a3…
|
florian
|
450 |
* **`mainmenu`** - The mainmenu variable contains a TCL list with the main |
|
12036a3…
|
florian
|
451 |
menu entries. See the [mainmenu](/help/mainmenu) setting for details. |
|
c397fe5…
|
drh
|
452 |
|
|
3b505e6…
|
wyoung
|
453 |
* **`title`** - The title variable holds the title of the page being |
|
c397fe5…
|
drh
|
454 |
generated. |
|
e214a57…
|
drh
|
455 |
|
|
c397fe5…
|
drh
|
456 |
The title variable is special in that it is deleted after |
|
e214a57…
|
drh
|
457 |
the header script runs and before the footer script. This is |
|
e214a57…
|
drh
|
458 |
necessary to avoid a conflict with a variable by the same name used |
|
e214a57…
|
drh
|
459 |
in my ticket-screen scripts. |
|
e214a57…
|
drh
|
460 |
|
|
3b505e6…
|
wyoung
|
461 |
* **`baseurl`** - The root of the URL namespace for this server. |
|
e214a57…
|
drh
|
462 |
|
|
3b505e6…
|
wyoung
|
463 |
* **`secureurl`** - The same as $baseurl except that if the scheme is |
|
e214a57…
|
drh
|
464 |
"http:" it is changed to "https:" |
|
e214a57…
|
drh
|
465 |
|
|
3b505e6…
|
wyoung
|
466 |
* **`home`** - The $baseurl without the scheme and hostname. For example, |
|
e214a57…
|
drh
|
467 |
if the $baseurl is "http://projectX.com/cgi-bin/fossil" then the |
|
e214a57…
|
drh
|
468 |
$home will be just "/cgi-bin/fossil". |
|
e214a57…
|
drh
|
469 |
|
|
3b505e6…
|
wyoung
|
470 |
* **`index_page`** - The landing page URI as |
|
e214a57…
|
drh
|
471 |
specified by the Admin/Configuration setup page. |
|
e214a57…
|
drh
|
472 |
|
|
3b505e6…
|
wyoung
|
473 |
* **`current_page`** - The name of the page currently being processed, |
|
e214a57…
|
drh
|
474 |
without the leading "/" and without query parameters. |
|
4db19dc…
|
jan.nijtmans
|
475 |
Examples: "timeline", "doc/trunk/README.txt", "wiki". |
|
c90e810…
|
florian
|
476 |
|
|
c90e810…
|
florian
|
477 |
* **`current_checkin`** - The [check-in name](./checkin_names.wiki) to |
|
c90e810…
|
florian
|
478 |
which the current |
|
c90e810…
|
florian
|
479 |
[/ci](/help/www/ci), |
|
c90e810…
|
florian
|
480 |
[/dir](/help/www/dir), |
|
c90e810…
|
florian
|
481 |
[/tree](/help/www/tree), |
|
c90e810…
|
florian
|
482 |
[/timeline](/help/www/timeline) or |
|
c90e810…
|
florian
|
483 |
[/vinfo](/help/www/vinfo) |
|
c90e810…
|
florian
|
484 |
page refers, or undefined for all other pages. This variable is |
|
c90e810…
|
florian
|
485 |
derived from query parameters and is therefore a [tainted string] |
|
c90e810…
|
florian
|
486 |
(./th1.md#taint). |
|
3b505e6…
|
wyoung
|
487 |
|
|
3b505e6…
|
wyoung
|
488 |
* **`csrf_token`** - A token used to prevent cross-site request forgery. |
|
366b23a…
|
wyoung
|
489 |
|
|
3b505e6…
|
wyoung
|
490 |
* **`default_csp`** - [Fossil’s default CSP](./defcsp.md) unless |
|
366b23a…
|
wyoung
|
491 |
[overridden by custom TH1 code](./defcsp.md#th1). Useful within |
|
366b23a…
|
wyoung
|
492 |
the skin for inserting the CSP into a `<meta>` tag within [a |
|
366b23a…
|
wyoung
|
493 |
custom `<head>` element](#headfoot). |
|
366b23a…
|
wyoung
|
494 |
|
|
3b505e6…
|
wyoung
|
495 |
* **`nonce`** - The value of the cryptographic nonce for the request |
|
0236734…
|
mistachkin
|
496 |
being processed. |
|
0236734…
|
mistachkin
|
497 |
|
|
3b505e6…
|
wyoung
|
498 |
* **`release_version`** - The release version of Fossil. Ex: "1.31" |
|
0236734…
|
mistachkin
|
499 |
|
|
3b505e6…
|
wyoung
|
500 |
* **`manifest_version`** - A prefix on the check-in hash of the |
|
e214a57…
|
drh
|
501 |
specific version of fossil that is running. Ex: "\[47bb6432a1\]" |
|
e214a57…
|
drh
|
502 |
|
|
3b505e6…
|
wyoung
|
503 |
* **`manifest_date`** - The date of the source-code check-in for the |
|
e214a57…
|
drh
|
504 |
version of fossil that is running. |
|
e214a57…
|
drh
|
505 |
|
|
3b505e6…
|
wyoung
|
506 |
* **`compiler_name`** - The name and version of the compiler used to |
|
e214a57…
|
drh
|
507 |
build the fossil executable. |
|
e214a57…
|
drh
|
508 |
|
|
3b505e6…
|
wyoung
|
509 |
* **`login`** - This variable only exists if the user has logged in. |
|
e214a57…
|
drh
|
510 |
The value is the username of the user. |
|
e214a57…
|
drh
|
511 |
|
|
3b505e6…
|
wyoung
|
512 |
* **`stylesheet_url`** - A URL for the internal style-sheet maintained |
|
e214a57…
|
drh
|
513 |
by Fossil. |
|
e214a57…
|
drh
|
514 |
|
|
3b505e6…
|
wyoung
|
515 |
* **`logo_image_url`** - A URL for the logo image for this project, as |
|
e214a57…
|
drh
|
516 |
configured on the Admin/Logo page. |
|
e214a57…
|
drh
|
517 |
|
|
3b505e6…
|
wyoung
|
518 |
* **`background_image_url`** - A URL for a background image for this |
|
e214a57…
|
drh
|
519 |
project, as configured on the Admin/Logo page. |
|
e214a57…
|
drh
|
520 |
|
|
e214a57…
|
drh
|
521 |
All of the above are variables in the sense that either the header or the |
|
e214a57…
|
drh
|
522 |
footer is free to change or erase them. But they should probably be treated |
|
e214a57…
|
drh
|
523 |
as constants. New predefined values are likely to be added in future |
|
e214a57…
|
drh
|
524 |
releases of Fossil. |
|
c397fe5…
|
drh
|
525 |
|
|
4e6d36d…
|
wyoung
|
526 |
|
|
93cee1f…
|
wyoung
|
527 |
## <a id="procedure"></a>Suggested Skin Customization Procedure |
|
c397fe5…
|
drh
|
528 |
|
|
c397fe5…
|
drh
|
529 |
Developers are free, of course, to develop new skins using any method they |
|
c397fe5…
|
drh
|
530 |
want, but the following is a technique that has worked well in the past and |
|
c397fe5…
|
drh
|
531 |
can serve as a starting point for future work: |
|
c397fe5…
|
drh
|
532 |
|
|
c397fe5…
|
drh
|
533 |
1. Select a built-in skin that is closest to the desired look. Make |
|
c397fe5…
|
drh
|
534 |
copies of the css, footer, and header into files name "css.txt", |
|
106c090…
|
drh
|
535 |
"details.txt", |
|
c397fe5…
|
drh
|
536 |
"footer.txt", and "header.txt" in some temporary directory. |
|
c397fe5…
|
drh
|
537 |
|
|
c397fe5…
|
drh
|
538 |
If the Fossil source code is available, then these three files can |
|
c397fe5…
|
drh
|
539 |
be copied directly out of one of the subdirectories under skins. If |
|
c397fe5…
|
drh
|
540 |
sources are not easily at hand, then a copy/paste out of the |
|
c397fe5…
|
drh
|
541 |
CSS, footer, and header editing screens under the Admin menu will |
|
c397fe5…
|
drh
|
542 |
work just as well. The important point is that the three files |
|
c397fe5…
|
drh
|
543 |
be named exactly "css.txt", "footer.txt", and "header.txt" and that |
|
c397fe5…
|
drh
|
544 |
they all be in the same directory. |
|
c397fe5…
|
drh
|
545 |
|
|
c64f28d…
|
drh
|
546 |
2. Run the [fossil ui](/help/ui) command with an extra |
|
c397fe5…
|
drh
|
547 |
option "--skin SKINDIR" where SKINDIR is the name of the directory |
|
c397fe5…
|
drh
|
548 |
in which the three txt files were stored in step 1. This will bring |
|
c397fe5…
|
drh
|
549 |
up the Fossil website using the tree files in SKINDIR. |
|
c397fe5…
|
drh
|
550 |
|
|
48a4be5…
|
drh
|
551 |
3. Edit the *.txt files in SKINDIR. After making each small change, |
|
c397fe5…
|
drh
|
552 |
press Reload on the web browser to see the effect of that change. |
|
c397fe5…
|
drh
|
553 |
Iterate until the desired look is achieved. |
|
c397fe5…
|
drh
|
554 |
|
|
106c090…
|
drh
|
555 |
4. Copy/paste the resulting css.txt, details.txt, |
|
106c090…
|
drh
|
556 |
header.txt, and footer.txt files |
|
106c090…
|
drh
|
557 |
into the CSS, details, header, and footer configuration screens |
|
37e2705…
|
stephan
|
558 |
under the Admin/Skins menu. Alternately, import them using the |
|
37e2705…
|
stephan
|
559 |
process described below. |
|
37e2705…
|
stephan
|
560 |
|
|
37e2705…
|
stephan
|
561 |
An alternative to step 4 is to convert the skin files into a form |
|
37e2705…
|
stephan
|
562 |
which can be imported into a repository using `fossil config import`. |
|
37e2705…
|
stephan
|
563 |
It requires compiling [a small tool from the fossil source |
|
37e2705…
|
stephan
|
564 |
tree](/file/tools/skintxt2config.c): |
|
37e2705…
|
stephan
|
565 |
|
|
37e2705…
|
stephan
|
566 |
> |
|
37e2705…
|
stephan
|
567 |
``` |
|
37e2705…
|
stephan
|
568 |
$ cc -o s2c /path/to/fossil/checkout/tools/skintxt2config.c |
|
37e2705…
|
stephan
|
569 |
``` |
|
37e2705…
|
stephan
|
570 |
|
|
37e2705…
|
stephan
|
571 |
With that in place, the custom skin files can be converted with: |
|
37e2705…
|
stephan
|
572 |
|
|
37e2705…
|
stephan
|
573 |
> |
|
37e2705…
|
stephan
|
574 |
``` |
|
37e2705…
|
stephan
|
575 |
$ ./s2c yourskin/*.txt > skin.config |
|
37e2705…
|
stephan
|
576 |
``` |
|
37e2705…
|
stephan
|
577 |
|
|
37e2705…
|
stephan
|
578 |
It can be imported into an arbitrary fossil repository with: |
|
37e2705…
|
stephan
|
579 |
|
|
37e2705…
|
stephan
|
580 |
> |
|
37e2705…
|
stephan
|
581 |
``` |
|
37e2705…
|
stephan
|
582 |
$ fossil config import skin.config |
|
37e2705…
|
stephan
|
583 |
``` |
|
37e2705…
|
stephan
|
584 |
|
|
37e2705…
|
stephan
|
585 |
And it can be pushed to a remote repository with: |
|
37e2705…
|
stephan
|
586 |
|
|
37e2705…
|
stephan
|
587 |
> |
|
37e2705…
|
stephan
|
588 |
``` |
|
37e2705…
|
stephan
|
589 |
$ fossil config push skin |
|
37e2705…
|
stephan
|
590 |
``` |
|
37e2705…
|
stephan
|
591 |
|
|
37e2705…
|
stephan
|
592 |
That approach has proven to be an effective way to locally develop |
|
37e2705…
|
stephan
|
593 |
skin changes then push them to a "live" site. |
|
4e6d36d…
|
wyoung
|
594 |
|
|
42e7733…
|
joel
|
595 |
|
|
4e6d36d…
|
wyoung
|
596 |
## See Also |
|
42e7733…
|
joel
|
597 |
|
|
42e7733…
|
joel
|
598 |
* [Customizing the Timeline Graph](customgraph.md) |