WARNING
This version of ssg
has been retired. Check the current version.
KNOWN ISSUE
If you use relative links on your pages (as I do),
rss.xml
won’t render them properly.
Tested on OpenBSD 6.3
ssg1 is a static site generator written in shell and powered by lowdown(1), rsync(1), and entr(1).
It generates a site from HTML and Markdown articles.
.*
and _*
,index.html
,<h1>
tag from every article to generate a
sitemap and use it as a page title,$DOCS/
.240 LoC. Enlarge, enhance, zoom!
ssg1
is one hundred times smaller than Jekyll.
ssg1
and its dependencies are about 800KB combined. Compare that
to 78MB of ruby with Jekyll and all the gems. So ssg1
can be
installed in just few seconds on almost any Unix-like operating
system.
Obviously, ssg1
is tailored for my needs, it has all features I
need and only those I use.
Keeping ssg1
helps you to master your Unix-shell skills: awk
,
grep
, sed
, sh
, cut
, tr
. As a web developer you work with
lots of text: code and data. So you better master these wonderful
tools.
100 pps. On modern computers ssg1
generates a hundred pages
per second. Half of a time for markdown rendering and another half
for wrapping articles into the template. I heard good static site
generators work—twice as fast—at 200 pps, so there’s lots of
performance that can be gained. ;)
If you agree with the license, feel free to use this script, its HTML and CSS or/and re-write them for your needs.
Install dependencies and download ssg1
. For example, on OpenBSD:
as root install rsync(1), lowdown(1), and entr(1).
# pkg_add rsync-3.1.3-iconv lowdown entr quirks-2.414 signed on 2018-03-28T14:24:37Z rsync-3.1.3-iconv: ok lowdown-0.3.1: ok entr-4.0: ok The following new rcscripts were installed: /etc/rc.d/rsyncd See rcctl(8) for details. #
Then as a regular user change into ~/.bin
directory.
$ cd ~/.bin $ ftp https://www.romanzolotarev.com/bin/ssg1 Trying 140.82.28.210... Requesting https://www.romanzolotarev.com/bin/ssg1 100% |****************************************| 7257 00:00 7257 bytes received in 0.00 seconds (2.99 MB/s) $ chmod +x ssg1 $
Let’s customize your ssg1
setup.
To configure ssg1
you need to set two variables:
$DOCS
- path to web server document root directory$ROOT
- root URL of your web siteThere are three more variables, but these are optional:
$WEBSITE_TITLE
- title (suffix) for all pages$RSS_AUTHOR
- author’s full name for RSS feed$RSS_DESCRIPTION
- RSS feed descriptionYou can set all those variables in enviornment with export
or
env
, but I recommend to create _ssg.conf
file. For example, here
is mine:
#!/bin/sh
: "${DOCS:=/var/www/htdocs/www.romanzolotarev.com}"
ROOT='https://www.romanzolotarev.com'
WEBSITE_TITLE='Roman Zolotarev'
RSS_AUTHOR='hi@romanzolotarev.com (Roman Zolotarev)'
RSS_DESCRIPTION='Personal website'
Note: in this example if $DOCS
is set, then ssg1
uses the original
value, not the value from _ssg.conf
.
There is only one file required:
index.html
or index.md
- home pageExample of index.md
:
# Jack
- [About](/about.html "01 Aug 2016")
ssg1
renders index.md
to index.html
and then generates the RSS feed
based on first 20 links, if they have the following syntax (it only uses
page URL and date from <a>
tag):
...
<li><a href="/about.html" title="01 Aug 2016">About</a></li>
...
_header.html
- header of every page_footer.html
- and its footer_styles.css
- styles, take mine and customizeIf you use my CSS, don’t forget to wrap the content of _header.html
into <div class="header>...</div>
and the content of _footer.html
into <div class="footer>...</div>
.
There are also reserved filenames, these files are generated when you run
ssg1 build
. Don’t use these names.
rss.xml
- reserved for RSS feedsitemap.xml
- for the sitemapLet’s create about.html
with one header and some text about your site.
# About this site
...
ssg1
converts all .md
article into .html
and then uses content of the
first <h1>
tag as a page title.
Nota bene: Don’t use =====
in titles.
Now we are ready to build. If your current source directory looks like this:
.
|-- .git/
|-- _footer.html
|-- _header.html
|-- _styles.css
|-- about.md
`-- index.md
After you run ssg1
(don’t forget to set $DOCS
):
$ ssg1 build building /var/www/htdocs/www 2018-04-10T10:56:52+0000 4pp $
You have your static website ready in /var/www/htdocs/www
.
.
|
|-- about.html
|-- index.html
|-- rss.xml
`-- sitemap.xml
For OpenBSD I suggest to run httpd locally.
For macOS and Linux you can run:
$ cd /var/www/htdocs/www $ python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000...
To re-build pages on change run:
$ ssg1 watch watching /home/jack/src/www building /var/www/htdocs/www 2018-04-10T11:04:11+0000 4pp
entr(1) watches changes in *.html
, *.md
, *.css
, *.txt
files and
runs ssg1 build
on every file change.
If you’d like to delete all files in the destination directory during build, then run:
$ ssg1 build --clean building /home/jack/src/www/docs --clean 2018-04-16T09:03:32+0000 4pp $
The same option works for watching.
$ ssg1 watch --clean watching /home/jack/src/www building /home/jack/src/www/docs --clean 2018-04-16T09:04:25+0000 4pp
If you don’t have a public server yet, try Vultr. To deploy to remote server you can use rsync(1) like this:
$ rsync -avPc /var/www/htdocs/www \ www.example.com:/var/www/htdocs/
Or if you want to clean up the target directory on the remote server use:
$ rsync -avPc --delete-excluded \ /var/www/htdocs/www \ www.example.com:/var/www/htdocs/ $
As root install rsync(1) and lowdown(1) packages on that server.
# pkg_add rsync-3.1.3-iconv lowdown quirks-2.414 signed on 2018-03-28T14:24:37Z rsync-3.1.3-iconv: ok lowdown-0.3.1: ok The following new rcscripts were installed: /etc/rc.d/rsyncd See rcctl(8) for details. #
Then as git
user download ssg1
on the server:
# cd /home/git # su git $ mkdir -p /home/git/bin $ cd /home/git/bin $ ftp https://www.romanzolotarev.com/bin/ssg1 Trying 140.82.28.210... Requesting https://www.romanzolotarev.com/bin/ssg1 100% |****************************************| 7257 00:00 7257 bytes received in 0.00 seconds (2.99 MB/s) $ chmod +x ssg1 $
Then add these lines to /home/git/REPOSITORY.git/hooks/post-receive
:
#!/bin/sh
TMPDIR="$(mktemp -d)"
git archive --format=tar HEAD | (cd "$TMPDIR" && tar xf -)
cd "$TMPDIR"
DOCS='/var/www/htdocs/www.romanzolotarev.com' \
/home/git/ssg1 build --clean
As root make sure git
user owns $DOCS
directory:
# chown -R git:git /var/www/htdocs/www.romanzolotarev.com $
Thanks to
Denis Borovikov for reading the draft of this,
h3artbl33d, and
Mischa Peters, and
Tom Atkinson for testing ssg1
,
Kristaps Dzonsons for
lowdown(1) and
Eric Radman for
entr(1).