Fix icon and logo to point to nodes
[Beorn] / README.markdown

🧸📔 Bjørn

A minimal static‐site generator with an emphasis on Atom feed generation.

Dependencies

🧸📔 Bjørn is written in Ecmascript and intended for use with Deno.

Usage

Assuming deno is installed on your computer, you can simply do :—

./build.js ❲path-to-my-blog❳

❲path-to-my-blog❳ is optional; if you don’t supply a path, the default is ..

You can (of course) also run the build script using deno run. Bjørn requires both --allow-read and --allow-write functionality for everything inside ❲path-to-my-blog❳.

Note that 🧸📔 Bjørn will silently overwrite existing index.xhtml files in the blog directory!!

Files and Locations

The feed metadata file (also used for generating the blog homepage) should be located at ❲path-to-my-blog❳/#feed.rdf. Entry metadata files (used for blogposts) are any files located at ❲path-to-my-blog❳/❲YYYY-MM-DD❳/❲identifier❳/#entry.rdf. It is recommended that you make ❲YYYY-MM-DD❳ the date of publication for the entry. ❲identifier❳ must not contain any characters not allowed in U·R·L’s (e·g spaces).

As the extensions of these files suggest, they are R·D·F∕X·M·L files. These can be a little cumbersome to write, but they are very easy to process and manipulate with tools, so they are a forward‐thinking format. Your feed.rdf file should probably look something like this :—

<awol:Feed
  rdf:about="https://blog.homepage.example"
  xml:lang="en"
  xmlns:awol="http://bblfish.net/work/atom-owl/2006-06-06/"
  xmlns:dc11="http://purl.org/dc/elements/1.1/"
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
  <dc11:title>My Cool Blog</dc11:title>
  <dc11:creator>
    <foaf:Person rdf:about="https://author.homepage.example" foaf:name="Me"/>
  </dc11:creator>
</awol:Feed>

The value of rdf:about on the root element needs to be the absolute U·R·L for your blog.

Your entry.rdf will look similar, but it needs a sioc:content property :—

<awol:Entry
  xml:lang="en"
  xmlns:awol="http://bblfish.net/work/atom-owl/2006-06-06/"
  xmlns:dc11="http://purl.org/dc/elements/1.1/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:sioc="http://rdfs.org/sioc/ns#"
>
  <dc11:title>A Sample Post</dc11:title>
  <sioc:content rdf:parseType="Markdown"><![CDATA[
Here is some *amazing* content!

I love it!
]]></sioc:content>
</awol:Entry>

In this case, the rdf:about can be automatically filled in based on the path to the entry from the blog root.

As you can see from the above example, 🧸📔 Bjørn supports a (nonstandard) Markdown value for rdf:parseType in addition to Literal. Some words of caution regarding this :—

  1. You should always put your markdown in a <![CDATA[ section.

  2. Your Markdown must process into valid X·M·L (not merely H·T·M·L), due to 🧸📔 Bjørn not really understanding the latter.

🧸📔 Bjørn uses rusty_markdown for its Markdown processing, which is CommonMark‐compliant.

Alongside the metadata files, there are two template files, index#feed.xhtml (used to generate the index page) and index#entry.xhtml (used to generate individual blogposts). Generated content will replace the first <bjørn-content> element. Metadata will be inserted into the <head> for you automatically.

Serving Content

You will need a file server which supports index files with a .xhtml file extension. A sample .rsync-filter might be as follows :—

- /.rsync-filter
-s .git
-s .gitignore
-s /README*
-s /build.js
-s /deno.json
-s index#*.xhtml
-s #*.rdf

Customization

Feel free to add styles, additional content, and whatever else you like to the template files (as well as the rest of the website).

Hooks

🧸📔 Bjørn recognizes the following hooks (defined on the global object) when it runs :—

Naturally, when running 🧸📔 Bjørn normally from the command line, all of these hooks are undefined. You can write your own small build script to define them, and run that instead :—

#!/usr/bin/env -S deno run --allow-read --allow-write
// custom_build.js

// Define your hooks first…
globalThis.bjørnTransformHead = (headElement, metadata, type) => {
  Array.from(headElement.children)
    .find(($) => $.localName == "title")
    .textContent += " | My Cool Site";
};

// Then run the script…
await import("./build.js");
This page took 0.237244 seconds and 5 git commands to generate.