User-friendly Fossil site

Difference between version 0 and 1 - Previous - Next
It's a short intro to the Fossil site building. Results from a discussion of [tclvfs%|%Obtaining tclvfs%|%], sort of continuation of it.

A special accent is set on how to get a Fossil skin like in [http://chiselapp.com/user/aplsimple/repository/aloupe/index%|%aloupe%|%], with "Download", "Docs" and all. Hopefully, it will help to make some Fossil sites more user-friendly.

------

Here, we are going to use [http://chiselapp.com/%|%chiselapp.com%|%] as web hosting.

To create a site:

   * Log in ''chiselapp.com'' using [http://chiselapp.com/secure/log-in/%|%Log In%|%] link. Or create your account if you are new to ''chiselapp.com'' using [http://chiselapp.com/secure/create-account/%|% Create Account%|%] link.  
   * After logging in, create a new repository using [https://chiselapp.com/secure/repository/create/%|%Create Repository%|%] link.  
   * Enter '''Repository name''' like ''mysite'' (no spaces and specials). Enter '''Password''' for ''this repo'' (no confirmation here). At need, switch '''Private''' checkbox on (this can be easily reverted afterwards). Switch '''Use SHA3''' checkbox on.

   * Hit '''Create Repository'''. Then, in a new page, hit '''Return to dashboard'''.  
   * In the list of your repositories, hit ''mysite'' link.  
   * The [http://chiselapp.com/%|%chiselapp.com%|%] will require to repeat "Login in", now for this repository. At thatlogging in, enter the repo's password (it's not the same as your password to [http://chiselapp.com/%|%chiselapp.com%|%]).
  
   * Hit '''Admin''' link, then '''Configuration'''. Enter ''mysite'' as '''Project name'''. Enter ''mysite'' as '''Tarball and ZIP-archive Prefix'''. Then enter below:  
     /doc/trunk/README.md    as Documentation Index (the README.md of your root directory would be Docs link)
     /download               as Download
     MIT (or other)          as License

   * Hit '''Apply Changes'''.

** **

** Now we make a skin **

Hit '''Admin''' again.
Hit '''Skins''' link (amo15th ing the links belowt).

Go to '''Step 4: Make Edits'''.

Clicking '''CSS, Header, Footer, Details, Javascript''' links, fill their contents.

The appropriate text fields are following below (look for "Copy to clipboard" at their top right).

Each time, hit '''Apply Changes''' and close the page to return to the Skins.

** **

*** CSS ***

======
body {
    margin: 0 auto;
    background-color: white;
    font-family: sans-serif;
    font-size:14pt;
    -moz-text-size-adjust: none;
    -webkit-text-size-adjust: none;
    -mx-text-size-adjust: none;
}
a {
    color: #4183C4;
    text-decoration: none;
}
a:hover {
    color: #4183C4;
    text-decoration: underline;
}
div.forumPosts a:visited {
    color: #6A7F94;
}
hr {
    color: #eee;
}
.title {
    color: #4183C4;
    float:left;
}
.title h1 {
    display:inline;
}
.title h1:after {
    content: " / ";
    color: #777;
    font-weight: normal;
}
.content h1 {
    font-size: 1.25em;
}
.content h2 {
    font-size: 1.15em;
}
.content h3 {
    font-size: 1.05em;
    font-weight: bold;
}
.section {
    font-size: 1em;
    font-weight: bold;
    background-color: #f5f5f5;
    border: 1px solid #d8d8d8;
    border-radius: 3px 3px 0 0;
    padding: 9px 10px 10px;
    margin: 10px 0;
}
.sectionmenu {
    border: 1px solid #d8d8d8;
    border-radius: 0 0 3px 3px;
    border-top: 0;
    margin-top: -10px;
    margin-bottom: 10px;
    padding: 10px;
}
.sectionmenu a {
    display: inline-block;
    margin-right: 1em;
}
.status {
    float:right;
    font-size:.7em;
}
.mainmenu {
    font-size:.8em;
    clear:both;
    background:#eaeaea linear-gradient(#fafafa, #eaeaea) repeat-x;
    border:1px solid #eaeaea;
    border-radius:5px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    z-index: 21;  /* just above hbdrop */
}
.mainmenu a {
    text-decoration:none;
    color: #777;
    border-right:1px solid #eaeaea;
}
.mainmenu a.active,
.mainmenu a:hover {
    color: #000;
    border-bottom:2px solid #D26911;
}
div#hbdrop {
    background-color: white;
    border: 1px solid black;
    border-top: white;
    border-radius: 0 0 0.5em 0.5em;
    display: none;
    font-size: 80%;
    left: 2em;
    width: 90%;
    padding-right: 1em;
    position: absolute;
    z-index: 20;  /* just below mainmenu, but above timeline bubbles */
}
.submenu {
    font-size: .7em;
    padding: 10px;
    border-bottom: 1px solid #ccc;
}
.submenu a, .submenu label {
    padding: 10px 11px;
    text-decoration:none;
    color: #777;
}
.submenu a:hover, .submenu label:hover {
    padding: 6px 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    color: #000;
}
.content {
    padding-top: 10px;
    font-size:.8em;
    color: #444;
}
.udiff, .sbsdiff {
    font-size: .85em !important;
    overflow: auto;
    border: 1px solid #ccc;
    border-radius: 5px;
}
.content blockquote {
    padding: 0 15px;
}
div.forumHierRoot blockquote, div.forumHier blockquote {
    background-color: rgba(65, 131, 196, 0.1);
    border-left: 3px solid #254769;
    padding: .1em 1em;
}
table.report {
    cursor: auto;
    border-radius: 5px;
    border: 1px solid #ccc;
    margin: 1em 0;
}
.report td, .report th {
   border: 0;
   font-size: .8em;
   padding: 10px;
}
.report td:first-child {
    border-top-left-radius: 5px;
}
.report tbody tr:last-child td:first-child {
    border-bottom-left-radius: 5px;
}
.report td:last-child {
    border-top-right-radius: 5px;
}
.report tbody tr:last-child {
    border-bottom-left-radius: 5px;
    border-bottom-right-radius: 5px;
}
.report tbody tr:last-child td:last-child {
    border-bottom-right-radius: 5px;
}
.report th {
    cursor: pointer;
}
.report thead+tbody tr:hover {
    background-color: #f5f9fc !important;
}

td.tktDspLabel {
    width: 70px;
    text-align: right;
    overflow: hidden;
}
td.tktDspValue {
    text-align: left;
    vertical-align: top;
    background-color: #f8f8f8;
    border: 1px solid #ccc;
}
td.tktDspValue pre {
    white-space: pre-wrap;
}
span.timelineDetail {
    font-size: 90%;
}
.footer {
    border-top: 1px solid #ccc;
    padding: 10px;
    font-size:.7em;
    margin-top: 10px;
    color: #ccc;
}
div.timelineDate {
    font-weight: bold;
    white-space: nowrap;
}
span.submenuctrl, span.submenuctrl input, select.submenuctrl {
  color: #777;
}
span.submenuctrl {
  white-space: nowrap;
}
div.submenu label {
  white-space: nowrap;
}
@media screen and (max-width: 600px) {
  /* Spacing for mobile */
  body {
    padding-left: 4px;
    padding-right: 4px;
  }
  .title {
    padding-top: 0px;
    padding-bottom: 0px;
  }
  .status {padding-top: 0px;}
  .mainmenu a {
    padding: 10px 10px;
  }
  .mainmenu {
    padding: 10px;
  }
  .desktoponly {
    display: none;
  }
}
@media screen and (min-width: 600px) {
  /* Spacing for desktop */
  body {
    padding-left: 20px;
    padding-right: 20px;
  }
  .title {
    padding-top: 10px;
    padding-bottom: 10px;
  }
  .status {padding-top: 30px;}
  .mainmenu a {
    padding: 10px 20px;
  }
  .mainmenu {
    padding: 10px;
  }
}
@media screen and (max-width: 1200px) {
  /* Special declarations for narrow desktop or wide mobile */
  .wideonly {
    display: none;
  }
}
======

** **

*** Header ***
In the field below, replace two ''aplsimple'' with your ''login''. Or remove the link at all, to restore Fossil defaults.

You can also insert your own links into the header, e.g. under "menulink /download Download {}" line.

======
<div class="header">
  <div class="title">
    <div class="page-title">
      <div class="title-header"><a href="$home$index_page"><h1>$<project_name></h1></a>
      <th1>
        if {$current_page eq [string range $index_page 1 end] || 
            $current_page eq "index" || $project_name eq $title} {
          puts Home
        } else {
          puts $title
        }
      </th1>
      </div>
    </div>
  </div>
    <div class="status"><th1>
 if {[info exists login]} {   html "<a href='http://chiselapp.com/user/$login/'>$login</a> — <a href='$home/login'>Logout</a>\n"
 } else {   html "<a href='http://chiselapp.com/user/aplsimple/'>aplsimple</a> | <a href='$home/login'>Login</a>\n"
 }
    </th1></div>
</div>
<div class="mainmenu">
<th1>
proc menulink {url name cls} {
  upvar current_page current
  upvar home home
  if {[string range $url 0 [string length $current]] eq "/$current"} {
    html "<a href='$home$url' class='active $cls'>$name</a>\n"
  } else {
    html "<a href='$home$url' class='$cls'>$name</a>\n"
  }
}
html "<a id='hbbtn' href='#'>&#9776;</a>"
menulink $index_page Home {}
menulink /doc/trunk/README.md Docs {}
menulink /download Download {}
if {[anycap s]} {
  # jor
  menulink /timeline Timeline {}
}
if {[hascap oh]} {
  menulink /dir?ci=tip Files desktoponly
}
if {[hascap s]} {
  # o
  menulink  /brlist Branches desktoponly
  menulink  /taglist Tags wideonly
}
if {[anycap 23456] || [anoncap 2] || [anoncap 3]} {
  menulink /forum Forum wideonly
}
if {[hascap oh]} {
  # r
  menulink /ticket Tickets wideonly
}
if {[hascap j]} {
  menulink /wiki Wiki wideonly
}
if {[hascap s]} {
  menulink /setup Admin {}
} elseif {[hascap a]} {
  menulink /setup_ulist Users {}
}
</th1></div>
<div id='hbdrop'></div>
======

** **

*** Footer ***

======
<div class="footer">
This page was generated in about
<th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
Fossil $release_version $manifest_version $manifest_date
</div>
<script nonce="$nonce">
<th1>styleScript</th1>
</script>
======

** **

*** Details ***

======
timeline-arrowheads:        1
timeline-circle-nodes:      1
timeline-color-graph-lines: 1
white-foreground:           0
======

** **

*** Javascript (optional) ***
Don't consider the Javascript field ''optional'' as suggested by Fossil.

The field is mandatory for this skin.

======
(function() {
  var panel = document.getElementById("hbdrop");
  if (!panel) return;   // site admin might've nuked it
  if (!panel.style) return;  // shouldn't happen, but be sure
  var panelBorder = panel.style.border;
  // Disable animation if this browser doesn't support CSS transitions.
  //
  // We need this ugly calling form for old browsers that don't allow
  // panel.style.hasOwnProperty('transition'); catering to old browsers
  // is the whole point here.
  var animate = panel.style.transition !== null && (typeof(panel.style.transition) == "string");
  var animMS = 400;
  // Calculate panel height despite its being hidden at call time.
  // Based on https://stackoverflow.com/a/29047447/142454
  var panelHeight;  // computed on sitemap load
  function calculatePanelHeight() {
    // Get initial panel styles so we can restore them below.
    var es   = window.getComputedStyle(panel),
        edis = es.display,
        epos = es.position,
        evis = es.visibility;
    // Restyle the panel so we can measure its height while invisible.
    panel.style.visibility = 'hidden';
    panel.style.position   = 'absolute';
    panel.style.display    = 'block';
    panelHeight = panel.offsetHeight + 'px';
    // Revert styles now that job is done.
    panel.style.display    = edis;
    panel.style.position   = epos;
    panel.style.visibility = evis;
  }
  // Show the panel by changing the panel height, which kicks off the
  // slide-open/closed transition set up in the XHR onload handler.
  //
  // Schedule the change for a near-future time in case this is the
  // first call, where the div was initially invisible.  If we were
  // to change the panel's visibility and height at the same time
  // instead, that would prevent the browser from seeing the height
  // change as a state transition, so it'd skip the CSS transition:
  //
  // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#JavaScript_examples
  function showPanel() {
    if (animate) {
      setTimeout(function() {
        panel.style.maxHeight = panelHeight;
        panel.style.border    = panelBorder;
      }, 40);   // 25ms is insufficient with Firefox 62
    }
    else {
      panel.style.display = 'block';
    }
  }
  // Return true if the panel is showing.
  function panelShowing() {
    if (animate) {
      return panel.style.maxHeight == panelHeight;
    }
    else {
      return panel.style.display == 'block';
    }
  }
  // Click handler for the hamburger button.
  var needSitemapHTML = true;
  document.querySelector("div.mainmenu > a").onclick = function() {
    if (panelShowing()) {
      // Transition back to hidden state.
      if (animate) {
        panel.style.maxHeight = '0';
        setTimeout(function() {
          // Browsers show a 1px high border line when maxHeight == 0,
          // our "hidden" state, so hide the borders in that state, too.
          panel.style.border = 'none';
        }, animMS);
      }
      else {
        panel.style.display = 'none';
      }
    }
    else if (needSitemapHTML) {
      // Only get it once per page load: it isn't likely to
      // change on us.
      var xhr = new XMLHttpRequest();
      xhr.onload = function() {
        var doc = xhr.responseXML;
        if (doc) {
          var sm = doc.querySelector("ul#sitemap");
          if (sm && xhr.status == 200) {
            // Got sitemap.  Insert it into the drop-down panel.
            needSitemapHTML = false;
            panel.innerHTML = sm.outerHTML;
            // Display the panel
            if (animate) {
              // Set up a CSS transition to animate the panel open and
              // closed.  Only needs to be done once per page load.
              // Based on https://stackoverflow.com/a/29047447/142454
              calculatePanelHeight();
              panel.style.transition = 'max-height ' + animMS +
                  'ms ease-in-out';
              panel.style.overflowY  = 'hidden';
              panel.style.maxHeight  = '0';
              showPanel();
            }
            panel.style.display = 'block';
          }
        }
        // else, can't parse response as HTML or XML
      }
      xhr.open("GET", "$home/sitemap?popup");   // note the TH1 substitution!
      xhr.responseType = "document";
      xhr.send();
    }
    else {
      showPanel();   // just show what we built above
    }
    return false;  // prevent browser from acting on <a> click
  }
})();
======

** **

*** Last steps ***

Last but not least.
In the '''Step 5: Verify The Draft Skin''', hit the first link. ''It's a must!'' Then close the verified page to return to the Skins.

In the '''Step 7: Publish''', switch both checkboxes on.

Hit '''Publish Draft1''' button.

That's all.

** **

*** Other details ***
The [How to chisel at chiselapp.com] wiki covers other details, e.g. [https://wiki.tcl-lang.org/page/How+to+chisel+at+chiselapp.com#home%|%how to make "Home" page%|%].