Echo Writes Code

README.md

web-pylon: a personal website backend

Not quite a static site generator, not quite a full CMS: web-pylon is a minimalistic website backend that lets you quickly get a personal website up and running with minimal fuss.

Features

  • Read-only: web-pylon is designed to never write anything to a file, other than system logs. You can trust that web-pylon will never write over your data, and that if any exploits are found in web-pylon's source code or dependencies, they won't be able to alter any system files.
  • Static database: One of the biggest draws of static site generators is that there is no complicated database setup. The tradeoff for this is that metadata, such as page titles, must be embedded in the pages themselves. Instead of either of these approaches, web-pylon uses a static database: a JSON file that describes everything about how your site is laid out. This enables web-pylon to have access to individual properties about specific pages without loading the entire page into memory, but also means you don't need to fiddle with setting up MySQL just to run a simple website.
  • Fully customizable: web-pylon asks only that you provide a page template, a list template, an _index.md page, and a static directory; the rest is up to you. Sample templates and stylesheets are distributed with web-pylon, but you are free to change them as much as you like to get your site looking just right.
  • Markdown and HTML: Author most of your content in Markdown, but drop to HTML in the page itself, or even customize the Tera and HTML template files if you need more power.
  • Written in Rust: Common attacks on languages that are distributed in source form won't work on web-pylon, because it's a compiled binary. This also means web-pylon is generally more performant than systems reliant on a scripting language like Python or PHP.

Building

You must have a recent version of the Rust toolchain installed.

Simply run a build in release mode:

$ cargo build --release

The web-pylon binary will be in the target/release directory.

Installing

You will need a Linux server with some kind of reverse-proxy web server installed. I recommend nginx.

  1. Create a folder /opt/web-pylon
  2. Copy the web-pylon binary to /opt/web-pylon/bin
  3. Copy the server/lib directory to /opt/web-pylon/lib
  4. Copy the server/web-pylon.example.toml file to /opt/web-pylon/web-pylon.toml.
  5. Create a directory readable by your web server that will hold your website content. Copy the contents of the sample folder (not the sample folder itself) to this directory.
  6. Edit /opt/web-pylon/web-pylon.toml to configure web-pylon for your machine. At the absolute minimum, you must set the content.root property to the directory you created in the previous step.
  7. Change the ownership of /opt/web-pylon and everything inside it, and also your content root, to be owned by your web server user (e.g. www or www-data, depending on your distro).
  8. Create a link from /etc/systemd/system/web-pylon.service to /opt/web-pylon/lib/systemd/system/web-pylon.service.
  9. Start the web-pylon service.

Customizing

After step 5 in the previous section, your content root will have the following structure:

metadata.json
content/
	pages/
		_index.md
		about.md
		cv.md
	posts/
		sample-post.md
static/
	stylesheets/
		theme.css
templates/
	_base.tera.html
	list.tera.html
	list_atom_feed.tera.xml
	page.tera.html
	post.tera.html

You are free to edit any of these files; the only hard requirements are that you have a metadata.json, content/_index.md, and the files in the templates directory.

Authoring

web-pylon uses a combination of the metadata.json file (the static database) and the Markdown files in the content folder to build the structure of your website.

Pages

Pages are for static content that isn't really part of an overarching structure, besides the site itself. Three example pages are included with the sample content: a home page (_index.md), an "About" page, and a CV page.

To create a new page, first add an entry in the pages array in metadata.json:

{
	...

	"pages": [
		...

		{
			"name": "My New Page",
			"slug": "my-new-page"
		}
	]
}

You can optionally add this page to the menu array, if you would like it to be accessible in the site.menu template variable.

Then, simply create a Markdown file in the content/pages directory named my-new-page.md:

# My New Page

Wow! Markdown!

- Here's
- A
- List

[Links work too](https://example.com/)

[Here's a link back to the home page](/)

[And here's a link to this page](/page/my-new-page)

Then restart the web-pylon service to reload the static database:

$ sudo systemctl restart web-pylon

Posts

Posts are meant to be serialized, like a social media timeline. They don't have to be short or barebones, but they are designed to form an ordered history; think of it kind of like an old-school blog.

Posts are composed exactly the same way as pages, except the metadata goes in the posts array of the static database, and the content file goes in the content/posts directory.

Posts require a little bit more metadata than pages:

  • A publish date and an update date. These have to be specified in RFC 3339 format, which looks like this: YYYY-MM-DDTHH:MM:SS+ZH:ZM (or YYYY-MM-DDTHH:MM:SSZ for UTC).
  • A syndication ID. This is used to generate Atom feeds of your posts so that your visitors can subscribe to you in an RSS reader. You can use any globally-unique ID for this value, but it is recommended to use a "tag URL", which is a string in the following format: tag:yourdomain.name,YYYY-MM-DD:/posts/your-post-slug