Holly

A blog-engine plugin for Ark.


Holly is a blog-engine plugin for the Ark static site generator. It turns Ark into a WordPress-style blog generator with support for post and tag indexes.

This plugin is intended as a proof-of-concept, to demonstrate how an Ark site can be customized.

Installation

You can install Holly from the package index using pip:

$ pip install holly

Activate the plugin by adding its name to the extensions list in your site's config.py file:

extensions = ['holly']

You'll need a blog-capable theme to notice any difference in your site. You can use the sample theme from the demo site in the plugin's Github repository as a starting point for building your own custom theme.

Directory Indexes

You can add a dictionary of settings for Holly to your site's config.py file. Tell Holly where to build your blog index by specifying the url of its root node, e.g.

holly = {
    "roots": [
        {"root_url": "@root/blog//"},
    ]
}

Holly will create an index at this node containing a list of all descendant leaf nodes, i.e. nodes which do not have children. Holly will recursively create a similar index for all descendant parent nodes, i.e. nodes which do have children.

Imagine our site looks like this:

src/
|-- blog/
    |-- cats/
    |   |-- cat-post-1.md
    |   |-- cat-post-2.md
    |-- dogs/
        |-- dog-post-1.md
        |-- dog-post-2.md

Holly will create an index at @root/blog// containing a list of all four posts. It will also create indexes at @root/blog/cats// and @root/blog/dogs// containing two posts each.

You can use this recursive branching to divide a large blog index up into subsidiary categories. There's no limit to how deep the branching can go.

You can specify multiple root urls to create multiple independent index hierarchies, e.g.

holly = {
    "roots": [
        {"root_url": "@root/blog//"},
        {"root_url": "@root/photoblog//"},
    ]
}

Each root can have its own settings and will have its own independent set of tag indexes.

The full list of possible settings for a root looks like this:

holly = {
    "roots": [
        {
            "root_url": "@root/blog//",
            "tag_slug": "tags",
            "sort_func": lambda node: node.filepath,
            "reverse": True,
            "per_page": 10,
            "per_tag_page": 100,
        },
    ]
}

By default index listings are sorted in reverse order first by filepath then by date if a date attribute has been set. You can override this by supplying a custom sort function which should accept a Node instance and return the relevant sort key.

Tags and Tag Indexes

Holly checks each node for a string of comma-separated tags:

---
tags: foo, bar, baz
---

It converts this tags attribute into a list of tag links and assembles a set of tag indexes attached to the root node. For example, using the settings above, the index for tag foo would be found at @root/blog/tags/foo//.

If you specify multiple roots, each root will have its own independent set of tag indexes.

The Homepage Index

Holly can assemble a composite index for the homepage drawing from multiple roots:

holly = {
    "homepage": {
        "root_urls": ["@root/blog//", "@root/photos//"],
    }
}

The full list of possible settings for the homepage index looks like this:

holly = {
    "homepage": {
        "root_urls": ["@root/blog//", "@root/photos//"],
        "sort_func": lambda node: node.filepath,
        "reverse": True,
        "per_page": 10,
    }
}

Flags, Classes, Attributes

Holly adds a set of flags to index nodes which you can use in template files:

is_index
is_dir_index
is_tag_index
is_homepage_index
is_paged
is_tag_base

It adds a corresponding set of CSS classes for the <body> element:

index
dir-index
tag-index
homepage-index
paged
tag-base

Paged index nodes have a set of paging attributes:

page_num
total_pages
prev_url
next_url

The index itself is a sorted list of nodes which you can access in template files via the node.index attribute.

License

Zero-Clause BSD (0BSD).

All the images used in the demo site are public domain photos from https://unsplash.com — thank you to their creators for making them freely available!