Accent CMS 0.27: your own taxonomies, Atom and JSON feeds, more data in templates
Accent CMS 0.27.0 is out. Five changes can need action when you upgrade, so they come first.
Before you upgrade
Tag URLs use slugs. A tag page moves from /tags/javascript runtime
to /tags/javascript-runtime. Static builds and accent serve redirect
the old URLs. If your theme builds tag links by hand, such as
/tags/{{ tag.name }}, use {{ tag_url(tag) }} instead. The function adds
the slug, the deployment prefix and the language prefix.
pages lists only the current language. On a site with
site.languages, the pages list that a menu loops over now holds the
pages of the page’s own language. To link the other languages, add a
language switcher over page.translations. The starter theme shows how.
A broken component manifest fails accent build. Before, the build
dropped the component with a warning and passed. Use --lax to get the
old behavior.
The build manifest moved out of the output. accent build wrote
.build-manifest.json into the output directory, so a deploy published
it, with the URL and status of every page, drafts included. It now lives
in .accent/build/ next to config.yaml, and the first build after the
upgrade moves it for you. If your deploy never deletes remote files,
delete /.build-manifest.json from your host. In CI, cache
.accent/build/ together with the output to keep incremental builds.
YAML and dates are read more strictly.
- A hex or octal number with an uppercase prefix, such as
0X1F, is now a string.0x1Fis still the number 31. - A control character in a YAML comment is an error.
- A
publish_datethat is neither a date nor an ISO 8601 timestamp keeps the page a draft. Before, the page was published. Timestamps such as2026-12-01T09:00:00Znow work.
Run accent validate after the upgrade. It reports each of these.
Your own taxonomies
Tags are no longer the only way to group pages. List more taxonomies in
config.yaml:
taxonomies: - name: categories singular: category path: /themen # default: /categories
Each taxonomy gets what tags have: an index page, one page per term with
a slug URL, pages per language, and taxonomy.categories in every
template. A page opts in with categories: praxis or
categories: [praxis]. A theme can add categories.html.jinja and
category.html.jinja; without them, Accent uses the tag templates. Link
a term with term_url("categories", term).
More feeds
Accent now writes Atom and JSON Feed as well as RSS, and it can write several feeds at once:
feed: outputs: - { format: atom, path: /feed.xml } - { format: json, path: /feed.json } include: ["/posts/"] # only posts, while they stay in the sitemap
feed.includeandfeed.excludelimit a feed to one section of the site.- A page whose
content:block setsfeed: truegets a feed of its collection at<its url>/feed.xml. - A taxonomy with
feed: truegets one feed per term, such as/themen/<slug>/feed.xml. feed_outputs()lists the feeds, so a theme can write one<link rel="alternate">for each. The default theme does.accent serveanswers every feed at the same URL as the build. Outside dev mode, it caches the feed bodies.
A config with only feed.path writes the same RSS feed as before.
More data in templates
site.extra holds your own site-wide values:
site: extra: newsbar: enabled: true message: "No free slots at the moment."
A template reads them as site.extra.newsbar.message. site.extra is
always there, so {% if site.extra.x %} is safe.
Your frontmatter in listings. Every entry in all_pages, pages,
page.children and the other listings has a custom map with your own
frontmatter keys. A collection’s filter also takes a custom: map, so
custom: { category: praxis } lists only those pages.
Components see the page. A component template now gets site,
page, pages, all_pages, taxonomy, theme, dev and accent,
like a page template. A component can list the latest posts of a tag
without an attribute for each value.
Dates in the page’s language. The date filter writes month and
weekday names in the page’s language, so a German page shows März.
date("long") and date("short") are presets for common formats, and
locale="fr" picks another language.
Content and builds
- A
static/directory. Files under./staticare served and copied to the site root, for files such asfavicon.ico, a verification file orhumans.txt. Incremental builds track them. {% include-file %}shows a file of your site as a highlighted code block. It reads the file on every render, so the code on the page always matches the file.linesandregionshow part of a file.- Marks in code. A code block that opts in with
{% process=true %}can wrap parts of its code in themarkcomponent, for example to highlight one part of a command. - Files in mounts. A directory mount now publishes the non-markdown files next to its pages, as the content directory does.
- Links to files. A relative link to a file next to the page, such as
[plan](benchmark.yml), is rewritten to the file’s URL. The same link works on GitHub and on the site. - Netlify
_redirects. Withbuild.header_artifacts: ["netlify"], the build also writes_redirectsfrom your redirects and page moves. Cloudflare Pages reads the same file. - Component manifests can declare
body: noneandplacement: block | inline | both.
Security fixes
- Remote content, such as a remote mount or
accent serve <url>, can no longer pull a file of your site into a page withinclude-fileorpartial. include-file,partialanddiagram src=refuse the site’s config file, so they cannot publish a license key or credentials.- Theme assets no longer serve or copy dotfiles such as
.env, and no longer follow a link out of the theme. - With the config file inside the content directory, another spelling of
its name (
/Config.yamlon macOS and Windows) or a link to it no longer serves it. - The theme asset route and the admin static route no longer read files outside their directories.
- The build manifest no longer ends up in the deployed site (see above).
Fixes for multi-language and versioned sites
- Tag pages exist in each language, under the language prefix.
- A translated home page has one URL and lists its pages.
nav_tree(), menus andaccent query treefollow the page’s language.- On versioned docs,
accent querysees inherited pages, a.mdlink on an inherited page reaches its target, andaccent validatereports a finding on an inherited page once.
Other fixes
- A new release reaches returning visitors within an hour. CSS, JavaScript and font files whose URL has no content hash are no longer cached for a year.
/readyzanswers 503 while a theme template does not compile.- DocFind search finds the body words of German pages, and Simple Search keeps words with non-ASCII letters whole.
- A build without
--cleanfollows frontmatter edits and renders again the pages that show a changed page. - Headings keep their
{ .class #id }attributes, and a raw HTML block stays where it was written. - A diagram’s alt text reaches screen readers.
Under the hood
The YAML parser moves to noyalib 0.0.57, and the other dependencies are
updated. cargo audit reports no known vulnerabilities.
The GitHub release has the full list of changes.
Install or upgrade:
curl -fsSL https://accentcms.dev/install.sh | sh
Binaries for all platforms, checksums, and signatures are on the GitHub release page.