Skip to Content

emsenn's website

This doc

Introduction

Summary

Please note any “TODO” or “TK” - that means text around it is incomplete or inaccurate, such as missing a citation.

This document is my personal website. This is a novel concept to me, so bear with me while I explain.

This document contains within itself many source blocks, which are blocks of text that represent computer code, in some way or another.

Using the EmacsTK text editor, those snippets of code can either be run or extracted into other files - the latter is mostly what I’ve done.

There are source blocks in this document for not just the content of my basic webpages, but the templates which the Hugo static site generatorTK uses to turn that content into HTML documents.

If you’re a programmer, think of it this way: instead of having code with chunks of documentation mixed in, this is documentation with chunks of code mixed in.

If you’re not, you can just read this linearly or at random, and you may gain some understanding of the code behind my website.

License & Editorial Information

This document and the source code it contains are released under the MIT License and maintained at https://git.sr.ht/~emsenn/website, where a list of syndications is available.

Using this Document

Introduction

This document is written, for now, mostly for my own use and benefit. It’s important readers understand that before going further. While wrapping this up nicely as a real resource is an eventual plan, for now I need to focus on giving myself a reliable publishing platform through this website.

So, if you’re an ordinary reader, very few concessions have been made for you. I hope you are able to get what you want from this document anyway.

If you’re hoping to use this document to create your own version of my website, it is required you be familiar with EmacsTK, Org-modeTK, and BabelTK.

The original Org-mode source of this document can be detangled which will create a functional Hugo site in the build./ directory, which you can then build with Hugo as normal.

The next few sections contain source blocks which can be run in Org-mode, to go through the steps of building and deploying the site. They’re for my own convenience and others’ education, don’t expect them to work if you have this code locally.

Since I’m working with them as source blocks, assume they’re all to be run in the same directory as the emsenn-website.org file you’re looking at now.

Clean Current Build

rm -r ./build

Make Build Directory

mkdir -p ./build/{data,content}
mkdir -p ./build/layouts/_default
mkdir -p ./build/layouts/metapages
mkdir -p ./build/layouts/partials/functions
find ./build -type d -maxdepth 2

Tangle code

Run the command org-bable-tangle or the hotkey C-c C-v C-t.

Pull in Other Content


Build the site

cd build
hugo

Upload

This script uploads ./build/public to Neocities, which is the host for the HTTP distribution of the site. Note, this relies on the Neocities CLI application, and being logged in with it.

cd ./build/public
neocities push .

All-in-One

