The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

chronicle - A static blog-compiler.

SYNOPSIS

  chronicle [options]


  Path Options:

   --comments       Specify the path to the optional comments directory.
   --config         Specify a configuration file to read.
   --input          Specify the input directory to use.
   --output         Specify the directory to write output to.
   --pattern        Specify the pattern of files to work with.
   --theme          Specify the theme to use.
   --theme-dir      Specify the path to the theme templates.
   --url-prefix     Specify the prefix to the generated blog.

  Counting Options:

   --comment-days=N    The maximum age a post may allow comments.
   --entry-count=N     Number of posts to show on the index.
   --rss-count=N       Number of posts to include on the RSS index feed.

  Optional Features:

   --author        Specify the author's email address
   --blog-subtitle Set the title of the blog
   --blog-title    Set the title of the blog
   --force         Always regenerate pages.

  Help Options:

   --help         Show the help information for this script.
   --list-plugins List the available plugins.
   --list-themes  List the available themes.
   --manual       Read the manual for this script.
   --verbose      Show useful debugging information.
   --version      Show the version number and exit.

ABOUT

Proof of concept Chronicle successor which uses SQLite to generate a static blog with support for comments.

The key observation which has lead to this prototype is that rebuilding a blog with chronicle is slow because every file must be parsed and processed in a large data-structure, in ram, on every run.

However 90% of the time when a blog is rebuilt it is only to include a new user-submitted comment, or a new entry. There are rarely changes applied to previous posts.

If we parse all the blog entries *ONCE* and insert into a persistent SQLite database we can query that for reading tag-data, archives, etc, and this will be even faster thanreading our previous in-RAM data-structure.

Because people are fallible we'll store the `mtime` of the blog-posts and include that in the database too, this will allow us to incorporate new posts and edits to old posts, without having to throw away our database.

The average run of a blog with 1000 entries, and no changes, is 3 seconds and when changes have been detected, or we have to rebuild the SQLite database from scratch it is still ~10 seconds. This is a considerable win.

DATABASE STRUCTURE

We create a simple SQLite database with two tables:

A table for tags, storing the tag-name and associated blog-entry.
A table for blog entries.

The blog-entry table contains the following columns:

mtime The mtime of the input file.
date The date-header as self-reported in the blog-post.
body The body of the blog-post itself.
title The title of the blog-post itself.

EXTENDING WITH PLUGINS

The core of this script is responsible for a small amount of things:

Finding blog posts.
Parsing them into the SQLite database.
Cleaning up.

Actually generating output is delegated to a series of plugins each of which is responsible for outputing one thing. For example all of the tag-pages, located beneath /tags/ in your generated site, are generated by the plugin Chronicle::Plugin::Generate::Tags.

The core will call the following methods if present in plugins:

on_db_create This is called if the SQLite database does not exist, and can be used to add new columns, or tables.
on_db_open This is called when the database is opened, and we use it to set memory/sync options. It could be used to do more.
on_insert This method is invoked as a blog entry is read to disk before it is inserted into the database for the first time - or when the item on disk has been changed and the database entry must be refreshed. This method is designed to handle Markdown expansion, etc.
on_initiate This is called prior to any generation, with a reference to the configuration options and the database handle used for storage.
on_generate This is called to generate the output pages. There is no logical difference between this method and on_initiate except that the former plugin methods are guaranteed to have been called prior to on_generate being invoked. Again a reference to the configuration options, and the database handle is provided.

Any plugin in the Chronicle::Plugin:: namespace will be loaded when the script starts.

**NOTE**: It is not necessary for a plugin to define all three methods.

Much of the core functionality, such as the generation of the main RSS feed, is implemented as plugins. You might wish to disable plugins, and this can be done via command-line flags such as --exclude-plugin=RSS,Verbose.

AUTHOR

 Steve
 --
 http://www.steve.org.uk/

LICENSE

Copyright (c) 2014 by Steve Kemp. All rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The LICENSE file contains the full text of the license.