Holly

A blog-engine plugin for Ivy.



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

Installation

First install the latest version of Ivy from the package index. (Holly requires Ivy v3 which is currently in development and unstable.)

$ pip install --pre ivy

Next, install Holly itself:

$ pip install holly

Activate Holly 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 carbon theme from the demo site in the Github repository as a starting point for building your own custom theme.

Node 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 note, 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 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_node_index
is_tag_index
is_homepage_index
is_paged

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

index
node-index
tag-index
homepage-index
paged

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

All code has been placed in the public domain.

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!