{"id":15286183,"url":"https://github.com/skx/chronicle2","last_synced_at":"2025-10-07T01:30:31.425Z","repository":{"id":20889313,"uuid":"24176662","full_name":"skx/chronicle2","owner":"skx","description":"Chronicle is a simple blog compiler, written in Perl with minimal dependencies.","archived":true,"fork":false,"pushed_at":"2020-04-03T05:39:41.000Z","size":596,"stargazers_count":20,"open_issues_count":0,"forks_count":4,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-09-30T15:13:11.167Z","etag":null,"topics":["cgi","cpan","perl","sqlite","static-site-generator"],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skx.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"skx","custom":"https://steve.fi/donate/"}},"created_at":"2014-09-18T06:27:28.000Z","updated_at":"2023-08-06T06:25:17.000Z","dependencies_parsed_at":"2022-08-30T17:41:16.215Z","dependency_job_id":null,"html_url":"https://github.com/skx/chronicle2","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skx%2Fchronicle2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skx%2Fchronicle2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skx%2Fchronicle2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skx%2Fchronicle2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skx","download_url":"https://codeload.github.com/skx/chronicle2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235569498,"owners_count":19011184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cgi","cpan","perl","sqlite","static-site-generator"],"created_at":"2024-09-30T15:10:54.693Z","updated_at":"2025-10-07T01:30:31.061Z","avatar_url":"https://github.com/skx.png","language":"Perl","funding_links":["https://github.com/sponsors/skx","https://steve.fi/donate/"],"categories":[],"sub_categories":[],"readme":"\n* Homepage:\n    * https://steve.fi/Software/chronicle/\n* CPAN:\n    * http://search.cpan.org/dist/App-Chronicle/\n* Git Repository:\n    * http://github.com/skx/chronicle2\n\n\n# Project: Obsolete\n\n**NOTE** this project is currently unmaintained, it was replaced by a golang-based application which has complete feature-parity:\n\n* [https://github.com/skx/ephemeris](https://github.com/skx/ephemeris)\n\nchronicle\n---------\n\nChronicle is a tool which will convert a directory of simple text files into a static HTML weblog, (or blog if you prefer).\n\nThis repository contains a from-scratch rewrite of the Chronicle static blog compiler, which represents a significant upgrade in terms of both speed and flexibility.\n\nThe system is intentionally simple, but it does support:\n\n* Template based output.\n* Support for RSS feeds.\n* Support for tagged entries.\n* Optional support for comments.\n\n\nThis implementation is significantly faster at page generation than previous releases, primarily because posts are parsed and inserted into an SQLite database, rather than having each post read into RAM.\n\nOnce the blog posts have been populated in the SQLite database they are inserted into a series of templates, which ultimately generates the output.\n\n\u003e Although we assume you keep the SQLite database around it doesn't matter if you delete it.  The act of parsing all your entries is still a very quick process.\n\n\nInstallation\n-------------\n\nClone the repository then install as you would any CPAN module:\n\n    perl Makefile.PL\n    make test\n    su - make install\n\n\n\n\nBlog Format\n-----------\n\nThe blog format is very simple, and the following file is a sample:\n\n    title: The title of my post\n    date: 12 August 2007\n    tags: foo, bar, baz\n\n    The text of the actual entry goes here.\n\n    However much there is of it.\n\n\nThe entry is prefixed by a small header, consisting of several pseudo-header fields. The header __MUST__ be separated from the body by at least one empty line.\n\nHeader values which are unknown are ignored, and no part of the header is included in the output which is generated.\n\nThe following header values are recognized:\n\n* Title:\n    * This holds the name of the post. (\"Subject:\" may be used as a synonym.) If neither \"Title\" or \"Subject\" are present the filename itself is used.\n* Date:\n    * The date this entry was created. If not present the creation time of the file is used.\n* Tags:\n    * If any tags are present they will be used to categorize the entry.\n* Format:\n    * This allows you to specify if you're writing in markdown, or textile.  If you are then the blog-body will be processed correctly.\n\nAdditional headers may be inserted, which will be ignored by default, for access by particular plugins.  For example the `Chronicle::Plugin::SkipDrafts` plugin will ensure that blog entries are ignored if they are still drafts - and include a `draft:1` header.  Similarly there is a plugin called `PostSpooler` which will ignore posts until their due data, and that uses the special `publish` header - rather than the default `date`.\n\n\nSimple Usage\n------------\n\nAssuming you have a directory containing a number of blog posts\nyou should be able to generate your blog like so:\n\n    chronicle --input=path/to/input --output=/path/to/output \\\n       --theme=blog.steve.org.uk\n\nThis will read `path/to/input/*.txt` and generate the blog beneath\nthe directory `/path/to/output/` creating that directory if missing.\n\nThe SQLite database will be created at `./blog.db` by default, and if it is\ndeleted it will be regenerated.\n\n\nAdvanced Usage\n--------------\n\nThe previous example showed the basic usage, one obvious change most users would prefer would be to set the title of the blog, and the subtitle:\n\n    chronicle --title=\"Steve Kemp's Blog\" --sub-title=\"Writings about cake\" ..\n\nIf you start setting multiple values you might prefer to use a configuration\nfile instead.  Chronicle will read  `/etc/chronicle/config`, and `~/.chronicle/config` prior to starting.  Failing that you can specify a configuration file of your own via `--config=/path/to/conf`.\n\nThe configuration file matches the command line arguments exactly, so given \"--foo=bar\" the configuration file would allow the same thing to be set via:\n\n    foo = bar\n\nAs we've previously noted the blog-generation largely occurs via a series of plugins.  For example the sidebar might show the list of all tags, which can get unwieldy quickly.  If you wished to disable that you could do so via:\n\n    chronicle --exclude-plugins=AllTags,RecentPosts --force ..\n\n\u003e **NOTE**: The plugins which generate output pages are located beneath the `Chronicle::Plugin::Generate` name-space.  The plugins which generate snippets available to all pages are located beneath the `Chronicle::Plugin::Snippets` name-space.\n\n\u003e **NOTE**: Because the snippets are included in every page, in the default themes, we've added `--force` to ensure that the output pages are updated.\n\n\nUser-Visible Changes\n--------------------\n\nIn an ideal would you should be able to migrate from previous Chronicle releases directly to this codebase, as the purpose and main operation is identical:\n\n* Blog entries are are still read from `data/`, unless you specify a different path via \"`--input`\".\n* We still assume `*.txt` are the blog entries, unless you specify \"`--pattern=*.blog`\".\n* Blog entries are still built up of a header and the entry.\n* Entries are still parsed in HTML, Markdown, and Textile formats.\n\nHowever there are changes, and these largely relate to the templates, along with the implementation differences.\n\nAs of Chronicle 5 the main script parses any command-line arguments, and reads the blog posts, but the actual generation of your site is entirely plugin-based.  The plugins are standard Perl modules located beneath the `Chronicle::Plugin` name-space, and although you don't need to know any of the details they can be ordered thanks to the use of [Module::Pluggable::Ordered](http://search.cpan.org/perldoc?Module%3A%3APluggable%3A%3AOrdered) class.\n\nThe template changes are a little more significant than I'd like, but\nhappily these changes largely consist of new locations for things,\nand additional pages.\n\n\n\nExtending\n---------\n\nAs mentioned the core code is pretty minimal and all output functionality\nis carried out by plugins.\n\nThe core will call the following methods if present in plugins:\n\n* `on_db_create`\n    * This is called if the SQLite database does not exist, and can be used to add new columns, or tables.\n* `on_db_open`\n    * This is called when the database is opened, and we use it to set memory/sync options.  It could be used to do more.\n* `on_insert`\n    * 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 must be refreshed.\n    * This method is designed to handle Markdown/Textile conversion, etc.\n* `on_initiate`\n    * This is called prior to any processing, with a reference to the configuration options and the database handle used for storage.\n    * This is a good place to call code that generates common snippets, or populates global-variables.\n* `on_generate`\n    * This is called to generate the actual 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.\n    * This is where pages are output.\n\n\n\nSteve\n--\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskx%2Fchronicle2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskx%2Fchronicle2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskx%2Fchronicle2/lists"}