rm -r ./build
mkdir -p ./build/data
mkdir -p ./build/content/{docs,projects}
mkdir -p ./build/layouts/_default
mkdir -p ./build/layouts/metapages
mkdir -p ./build/layouts/partials/functions
find ./build -type d -maxdepth 2
cp -r ./static ./build/static
cp -r ./content/* ./build/content/
cd ./build
hugo

Acknowledgements

Hugo Configuration

Introduction

Hugo allows for a fair bit of configuration - in this section, I’ll explain which configurations I set - all of which are written to ./config.toml.

Base URL Configuration

The baseURL variable, accessed through .Site.BaseURL, is currently unused.

baseURL = "http://localhost:1313"

Language Configuration

The languageCode variable, accessed through .Site.Language.Lang, is used in the 5.2.1.

languageCode = "en-us"

Emoji Configuration

The enableEmoji variables sets whether or not emoticon shortcodes in documents are rendered. (😄 to a smiling face emoji, for example.)

enableEmoji = true

Title Configuration

title = "emsenn"

Site Author Configuration

author = "emsenn"

Site Document Types Configuration

[params]
  documentTypes = "essay fiction document letter manual"

Content

Documents Listing

Ending up at emsenn.net/docs/, this content is caught by Hugo and used as the basis for a special page that lists all the categories and tags that documents fall under.

+++
title = "My Documents"
type = "metapages"
layout = "docs"
+++

This page is a listing of all the documents I've published to my
website.

Drafts Listing

+++
title = "Drafts"
author = ["emsenn"]
lastmod = 2019-01-20T20:01:00-05:00
categories = ["webpage"]
draft = false
+++

This !!contentType!! is a listing of all the **_drafts_** in this
website: documents that are, for one reason or another, not yet
finished.

Finished Document Listing

+++
title = "Finished Documents"
author = ["emsenn"]
lastmod = 2019-01-20T20:01:00-05:00
categories = ["webpage"]
draft = false
+++

This !!contentType!! is a listing of all the **_finished documents_** in this website:
documents that I consider complete and ready for general distribution.  Note that this
listing also includes webpages.

Services Page

My name is _**emsenn**_. I'm an independent consultant and writer who
specializes in teaching senior executives how they can improve their
business by adopting methods used in open-source software development.

Contact Page

+++
title = "Contact Me"
type = "metapages"
+++

_**In a hurry?**_ Send an email to my [public
inbox](https://lists.sr.ht/~emsenn/public-inbox), or [send me an
email](mailto:emsenn@emsenn.net) if you really have to.

## Introduction

This website is just part of my online presence, and doesn't provide
any means for readers to communicate back with me. I do maintain lots
of other accounts for various purposes - this is a list of all them,
not just the ones I use for "communicating."

## Email

You can */send me an email/*. I maintain a [collection of mailing
lists](https://lists.sr.ht/~emsenn/) relevant to my projects, as well
as a [public inbox](https://lists.sr.ht/~emsenn/public-inbox) for more
general public communication. I also accept [private
emails](mailto:emsenn@emsenn.net) but I reserve the right to publicize
anything you might send to me.

## Chatting

I'm active in the Fediverse, a network of communication platforms:

- At [@emsenn@mastodon.social](https://mastodon.social/@emsenn), I do
  my general chatting. _(If you're more familiar with legacy social
  media, it's kind of like my Twitter.)_
- At [@emsenn@tabletop.social](https://tabletop.social/@emsenn), I
  chat about tabletop role-playing games, like Dungeons and Dragons or
  my own _[Brave Old World](/projects/brave-old-world)_.

## Syndication

In addition to publishing my non-commissioned writing on my website, I
also syndicate on other platforms.

- [@emsenn@wordsmith.social](https://wordsmith.social/emsenn) is where
  I syndicate drafts and non-commissioned writing.
- [@emsenn@tabletop.press](https://tabletop.press/emsenn) is where I
  syndicate my tabletop gaming rules and adventures.
- [LBRY](lbry://@emsenn) lets you buy my writing with a cryptocurrency
  of the same name.


This website is also syndicated through the [DAT
protocol](dat://beea87bd7ba3c55fbcf54a5f868dc5f6ff64b77ac8d82682170072c76a8d0c0f/)
and [archived on the
IPFS](https://neocities.org/site/emsenn/archives).

Project Pages

Brave Old World

+++
title = "Brave Old World"
+++

_**Brave Old World**_ are rules for telling stories with friends: a
collection of rules for playing a tabletop role-playing game.

Data

Index

introduction = """
I have an interest in the things that shape our interactions with
technology, like software document and project governance."""
plans = [
  "Finish centralizing my project repositories at [git.sr.ht/~emsenn](https://git.sr.ht/~emsenn).",
  "Consider using Org-mode to create a literately programmed static site generator.",
  "Develop a MUD engine."
]

Activities

2019-01-16 = """
I started centralizing my projects at
[git.sr.ht/~emsenn](https://git.sr.ht/~emsenn)."""

2019-01-17 = """
I wrote a new homepage."""

2019-01-18 = """
I wrote [Mastodon is a Bake
Fair](/docs/mastodon-is-a-bake-fair/)."""

Category Descriptions

directive = "_*Directives*_ are principles which guide my actions and decision-making."
essay = "_*Essays*_  are short pieces written with some depth or seriousness."
fiction = "_*Fictions*_ are untrue for one or more reason, usually entertainment."
game = "_*Games*_ are rules for doing something fun, often with friends."
letter = "_*Letters*_ are pieces written for a specific audience."
list = "Lists of useful information."
manual = "Guides for accomplishing a type of work or fulfilling a role."
note = "Unrefined writing on a variety of topics."
procedure = "A single set of instructions for completing an action.  _These are singular procedures._"
procedures = "A collection of procedures related to a broad action.  _These are collections of procedures._"
project = "Information about projects I'm developing."
service = "Information about professional services I offer."
webpage = "Other pages on this website; not really \"documents.\""

Layouts

Introduction

Default Layouts

The default layouts, located under ./layouts/_default/ are used when there’s not a more relevant layout to use with a document. In practice they’re used quite a lot. Because Hugo is written as a static website generator, all the default templates are in HTML.

Base Default Layout

The base default layout, saved as ./layouts/_default/baseof.html, is the lowest-priority (except for themes’) base template, but even so is used as the base template for every(?) HTML document on my website.

There are roughly two parts to the baseof.html layout - there is some initialization of variables at the top, and then the rest pulls in other layouts to render a complete HTML document.

  1. Base Default Layout: Document Declaration

    {{ block "documentDeclaration" . }}
      <!DOCTYPE html>
        <html xmlns="http://www.w3.org/1999/xhtml"
          {{- with .Site.Language.Lang }} xml:lang="{{- . -}}" lang="{{- . -}}"
          {{- end }}>
    {{ end }}
    
  2. Base Default Layout: Head

    1. Base Default Layout: Head: Opening

      The default base layout creates a head block, which, in its default, contains a <head> tag with several components.

      {{ block "head" . }}
        <head>
      
    2. Base Default Layout: Head: Meta

      The headMeta block contains a <link> tag that I honestly don’t know why or what it does, and several <meta> tags.

      {{ block "headMeta" . }}
        <link href="https://gmpg.org/xfn/11" rel="profile">
      

      Setting the charset property does… something. I think maybe lets emoji be available? Or tells the client to try and make them available?

      <meta charset="UTF-8">
      

      The description is used by search engines and other external resources if they don’t have a more relevant description to pull.

      <meta name="description" content="{{- (partial "briefDescription.html" .) -}}">
      

      The keywords are used for SEO bullshit.

      <meta name="keywords" content="{{- .Render "keywords" -}}">
      

      The author is set only if the document has an author parameter set or if the config.toml contains a author configuration.

      {{ with ((.Params.author) | default (.Site.Author)) -}}
        <meta name="author" content="{{ . }}">
      {{- end }}
      
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
      {{ end }}
      
    3. Base Default Layout: Head: Title

      {{ block "headTitle" . }}
        <title>
          {{- printf "%s%s" (.Site.Title) (printf ": %s" (((.Data.Term | pluralize) | default .Title)) | default "") -}}
        </title>
      {{ end }}
      
    4. Base Default Layout: Head: Style

      {{ block "style" . }}
        <style>
          {{ block "htmlCSSRules" . }}
            html {
          color: #222;
          background-color: #eee;
          hyphens: auto;
          font-family: sans-serif;
          letter-spacing: 0.025em;
          word-spacing: 0.045em;
          line-height: 1.4;
          font-size: 1.3rem;
          transition-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
          animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
            }
          {{ end }}
          {{ block "bodyCSSRules" . }}
            body {
          max-width: 40rem;
          margin: 0 auto;
          min-height: 115vh;
            }
          {{ end }}
          {{ block "mainCSSRules" . }}
            main {
          width: 70vw;
          max-width: 40rem;
          padding: 3rem 2rem 6rem;
          margin: 0 auto;
             margin-bottom: -6rem;
            }
          {{ end }}
          {{ block "sectionCSSRules" . }}
            section {
          padding: 0.3em;
            }
          {{ end }}
          {{ block "h1CSSRules" . }}
            h1 {
          text-align: center;
          font-weight: normal;
          font-size: 2em;
          margin: 0.5em 0 0 0;
            }
          {{ end }}
          {{ block "aCSSRules"  .}}
            a {
          color: #222;
          display: inline-block;
          position: relative;
          text-decoration: none;
          transition: color 0.3s;
          background: linear-gradient(to left, #eee 50%, rgba(34,34,34,0.3) 50%);
          background-size: 200% 100%;
          background-position:right bottom;
          transition: background 0.3s;
            }
            a:before {
          background: #222;
          content: "";
          display: block;
          position: absolute;
          bottom: 0.05em;
          height: 0.1em;
          width: 100%;
          transition: all 0.3s;
            }
            a:visited {
          color: #777;
            }
            a:hover {
          outline-style: none;
          animation-delay: 0.3s;
          animation: animation-pulse 0.8s infinite;
          background-position:left bottom;
            }
            a:hover:before, a:focus:before {
          width: 0em;
            }
            a:focus {
          outline-style: none;
          animation-delay: 0.3s;
          background: none;
          animation: animation-pulse-heavy 1.2s infinite;
            }
          {{ end }}
          {{ block "skipToContentCSSRules" . }}
            .skipToContentLink {
          opacity: 0;
          position: absolute;
            }
            .skipToContentLink:focus{
          opacity:1
            }
          {{ end }}
          {{ block "selectionCSSRules" . }}
           ::selection {
           color: #222;
           background-color: #777;
           }
           {{ end }}
           {{ block "animationPulseCSSRules" . }}
           @keyframes animation-pulse {
           from, 50%,
           to { background-color: rgba(117,117,117,0.2)); }
           50% { background-color: rgba(117,117,117,0.1); }
           }
           @keyframes animation-pulse-heavy {
           from, 50%,
           to {
           background-color: rgba(117,117,117,0.3));
           }
           50% { background-color: rgba(117,117,117,0.2); }
           }
           {{ end }}
        </style>
      {{ end }}
      
    5. Base Default Layout: Head: Close

        </head>
      {{ end }}
      
  3. Base Default Layout: Body

    1. Base Default Layout: Body: Opening

      {{ block "body" . }}
        <body>
      
    2. Base Default Layout: Body: Background

      {{ block "bodyBackground" . }}
        <div class="backgroundimage"></div>
      {{ end }}
      
    3. Base Default Layout: Body: Preface

      {{ block "bodyPreface" . }}
        <a class="skipToContentLink" href="#content">Skip to Content</a>
      {{ end }}
      
    4. Base Default Layout: Body: Header

      {{ block "header" . }}
        <header>
          {{ block "headline" . }}
            <h1>{{ .Title | default .Site.Title }}</h1>
          {{ end }}
          {{ block "subheadline" . }}
            <p style="text-align: center;">
          This website is in <strong>early development</strong>.
            </p>
          {{ end }}
        </header>
      {{ end }}
      
    5. Base Default Layout: Body: Main

      {{ block "main" . }}
        <main id="content">
          {{ block "content" . }}
            {{ with .Content }}
          {{ . }}
            {{ end }}
          {{ end }}
          {{ block "sectionlisting" . }}{{ end }}
        </main>
      {{ end }}
      
    6. Base Default Layout: Body: Footer

      {{ block "footer" . }}
        <footer>
          {{ if (and (eq .Type "docs") (.IsPage)) }}
            <p>
          This {{ .Layout | default (.Type | singularize) }} is
          released under the
          <a href="https://opensource.org/licenses/MIT">
            MIT License
          </a>.
            </p>
          {{ end }}
        </footer>
      {{ end }}
      
    7. Base Default Layout: Body: Close

        </body>
      {{ end }}
      
  4. Base Default Layout: Document Close

    </html>
    

List Default Layout

{{ define "headline" }}
  <h1>{{ (.Data.Term | title | pluralize) | default .Title }}</h1>
{{ end }}
{{ define "sectionlisting" }}
  {{ with .Pages }}
    <ul>
      {{ range . }}
	<li>
	  <a href="{{ .Permalink}}"><strong>
	    {{- if (eq .Kind "taxonomy") -}}
	      {{- .Title | pluralize -}}
	    {{- else -}}{{- .Title -}}{{- end -}}
	  </strong></a><br/>
	</li>
      {{ end }}
    </ul>
  {{ end }}
{{ end }}

Single Document Default Layout

{{ define "subheadline" }}
  <!-- -->
{{ end }}
{{ define "content" }}
  {{ with .Content }}
    {{ . }}
  {{ end }}
{{ end }}

Index Default Layout

{{- define "headTitle" -}}
  <title>emsenn</title>
{{ end }}
{{- define "headline" -}}
  <h1>My name is emsenn</h1>
{{- end -}}
{{- define "subheadline" -}}
  <!-- -->
{{- end -}}
{{ define "content" }}
  {{ with .Site.Data.index.introduction }}
    {{ . | markdownify }}
  {{ end }}
  {{ with .Site.Data.activities }}
    <section id="recent-activites">
      <h2>Recent Activities</h2>
      <ul>
	{{ range $date, $report := . }}
	  <li>
	    {{ (printf "**%s,** %s" (dateFormat "January 2, 2006" $date) $report) | markdownify }}
	  </li>
	{{ end }}
      </ul>
    </section>
  {{ end }}
  {{ with .Site.Data.index.plans }}
    <section id="plans">
      <h2>Plans</h2>
      <ul>
	{{ range . }}
	  <li>
	    {{ . | markdownify }}
	  </li>
	{{ end }}
      </ul>
    </section>
  {{ end }}
  <p>
    {{ (printf "This website contains a [curated list of my projects](/projects/) and [my non-commissioned documents](/docs/).") | markdownify }}
  </p>
{{ end }}
{{ define "footer" }}
<!-- -->
{{ end }}

Document Layouts

Essay Layout

Metapage Layouts

List Metapage Layouts

{{ define "footer" }}
  <!-- -->
{{ end }}

Single Metapage Layout

{{ define "subheadline" }}
  {{ with .Description }}
    <p>
      {{ . }}
    </p>
  {{ end }}
{{ end }}
{{ define "content" }}
  {{ with .Content }}
    {{ . }}
  {{ end }}
{{ end }}
{{ define "footer" }}
  <!-- -->
{{ end }}

Docs Metapage Layout

{{ define "subheadline" }}
  <!-- -->
{{ end }}
{{ define "content" }}
  {{ $scratch := newScratch }}
  {{ ($scratch.Set "totalWordCount" 0) }}
  {{ ($scratch.Set "totalDrafts" 0) }}
  {{ ($scratch.Set "totalFinishedDocuments" 0) }}
  {{ ($scratch.Set "totalDocuments" 0) }}
  {{ with .Content }}
    {{ . }}
  {{ end }}
  {{ range where .Site.RegularPages "Type" "docs" }}
      {{ ($scratch.Set "totalWordCount" (add ($scratch.Get "totalWordCount") .WordCount)) }}
      {{ if .Draft }}
	{{ ($scratch.Set "totalDrafts" (add ($scratch.Get "totalDrafts") 1)) }}
      {{ else }}
	{{ ($scratch.Set "totalFinishedDocuments" (add ($scratch.Get "totalFinishedDocuments") 1)) }}
      {{ end }}
      {{ ($scratch.Set "totalDocuments" (add ($scratch.Get "totalDocuments") 1)) }}
  {{ end }}
  <p>
    At present, my website contains:
  </p>
  <ul>
    <li>
      {{ ($scratch.Get "totalFinishedDocuments") }}
      finished documents
    </li>
    <li>
      {{ ($scratch.Get "totalDrafts") }}
      drafts
    </li>
  </ul>
  <p>
    totalling {{ ($scratch.Get "totalDocuments") }}
    documents containing <strong>
			   {{ ($scratch.Get "totalWordCount") }}
			 </strong> words:
  </p>
  <ul>
    {{ range where .Site.RegularPages "Type" "docs" }}
      <li>
	<a href="{{ .Permalink}}"><strong>
	  {{- if (eq .Kind "taxonomy") -}}
	    {{- .Title | pluralize -}}
	  {{- else -}}{{- .Title -}}{{- end -}}
	</strong></a><br/>
      </li>
    {{ end }}
  </ul>
{{ end }}
{{ define "footer" }}
  <!-- -->
{{ end }}

Partial Layouts

Brief Description Partial Layout

{{- if (in (.Site.Params.documentTypes) (.Layout | default .Type)) -}}
{{ end }}

Description Partial Layout

This partial layout returns a paragraph about the page’s metadata, based on its content type. An example of the return might be

<p>
  This <strong>essay</strong> is about <strong>Galavant</strong> and
  was <strong>released on October 11, 2018</strong>, has
  <strong>918 words</strong>, and is estimated to take <strong>4
  minutes to read</strong>.
</p>
  1. Description Layout: Initialization

    The top part of the description layout sets up which attributes should be shown in the description.

    Attribute Renders in…
    List Count
    Date Essays, fictions, and notes
    Reading Time Essays, fictions, letters, manuals, procedures, and singular procedures.
    Word Count Essays, fictions, letters, manuals, procedures, and singular procedures.
    {{- $scratch := newScratch -}}
    {{- ($scratch.Set "showListItems" "") -}}
    {{- ($scratch.Set "showDate" "essay fiction note") -}}
    {{- ($scratch.Set "showReadingTime" "essay fiction letter manual procedure procedures") -}}
    {{- ($scratch.Set "showWordCount" "essay fiction letter manual procedure procedures") -}}
    {{- ($scratch.Set "paramTypes" slice) -}}
    
  2. Description Layout: Determine Content Type

    {{- if (isset .Params "categories") -}}
      {{- with .Params.categories -}}
        {{- range last 1 . -}}
          {{- ($scratch.Set "contentType" .) -}}
        {{- end -}}
      {{- end -}}
    {{- else -}}
      {{- $scratch.Set "contentType" "piece" -}}
    {{- end -}}
    
  3. Description Layout: Determine Content Subject

    {{- if (isset .Params "tags") -}}
      {{- with .Params.tags -}}
        {{- range last 1 . -}}
          {{- if (eq (. | title) .) -}}
        {{- ($scratch.Set "contentSubject" (. | humanize | title)) -}}
          {{- else -}}
        {{- ($scratch.Set "contentSubject" (. | humanize | lower)) -}}
          {{- end -}}
        {{- end -}}
      {{- end -}}
    {{- end -}}
    
  4. Description Layout: Configure Grammar

    {{- with ($scratch.Get "contentType") -}}
      {{- if (eq . ( . | pluralize)) -}}
        {{- ($scratch.SetInMap "grammar" "article" "these") -}}
        {{- ($scratch.SetInMap "grammar" "hasTense" "have") -}}
        {{- ($scratch.SetInMap "grammar" "isTense" "are") -}}
      {{- else -}}
        {{- ($scratch.SetInMap "grammar" "article" "this") -}}
        {{- ($scratch.SetInMap "grammar" "hasTense" "has") -}}
        {{- ($scratch.SetInMap "grammar" "isTense" "is") -}}
      {{- end -}}
    {{- end -}}
    
  5. Description Layout: Configure Date

    {{- if (in ($scratch.Get "showDate") ($scratch.Get "contentType")) -}}
      {{- with .Date -}}
        {{- ($scratch.SetInMap "pageParameters" "1date" .) -}}
      {{- end -}}
    {{- end -}}
    
  6. Description Layout: Configure List Count

    {{- if (in ($scratch.Get "showListItems") ($scratch.Get "contentType")) -}}
    {{- end -}}
    
  7. Description Layout: Configure Word Count

    {{- if (in ($scratch.Get "showWordCount") ($scratch.Get "contentType")) -}}
        {{- ($scratch.SetInMap "pageParameters" "3wordCount" .WordCount) -}}
    {{- end -}}
    
  8. Description Layout: Configure Reading Time

    {{- if (in ($scratch.Get "showReadingTime") ($scratch.Get "contentType")) -}}
      {{- ($scratch.SetInMap "pageParameters" "4readingTime" .ReadingTime) -}}
    {{- end -}}
    
  9. Description Layout: Configure Draft

    {{- if (.Draft) -}}
      {{- ($scratch.SetInMap "pageParameters" "5isDraft" true) -}}
    {{- end -}}
    
  10. Description Layout: Build Intro Clause

    With the variables assembled above, the layout now builds the actual paragraph to be returned, inside the variable introClause.

    {{- ($scratch.Set "introClause" (printf "%s **%s**" ((index ($scratch.Get "grammar") "article") | title) ($scratch.Get "contentType"))) -}}
    {{- with ($scratch.Get "contentSubject") -}}
      {{- ($scratch.Set "introClause" (printf "%s is about **%s** and" ($scratch.Get "introClause") (printf "%s" .))) -}}
    {{- end -}}
    {{- range $k, $v := ($scratch.Get "pageParameters") -}}
      {{- ($scratch.Add "paramTypes" (slice $k)) -}}
    {{- end -}}
    {{- if (gt (len ($scratch.Get "paramTypes")) 1) -}}
      {{- ($scratch.Set "fullDesc" ($scratch.Get "introClause")) -}}
      {{- range first (sub (len ($scratch.Get "paramTypes")) 1) ($scratch.Get "paramTypes") -}}
        {{- if (eq . "1date") -}}
          {{- if $.PublishDate -}}
        {{- if (ne (string $.PublishDate) ("0001-01-01 00:00:00 +0000 UTC")) -}}
          {{- ($scratch.Set "fullDesc" (printf "%s was **released on %s**," ($scratch.Get "fullDesc") (dateFormat "January 2, 2006" $.PublishDate))) -}}
        {{- else -}}
          {{- ($scratch.Set "fullDesc" (printf "%s was **last updated on %s**," ($scratch.Get "fullDesc") (dateFormat "Jan 2, 2006" $.Date))) -}}
        {{- end -}}
          {{- end -}}
        {{- else if (eq . "2listItems") -}}
        {{- else if (eq . "3wordCount") -}}
          {{- ($scratch.Set "fullDesc" (printf "s% %s **%s words**," ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "hasTense") (string (index ($scratch.Get "pageParameters") .)))) | safeHTML -}}
        {{- else if (eq . "4readingTime") -}}
          {{- ($scratch.Set "fullDesc" (printf "%s %s estimated to take **%s minutes to read**," ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "isTense") (string (math.Round (mul (index ($scratch.Get "pageParameters") .) 1.2))))) -}}
        {{- else if (eq . "5isDraft") -}}
          {{- ($scratch.Set "fullDesc" (printf "%s <strong>not finalized</strong>," ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "isTense"))) -}}
        {{- end -}}
      {{- end -}}
      {{- range last 1 ($scratch.Get "paramTypes") -}}
        {{- if (eq . "1date") -}}
          {{- if $.PublishDate -}}
        {{- if (ne (string $.PublishDate) ("0001-01-01 00:00:00 +0000 UTC")) -}}
          {{- ($scratch.Set "fullDesc" (printf "%s was **released on %s**," ($scratch.Get "fullDesc") (dateFormat "January 2, 2006" $.PublishDate))) -}}
        {{- else -}}
          {{- ($scratch.Set "fullDesc" (printf "%s was **last updated on %s**," ($scratch.Get "fullDesc") (dateFormat "Jan 2, 2006" $.Date))) -}}
        {{- end -}}
          {{- end -}}
        {{- else if (eq . "2listItems") -}}
        {{- else if (eq . "3wordCount") -}}
          {{- ($scratch.Set "fullDesc" (printf "%s and %s **%s words**." ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "hasTense") (string (index ($scratch.Get "pageParameters") .)))) | safeHTML -}}
        {{- else if (eq . "4readingTime") -}}
          {{- ($scratch.Set "fullDesc" (printf "%s and %s estimated to take **%s minutes to read**." ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "isTense") (string (math.Round (mul (index ($scratch.Get "pageParameters") .) 1.2))))) -}}
        {{- else if (eq . "5isDraft") -}}
          {{- ($scratch.Set "fullDesc" (printf "%s and %s **not finalized**." ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "isTense"))) -}}
        {{- end -}}
      {{- end -}}
    {{- else if (gt (len ($scratch.Get "paramTypes")) 0) -}}
      {{- ($scratch.Set "fullDesc" ($scratch.Get "introClause")) -}}
      {{- with ($scratch.Get "contentSubject") -}}
        {{- ($scratch.Set "introClause" (printf "%s %s about %s and" ($scratch.Get "introClause") (index ($scratch.Get "grammar") "isTense") ($scratch.Get "contentSubject" ))) -}}
      {{- end -}}
      {{- range first 1 ($scratch.Get "paramTypes") -}}
        {{- if (eq . "1date") -}}
          {{- if $.PublishDate -}}
        {{- if (ne (string $.PublishDate) ("0001-01-01 00:00:00 +0000 UTC")) -}}
          {{- ($scratch.Set "fullDesc" (printf "%s was **released on %s**," ($scratch.Get "fullDesc") (dateFormat "January 2, 2006" $.PublishDate))) -}}
        {{- else -}}
          {{- ($scratch.Set "fullDesc" (printf "%s was **last updated on %s**," ($scratch.Get "fullDesc") (dateFormat "Jan 2, 2006" $.Date))) -}}
        {{- end -}}
          {{- end -}}
        {{- else if (eq . "2listItems") -}}
        {{- else if (eq . "3wordCount") -}}
          {{- ($scratch.Set "fullDesc" (printf "%s %s **%s words**." ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "hasTense") (string (index ($scratch.Get "pageParameters") .)))) -}}
        {{- else if (eq . "4readingTime") -}}
          {{- ($scratch.Set "fullDesc" (printf "%s %s estimated to take **%s minutes to read**." ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "isTense") (string (math.Round (mul (index ($scratch.Get "pageParameters") .) 1.2))))) -}}
        {{- else if (eq . "5isDraft") -}}
          {{- ($scratch.Set "fullDesc" (printf "%s %s <strong>not finalized</strong>." ($scratch.Get "fullDesc") (index ($scratch.Get "grammar") "isTense"))) -}}
        {{- end -}}
      {{- end -}}
    {{- else -}}
      {{- ($scratch.Set "fullDesc" ($scratch.Get "introClause")) -}}
    {{- end -}}
    {{- ($scratch.Get "fullDesc") | markdownify -}}
    

Style Partial Layouts

404 Layout

{{- define "main" -}}

<article>
    <h1 class="post-title">404</h1>
    <p>
	Sorry, we have misplaced that URL or it's pointing to something that
	doesn't exist.
    </p>
    <p>
	Head back <a href="/">Home</a> or use the <a href="/search/">Search</a> to
	try finding it again.
    </p>
</article>

{{- end -}}

Static

Themes

Appendices

Bibliography

Contributors

Index