Publising static sites from iPad using BSSG and Working Copy
iPad BSSG and Working Copy works together.
This post is the result of my digging in iPad utilities and nice BSSG static site generator created by Stefano Marinelli. In last few weeks I testetd some tools to create environment for small programming tasks on iPad. When Stefano published BSSG, I thought that it could be nice to connect together all that things to make "publishing system with managed source on iPad".
I will focus on using a few packages:
- Working Copy - iPad Git environment (some functions require buying the app, but in my opinion it is worth of that)
- iWriterPro - iPad markdown editor (I use it but probably any other markdown editor also will be good, even Working Copy alone - it has simple programmers editor).
- BSSG - Bash Static Site Generator - available to download from git repo, requires standard Unix tools (grep, sed, awk) and one of markdown formatters (cmark, pandoc or markdown.pl)
How to publish static site using iPad and BSSG
Using markdown tools seems to be very popular today as also many diferent tools exixts for that. As Unix user for last 30 years with sentiment remeber old tools troff/nroff used to create all system documentation by preparing everything in terminal window and run only one command (or command pipeline if something should be printed on PS printer). The markdown technology is near of that old methods.
Today I'm also user of iPad - the main driver of many my daily tasks, which equipped with good keybord, is nice tool to prepare text, browse code and automate/control different processes.
BSSG is set of Unix scripts and web templates, converting markdown documents and css styles into nice static site which can be deployed on practically each standard web server. Driven by main script bssg.sh
produces as output set of artifacts which has to be transfered in dedicated place of web server file system. For details please loook into BSSG documentation.
Important thing for presented solution is that configuration of BSSG generated site is defined in local config file which is just bash code. It defines places where BSSG engine is looking for data (markdown files, css, templates), where to put results and many default settings for site in general. To create the final output, user must run main script with option build
. Path to the configuration is provided as script argument --config
or inside environment variable BSSG_LCONF
.
Prepare project subdirectory
To create environmet for new site contetent, first stage must be preparing directory structure on some Unix system (may be different than target system). It may be done by setting ssh session, installing (clonning) BSSG and execute bssg.sh
script with init command pointing to the directory dedicated for site project (see BSSG documetation).
./bssg.sh init ~/Sites/bssg-example
The project will be managed as git repo. I use private Forgejo instance on FreeBSD server, and always generate there empty repo and connect it with locally created project, but local repo also may be used. There is only one condition - possibility to connect via ssh from an iPad to that local repo.
cd ~/Sites/bssg-example
git init
Git don't include empty directories (and BSSG project in the begining has most of subdirs empty), so I put (touch) each subdirectory with empty file .empty
touch src/.empty
touch pages/.mepty
touch drafts/pages/.empty
touch static/.empty
After this git will add also that dirs
git add *
Commit to save all files in repo
git commit -m "First commit"
Now Working Copy (iPad Git environment) can clone the repository and save all files on local iPad storage. Next stages can be done directly from iPad using Working Copy (after clonning into iPad files system).
Generate website
To generate static content user has to call build.sh
with command build
pointing to local configuration for the site (see BSSG documentation).
cd ~\BSSG
./bssg.sh build --config ~/Sites/bssg-example/config.sh.local
In normal way config.sh.local looks like:
#!/usr/bin/env bash
#
# Local configuration for BSSG site created from input: '/home/user/Sites/bssg-example'
# Resolved absolute path: /home/user/Sites/bssg-example
# Generated by: bssg init
#
# Refer to the main 'config.sh' file in your BSSG installation
# for a complete list of available configuration options.
#
# --- Content Directories (Using path format provided during init: '~/Sites/bssg-example') ---
# Note: Tilde (~) expansion will occur when this file is sourced by the shell.
PAGES_DIR="~/Sites/bssg-example/pages"
DRAFTS_DIR="~/Sites/bssg-example/drafts"
STATIC_DIR="~/Sites/bssg-example/static"
OUTPUT_DIR="~/Sites/bssg-example/output" # Site output directory
# --- Site Specific Overrides (Examples) ---
# SITE_TITLE="BSSG example site"
SITE_URL="https://obsidian.vctl.net/bssg"
THEME="text-only"
For presented solution the part defining locations has to be changed by superseding prefix directory (here ~/Sites/bssg-example) by external environment variable BSSG_PROJ
. The value for that will be provided by external script runs "on demand" from Working Copy application.
SRC_DIR="$BSSG_PROJ/src"
PAGES_DIR="$BSSG_PROJ/pages"
DRAFTS_DIR="$BSSG_PROJ/drafts"
STATIC_DIR="$BSSG_PROJ/static"
OUTPUT_DIR="$BSSG_PROJ/output"
All changes here can be done directly from Working Copy.
Creating and publicing entries
Many different tools can be used to create/edit markdown files, but before it, sanboxed apps have to have access to files owned by Working Copy. System give such possibility by using external folders (aka document picker) and after enable it in Files application, repositories from Working Copy will be visible as subdirectories in Files app and documents can be read by other applications.
One of nice editing tools is iWriterPro, which read markdown files and present in nice, readable form during edition and in preview mode. One problem is when some file is modified outside program, to refresh document I have to select files view and read it again.
Another option is using internal editor from Working Copy, especially if someone prefer classical programmer editor view. There is also preview mode (from top right menu in editor) presenting document in HTML view.
BSSG expects special document structure with metadata in the beginning as yaml format, but in it lacks required information, reasoned default is provided. BTW many editors gives machanizm of templates, which can autofill such header. The yaml seems to don't disturb syntax highliting of markdown text. Placement of etntities in subdirectories matters when output is prepared(pages, weblog, drafts etc.), but it doesnt matter in process of edition of documents. Only names of files in weblog determine
After edition of source files time to prepare output for http server. This part requires installed BSSG and tools and of course cannot be done in normal way on ipad, external environment is required. In my case it is OpenBSD instansce on OpenBSD Amsterdam server with running OpenHTTPD server and installed (via git clone) current version of BSSG. But how to execute all required tasks? First idea was to run remotely git clone on target system, and then call bssg.sh script. But it require valid config file with local static path to all subdirs. Not good.
Using Working Copy command to prepare (and optionally deploy) site data
Working Copy has machanism "Run Command" on remote server:
- Transfer all changed files from selected subdirectory of repo to target system
- For target system transfer will be done to defined in Working Copy target subdirectory (by default related to home directory of remote user)
- Execute command via ssh. It may be any executable command in file system to which remote user has access. Particulary it may be shell script included in repo and transfered in previous step.
- Get results from executing command back to the ipad (log file) and synchronize all files changed on remote host to the repo of Working Copy. There is possibility to exclude files and directories from transfer by defining them in special file .sshignore (in top of repo). I don't see any reason to transfer back genereted content (output) so this part was put in exclude list.
If the config file will be prepared dynamically and setup target directories to place where all files will be transfered, script should work correctly and all data will be prepared in pointed output directory.
For such behavior project have additional bash script - the worker:
#!/bin/sh
export BSSG_PROJ="$(pwd)"
export BSSG_LCONF="$BSSG_PROJ/config.sh.local"
# echo Config: $BSSG_LCONF
# Excute BSSG
echo "========================================="
echo "EXECUTE BSSG"
cd ~/BSSG
SAVEPDW=$OLDPWD
./bssg.sh build
cd $SAVEPWD
# refresh www subdir
echo "========================================="
echo "SYNC SITE FILES"
echo
doas ~/bin/sync_bssg_site.sh $BSSG_PROJ
The script assume that BSSG was installed in home directory under BSSG/ and configuration file will be provided as environment variable. Because configuration has to point to real file, there are two environment variables:
BSSG_PROJ
- points to main subdirectory, defined as remote in Working Copy, where all files will be transfered and which is an anchor for the rest of the pipeline and is the place where script will be runningBSSG_LCONF
- defined internally by BSSG pointing to configuration file, sourced by bssg.sh script.- Configuration file is sourced bash file and use in evaluation variable
BSSG_PROJ
provided by main worker script - bssg.sh have to be run from inside of distribution directore, sourced before run, cd-ing there is required
- Last part of script is executing syncing process, transfering all files from output directory to the target subdirectory of www server. It can be done on may different ways, here is my small, internal solution.
In may case remote directory for command was defined as workcopy/bssg-site, which is relate to home direcory of remote ssh user. Local directory for commadn is set to empty, what means that it is related to top of git repo on iPad. All (changed on iPad) files from local directory will be transfered to remote directory before executing script, which also is transfered this way. The next stage is executing command, which is defined in Working Copy as name of script ('./make_bssg_site.sh') with current directory set to remote directory set in Working Copy.
The last step, syncing files script, is not part of git repo, but locally defined script, because of doas mechanizm authorization and access rights required to do sync operation. It must be prepared independly.
After all Working Copy can do commit and push to external repository to save current status of project (together with dynamic configuration and working script).
Summary
This post was produced and deployed (many times) using above procedure. After intial setup (create project using bssg.sh init) no any other direct ssh session to target server was done. It seems to be nice usage of iPad only environment to publish static content for example "on the road" and use git to manage versions.
I see also big potential in remote command of Working Copy to setup new environment, done temporary tasks etc.