Antora is a static site generator primarily meant for documentation in which the original content is written and maintained in AsciiDoc.
In our documentation setup, some of the pages contain useful updates (like release notes) that would be helpful to automatically broadcast to other channels when the Antora site is rebuilt.
An RSS feed is a good candidate for publishing such updates, but this isn't something that Antora offers out of the box.
Fortunately, it only takes a bit of JavaScript to customize Antora.
With the help of Antora extensions, we can hook into different parts of the build process and gather data from the current state of the build.
This means we could create an RSS file based on the pages that Antora generates and package it with the other static files before the site is deployed.
Ideally, the RSS feed would look like the following, where we have summarized the latest release(s) and linked to the full release notes in the documentation:
Let's walk through how we would create this.
First, Antora extensions are written as JavaScript files and referenced in the playbook file under `antora > extensions`.
For example:
In the JavaScript file, we'll export a "register function" that creates an event listener on the `sitePublished` event.
For example:
The `sitePublished` event happens at the end of the Antora build process, but we could hook into earlier events like `playbookBuilt` or `navigationBuilt` if we wanted to intercept specific things that Antora does.
One use case that Antora suggests is to conditionally unpublish pages during the `navigationBuilt` phase.
For us, we don't want to change anything about Antora. We just want to parse some of the completed pages.
In particular, we want to pull out the highlights from all of our "release notes" pages.
Release notes could span multiple components (i.e., products) and multiple versions of those components.
In our `sitePublished` callback, we can use the `contentCatalog` object to loop over every component and version, looking for anything marked as a "page" and then filtering out everything but the release notes pages.
For example:
If we only had one component/product with one version, then we could simplify this search in the following manner:
Now that we have the page (`releaseNotesPage`), we can parse out the data for the RSS feed.
In the original AsciiDoc, the release notes are written as follows:
For the RSS feed, we're only concerned with the latest release announcement (the first `==` header) and the first paragraph underneath.
After Antora processes this content, those details will look like the following HTML:
At this point, we could use regular expressions to capture the relevant details.
Personally, I like to use the npm package, Cheerio.
With Cheerio, we can write jQuery-like selectors to find elements in a given string/document.
In this case, we're looking for the `<h2>` and `<p>` elements.
Using Cheerio and other data from the Antora callbacks, we can start piecing together what constitutes an RSS feed item.
For example:
Remember that this is only capturing the latest release announcement on the page.
If we wanted to include every `==` header in the RSS feed, then we could use a jQuery `each()` method instead to loop over every `sect1` section.
For example:
Lastly, we can pass the collected RSS items into a template as follows:
We just need to ensure that we write the `feed.rss` file to the same directory that Antora outputs the HTML files (`build/site` by default).
Now, whenever Antora builds the documentation site, the RSS feed is included, and other services can subscribe to it.