Web setup

To build a website, you may need to:

  1. Copying static files and upload ‘production’ versions to your web server.

  2. Automatically watch files and compile HTML when the source is changed.

  3. Automatically reload the HTML preview when the HTML is compiled.

These can be done pretty easily with scripts, and here’s what I use:

Enable live previews for testing only

When setting up live previews, include the livereload script as follows:

~end_head: >-
  {% if env!="production" %}
    <script async src="/run/user/1000/livereload.js?host=127.0.0.1&port=35729"></script>
  {% endif %}

Now the live reload scripts will not be included if you compile it with:

md-to-html -o "env: production" .

Uploading to the webserver via git

Some servers (e.g. codeberg / github) allow you to commit to a repository and then serve all files. To use this create site-config.yaml as follows:

base_dir: .     # Directory where sources are relative to this file
dst_dir: pages  # Directory where targets go relative to this file

# List of source files / directories. If files are supplied on command line
# then this is ignored.
sources:
  - .

# directories to exclude recursing into (glob patterns OK)
exclude_dirs:
  - /pages

# Files to avoid processing (glob patterns OK)
#exclude_files: [README.md]

# Don't inline CSS / JS
standalone: false

# Default template for all documents
template: navright
~end_head: >-
  {% if env!="production" %}
    <script async src="/run/user/1000/livereload.js?host=127.0.0.1&port=35729"></script>
  {% endif %}

This sets the output to go into the pages directory. Setup this directory to be a git work tree with the branch you want to push to:

git worktree add --orphan -b pages pages

Now create your site for uploading

md-to-html -Pc site-config.yaml -o "env: production" -fv

(For local testing, omit the -o env=production option.) Upload the site using

git -C pages commit -a && git -C pages push

(On your first push you may have to specify the branch name via git -C pages push origin pages.)

Uploading to the webserver via RSync

First setup a filter list of files you want to include/exclude in .rsync-filter:

# rSync filter rules. First matching rule applies.

# Don't upload these
- no-upload
- preprocess.py
- .git/
- __pycache__/

# Upload these
+ *.html
+ *.jpg
+ *.png
+ *.css
+ *.js
+ *.pdf
+ *.csv
+ *.py
+ .htaccess

# Recurse into folders
+ */

# Exclude all files not handled above
- *

Now use a simple upload script:

#! /usr/bin/zsh

# Parameters
target=host:target_directory
md_to_html_args=(-c site-config.yaml -o "env: production" -dPfv .)
rsync_args=(-cav --delete --delete-excluded -FF)
# Rsync filter rules are in .rsync-filter

#Terminal color codes for error messages
RE=$'\e'"[0m" ER=$'\e'"[0;31m"

# Exit script if any command fails 
set -e

cd ${0:A:h}

# Re-render before uploading
md-to-html $md_to_html_args

# Warn if there are unreadable files
unreadable=($(find . -type f -not -perm /og+r))
if (( $#unreadable > 0 )); then
    echo "${ER}Warning unreadable files found: $unreadable${RE}"
fi

# Sync files
rsync $rsync_args ./ $target

Note, with the -d option if you rename a source .md file the old .html output will be deleted. If there are .html files you want protected use the protect_files / protect_dirs options