Quick Install

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