Hexo Series Plugin#
The series plugin (scripts/tag/series.js) is a Hexo tag plugin that groups posts by a shared series front-matter key and renders a sorted list of links to all posts in the group. It must be explicitly enabled in the theme config; it is disabled by default .
Note: There is a separate
card_post_seriessidebar widget that is enabled by default and uses a different helper (scripts/helpers/series.js). The two features share front-matter data but are configured and rendered independently.
Architecture: Module-Level Cache (groups)#
The plugin uses a module-level plain object, groups, as a cache. Keys are series names; values are arrays of { title, path, date } objects collected from post front-matter. Because groups is module-scoped, it persists for the lifetime of the Node.js process — including across incremental rebuilds in hexo server (watch mode).
Lifecycle via Hexo Filter Hooks#
Two filters manage the cache lifecycle:
| Hook | Behavior |
|---|---|
before_generate | Clears all keys in groups before every full site generation. |
before_post_render | Runs on every post; if the post has a series front-matter value, appends its { title, path, date } to the matching groups[series] array. |
The before_post_render filter is a no-op unless series.enable: true in the theme config .
Data Flow#
Tag Syntax and Rendering#
{% series %} <!-- uses the current post's `series` value -->
{% series <name> %} <!-- explicit series name -->
The series tag function looks up the resolved series name in groups, sorts the array, and returns an <ol class="series-items"> or <ul class="series-items"> depending on the number config option.
Sorting behavior is controlled by two config keys :
orderBy—'title'(default) or'date'order—1= ascending (default),-1= descending
Configuration Reference#
Defined in _config.yml and mirrored in default_config.js:
| Key | Default | Description |
|---|---|---|
series.enable | false | Must be true to activate the plugin |
series.orderBy | 'title' | Sort field: 'title' or 'date' |
series.order | 1 | 1 = asc, -1 = desc |
series.number | true | true → <ol>, false → <ul> |
Hot Reload Behavior (Development)#
Because groups is module-scoped and never reset between individual file-watch rebuilds, only a full generation (triggered by before_generate) clears stale data. In hexo server watch mode, editing a single post triggers before_post_render for that post but not before_generate, so:
- A renamed or removed post's entry stays in
groupsuntil the next full build. - New posts added mid-session are appended correctly, but the cache may contain duplicates if a post is re-rendered multiple times without an intervening
before_generate.
This is expected behavior given the filter design and is not a bug — restart hexo server or trigger a full rebuild to get a clean state.
Key Files#
| File | Role |
|---|---|
scripts/tag/series.js | Tag plugin + filter hooks (primary entry point) |
scripts/helpers/series.js | Helper for sidebar card_post_series widget |
layout/includes/widget/card_post_series.pug | Pug template for sidebar widget |
scripts/common/default_config.js | Default config schema |
_config.yml | User-facing config with defaults |