/vimwiki-publishing-system

Programs/scripts to help with publishing websites using vimwiki as an authoring environment.

Primary LanguageHaskellGNU General Public License v3.0GPL-3.0

vimwiki-publishing-system

(Note the name is probably going to change).

The premise: allow writing in vimwiki, and publish as a static website.

So it's a site producer that uses files according to a site.yaml or similarly named file. This is much more interesting as it forms the basis for generating arbitrary sites from pages that can be authored (and linked) in vimwiki. It also means that other editors could be used, which might make it useful for other people.

Thus there is one executable generated by this application:

  • sitegen -- use a site.yaml to generate a set of HTML files from the files within the same wiki doc. Use the -h option to see the various options.

Current State

So it started out as an itch to scratch. I wanted to edit my website 'pages' in (n)vim but also have a sense of being able to organise the pages using a wiki style. But the output didn't need to reflect that.

So I could have used Hakyl, but I also wanted to build something using Polysemy. And, as I am also a Python programmer, I wanted to try out Ginger templates, which are a (really good) emulation of the Jinga2 in Haskell. This meant that a single binary, a yaml file and a bunch of markdown files is all that is needed to generate a site.

It's also likely that once it's "good enough" for my usage that I'll probably stop working on it, except when I need a new feature. However, once it's more finished, I'd be happy to accept pull requests!

What works

  • Generating source files and index pages (with custom selections of pages)
  • Tags and Categories (as two different taxonomies). It'd probably be useful to just make these general, but we're not there yet.
  • 404 custom page
  • Atom /feed.atom (but not configurable)
  • Theme file and overrides.
  • Site overrides of theme files.
  • Placing output wherever you want in the hierachy.
  • Cleaning up output when files change (e.g. if the file shouldn't exist after the site is rendered, then it can be deleted.)
  • Ginger (Jinja2 compatible) templates for pages.
  • Table-of-Contents generation (although it's not heavily tested)
  • Rich and plain content possible.
  • Syntax highlighting using Skylight and Pandoc.
  • Pandoc Markdown with most of the options turned on.
  • Draft pages (by default)
  • Resolving links (and removing ones that point to drafts or inaccessible pages).

What is still on my todo list

  • Document how to make it all work.
  • Do less work; detect when things haven't changed.
  • Generate a sitemap.xml file for the site as needed.
  • Have a 'server' mode for use when writing files. i.e. something that will serve files and regenerate on demand for a browser.

The Site generator

How do you work with it?

The user creates and edits pages as normal in Vimwiki pages and links. i.e. It looks like a normal wiki of interconnected pages. Vimwiki can navigate around those pages assuming it is configured appropriately. Vimwiki can also 'publish' those pages using VimwikiAll2HTML which would convert every page. In this case, the vm2html would just remove the sitegen specific page config and generate individual wiki pages.

Note: vw2html is another program that can convert pages. It will eventually get the option to drop the page header (which it doesn't at present).

However, if there are no sitegen config sections on any pages, then no site will be generated (apart from, perhaps, the index page, but with no content).

But first there must be a site.yaml. Then pages that should be published in the site must have a sitegen config section at the top of the page to indicate that it should be included in the site.

The site.yaml config file

The configuration/control for the site build will be in a yaml file. This will specify the source and destination directories, how different parts are mapped and what features are enabled in the site build. Also, the location of template files, and how they are controlled.

e.g.

# key/values available in the site's YAML document
# the values provided are the default values
---
site: <site-identifier>
source: ./src  # the directory (relative, if wanted, to the site.yaml) to start
               # looking for sitegen pages.
output-dir: ./html
extension: .md # the extension of files that may be sitegen page parts
index-page-name: index # string representing the custom page name for the index
templates-dir: ./templates # directory to find templates
template-ext: .html.j2  # the extension used for templates
static-dir: ./static    # where the statics that get copied to the site live;
                        # e.g. CSS and JS files.
index-files: True       # generate thing/index.html rather than thing.html
generate-tags: true  # should sitegen generate a tags page
generate-categories: true  # should sitegen generate categories

See ./src/Lib/SiteGenConfig.hs for more details.

The sitegen header in the page

For a page to be recognised by sitegen it needs to have a header than identifies the page (or page fragment) as a page to be processed.

sitegen recognises three hyphens --- <keyword> as a sitegen instruction. This will be stripped out of the page and processed. The sitegen config in a page can include:

Note: I'm not sure I want to keep the 'sitegen' bit of the yaml file. It was to nail it down, but I think it just being a yaml header is probably good enough.

--- sitegen
title: The page <title> value
template: default  # the template file (minus .extension) to render this page with
style: style.css   # the style sheet to apply to this page.
tags: [tag1, tag2] # tags to apply to the page
category: cat1     # The SINGLE category to apply to the page.
date: 2019-10-11   # The Date/time to apply to the page
updated: 2019-10-12 # Date/time the page was updated.
route: code/slug-name  # The permanent slug to use for this page.
authors: [tinwood]  # Authors of this page.
publish: false        # The default is false; set to true to actually publish it.
site: <site-identifier> # the site that this belongs to. 'default' is the
                        # default site identifier.
<maybe more>
---                # this indicates the end of the header.
# Content goes here ...

See ./src/Types/Header.hs for more details on the parts of the page header.

The route is interesting as it can determine what section the page fits into. This (could) auto-select the template type for the page.