Quick Install

One command is all you need to start a new website.
wget -qO - https://go.habd.as/after-dark | sh

Run the above command in a terminal emulator after installing Hugo to start a new website in 5-10 seconds. Hugo version 0.51 or greater required.


After Dark includes a portable installation script for quick set-up. Please install Hugo 0.51 or greater before running:

Expand to view script
  1#!/bin/sh
  2
  3set -e
  4
  5#
  6# Copyright (C) 2019  Josh Habdas <jhabdas@protonmail.com>
  7#
  8# This file is part of After Dark.
  9#
 10# After Dark is free software: you can redistribute it and/or modify
 11# it under the terms of the GNU Affero General Public License as published
 12# by the Free Software Foundation, either version 3 of the License, or
 13# (at your option) any later version.
 14#
 15# After Dark is distributed in the hope that it will be useful,
 16# but WITHOUT ANY WARRANTY; without even the implied warranty of
 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18# GNU Affero General Public License for more details.
 19#
 20# You should have received a copy of the GNU Affero General Public License
 21# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 22#
 23
 24validate_hugo () {
 25   # Exit with error if hugo is not installed
 26   if ! hash hugo 2>/dev/null ; then
 27     echo "Error: After Dark requires Hugo version 0.51 or greater" >&2; exit 1
 28   fi
 29
 30   # Exit with error if not minimum required hugo version
 31   re="v(0\d*\.([5-9][1-9]|[6-9])|[1-9]).*"
 32   if ! hugo version | grep -qE "$re" ; then
 33      echo "Error: After Dark requires Hugo version 0.51 or greater" >&2; exit 1
 34   fi
 35}
 36
 37create_site_dir () {
 38   SITE_DIR="flying-toasters"
 39   if [ "$1" != "" ] ; then
 40      SITE_DIR="$1"
 41   fi
 42
 43   SITE_DIR_ABS="$PWD/$SITE_DIR"
 44   mkdir -p "$SITE_DIR"
 45}
 46
 47create_site () {
 48   echo "Creating a new Hugo site ..."
 49   hugo new site "$SITE_DIR" 1>/dev/null
 50   cd "$SITE_DIR" || exit 1
 51}
 52
 53download_theme () {
 54   echo "Downloading the latest version of After Dark ..."
 55   LATEST_META=$(wget -qO - https://registry.npmjs.org/after-dark/latest)
 56   vers=$(echo "$LATEST_META" | grep -oE "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
 57   mkdir -p themes/after-dark
 58   wget -qO - https://registry.npmjs.org/after-dark/-/after-dark-"$vers".tgz | tar --strip-components=1 -xz -C themes/after-dark
 59   echo "Version $vers downloaded to $SITE_DIR/themes/after-dark"
 60}
 61
 62download_module () {
 63   [ -z "$1" ] && { echo "Error: Attempt to download undefined module" >&2; exit 1; }
 64   echo "Downloading $1 module for After Dark ..."
 65   meta=$(wget -qO - https://registry.npmjs.org/"$1"/latest)
 66   vers=$(echo "$meta" | grep -oE "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
 67   mkdir -p themes/"$1"
 68   wget -qO - https://registry.npmjs.org/"$1"/-/"$1"-"$vers".tgz | tar --strip-components=1 -xz -C themes/"$1"
 69   echo "Version $vers downloaded to $SITE_DIR/themes/$1"
 70}
 71
 72configure_theme () {
 73   echo "Configuring basic After Dark theme settings ..."
 74   tee "config.toml" > /dev/null <<TOML
 75baseurl = "https://domain.example" # Controls base URL sitewide
 76languageCode = "en-US" # Controls site language
 77title = "After Dark" # Homepage title and page title suffix
 78paginate = 11 # Number of posts to show before paginating
 79copyright = "Copyright &copy; Copyright Owner. Licensed under <a target=\"_blank\" rel=\"external noopener license\" href=\"https://creativecommons.org/licenses/by-nd/4.0/\">CC-BY-ND-4.0</a>." # Optional, remove to suppress copyright notices
 80
 81# Controls default theme and theme components
 82theme = [
 83  "fractal-forest", # OBSD
 84  "after-dark" # AGPL-3.0-or-later
 85]
 86
 87disableLiveReload = false # Optional, set true to disable live reload
 88enableRobotsTXT = true # Suggested, enable robots.txt file
 89sectionPagesMenu = "main" # Enable menu system for lazy bloggers
 90
 91[markup]
 92  defaultMarkdownHandler = "blackfriday"
 93  [markup.blackfriday]
 94    footnoteReturnLinkContents = "↩" # Provides a nicer footnote return link
 95  [markup.highlight]
 96    noClasses = false # Required for custom syntax highlighting
 97
 98[params]
 99  description = "" # Suggested, controls default description meta
100  author = "" # Optional, controls author name display on posts
101  hide_author = false # Optional, set true to hide author name on posts
102  disable_csp = false # Optional, set true to disable content security policy
103  images = [
104    "https://source.unsplash.com/collection/983219/2000x1322"
105  ] # Suggested, controls default Open Graph images
106
107[params.layout.menu.main]
108  hidden = true # Optional, set false or remove to show section menu
109
110[params.layout.footer]
111  hidden = false # Optional, set true to hide footer
112
113[params.modules.fractal_forest]
114  enabled = true # Optional, set false to disable module
115  decoders = ["bpgdec8a"] # Optional, 8-bit javascript decoder with animation
116TOML
117}
118
119update_archetypes () {
120   echo "Updating the default content archetype ..."
121   rm -f archetypes/default.md
122   cp themes/after-dark/archetypes/default.md archetypes
123}
124
125create_welcome_post () {
126   echo "Creating welcome post ..."
127   hugo new post/welcome.md 1>/dev/null
128}
129
130serve_site () {
131   echo "Starting site server ..."
132   hugo serve --buildDrafts --navigateToChanged --port 1313 1>/dev/null &
133}
134
135generate_help_docs () {
136   echo "Generating help documentation ..."
137   THEME_PATH=themes/after-dark
138   meta_path="$THEME_PATH"/data/npm
139   mkdir -p "$meta_path" && echo "$LATEST_META" | tr '\r\n' ' ' > "$meta_path"/latest.json
140   cd "$THEME_PATH"/docs && mkdir themes && ln -s ../.. "$THEME_PATH"
141   hugo new validate.md --kind validate 1>/dev/null
142}
143
144serve_help () {
145   echo "Starting help server ..."
146   hugo serve --disableLiveReload --port 1414 1>/dev/null &
147}
148
149echo "Welcome to the After Dark quick installer. Press CTRL-C at any time to abort."
150
151validate_hugo
152create_site_dir "$1"
153create_site
154download_theme
155update_archetypes
156download_module "fractal-forest"
157configure_theme
158create_welcome_post
159serve_site
160generate_help_docs
161serve_help
162
163YELLOW='\033[0;33m'
164NC='\033[0m'
165
166printf "${YELLOW}Installation successful!${NC}\n"
167echo "Site created in $SITE_DIR_ABS"
168echo "Site server started at http://localhost:1313/"
169echo "To stop it run \"kill \$(ps aux | awk '/[h]ugo.*1313/ {print \$2}')\"."
170echo "Help server started at http://localhost:1414/"
171echo "To stop and restart it run \"./themes/after-dark/bin/help\"."
172echo "Thank you for choosing After Dark."

Script has been tested on GNU/Linux, BSD (Darwin) and Windows via Cmder.

Warning: Examine scripts downloaded from the Internet before running them.

Here are three methods for downloading and running:

  1. Download and pipe to sh directly:

    wget -qO - https://go.habd.as/after-dark | sh
  2. Download into new file, chmod and execute:

    curl -O https://cdn.jsdelivr.net/npm/after-dark@latest/bin/install && \
    chmod +x install && ./install
  3. From canonical git clone:

    # clone source and change to source directory
    git clone https://git.habd.as/comfusion/after-dark.git && cd "$_"
    
    # use npm cli to get the release hash
    echo "${$(npm run integrity)#*sha512-}"
    
    # run quick install after validating
    ./bin/install

Script should complete in 5-10 seconds resulting in a sample site and help docs:

After Dark screenshots
After Dark Quick Install running to completion in Terminal on Deepin Manjaro.

Your new site will be called flying-toasters. Change it to the name of your project anytime you like. Access site by navigating to https://localhost:1313.

Multi-site Configuration (Advanced)

After Dark enables multi-site management from a single installation. To manage multiple websites use the -c and -d flags to specify the content and destination directories, respectively.

For example, to generate an audio site using the current After Dark installation create an executable script to generate the site:

flying-toasters/bin/gen-audio-site
#!/bin/sh
hugo -c sites/audio -d public/static.domain.example

Where audio contains the content for that site:

├── layouts
├── sites
│   └── audio
│       ├── audiobooks
│       │   ├── gaining-currency.md
│       │   └── the-power-of-now.md
│       └── clips
│           └── war-of-the-worlds.md
├── static

And public contains a folder for each site:

public
└── static.domain.example
    ├── categories
    │   └── index.xml
    ├── audiobooks
    │   └── index.html
    ├── clips
    │   └── index.html
    ├── css
    ├── index.html
    ├── index.xml
    ├── js
    ├── sitemap.xml
    └── tags
        └── index.xml

And create another script to serve the content for editing:

flying-toasters/bin/serve-audio-site
#!/bin/sh
hugo -c sites/audio

Each subdirectory of public then becomes an independent, deployable website and exact copy save for destination content generated.

Tip: For additional flexibility type hugo --help and modify your scripts using the --theme and --config flags.

Multi-site is perfect for maintaining a consistent look-and-feel across multiple domain origins while limiting the need to run the Upgrade Script for each site.