div0 icon

← Go to page index ←

One File Site

This page was last updated on 2023.07.05.

One File Site is a Common Lisp script written by Izak Halseide that can be used to generate directories and HTML files from a given single text file. The script also supports text pre-processing for template replacements in order to reduce redundancy and increase site consistency of appearance.

Most of the content here, on div0.com is generated by this script. The only pages and media on div0.com that are not generated by one file site are the SaladFrosting Wiki, some downloadable files, and images. Even the separate CSS files are generated!

The source code can be found on GitHub: https://github.com/ihalseide/one-file-site

Explanation

The script takes one text file containing a bunch of markup, and may create files and directories in the file system. Also, the script copies all of the directories and sub-directories present in the given file's containing directory (and this behavior is subject to improvement). The script is not a valid HTML parser, rather it just looks for lines in the given file that start with certain tags. These are the tags that the script knows about and parses:

By the way these tags should not be nested if you want them to work properly.

A templated page is denoted by opening and closing <t-page> tags. The tag also requires a title attribute and a target attribute to be considered valid. The title is the page's title, which is required because I wanted all of my pages to define a title to show up in the HTML document's <title> tag. The target is the file path relative to the source file where the output from this templated page will be written to. The target can be named almost anything, so be careful, but this also allows generating non-HTML files for the website, such as CSS. Warning: if a file at the page's target path already exists, it may be overwritten! The text between to opening and closing tags is the page's content. The content is literally the data which will be written into the target file when the script runs. This means that if it is for an HTML page, it should include all of the required HTML tags. However, writing this all the time is tedious, so bring in the templates!

A template is denoted by opening and closing <template> tags. The tag requires a title attribute in order to be considered valid. The text between the opening and closing tags is the text that instances of this template can be replaced with. The script remembers this new association of the template's title with the content text, at a global scope, that is, for all pages.

The following is how templates work. Within the content of templated pages (or even templates), a template replacement token may appear. A template replacement token is the name/title of a template prefixed with an equals sign and surrounded by double curly brackets. For example, this is how to include the page's title: {{=title}}. The replacement text (which is defined in <template> tags) may also contain nested template replacement tokens, so the script processes these up to depth limit (which I believe is 3 by default).

There is one more way to define templates for use within templated pages, at a local scope. Any attributes defined within the starting <t-page> tag is really the definition of a template replacement. So the title attribute within templated pages really defines a template to replace instances of {{=title}}. Additional attributes and thus template replacements may be added to the <t-page> tag, as long as they do not contain line breaks or double quote characters.

Future plans

A <copy> tag may be added in the future. This tag tells the script to recursively copy the contents of the target path to the destination. It could be better to explicitly tell which paths to copy from the parent of the given file instead of the default behavior, which is to copy everything.

Also, the file copying behavior could be massively improved if the script kept track of the write times or checksums for each of the files so that it could tell if a file changed and needs to be re-copied.

↑ Return to top ↑