Repository navigation
Accent CMS v0.28.0
Pages can have an identity that survives a move or a rename. A model gives
each page a uid and an optional alias, reference fields follow both, and a
moved page keeps answering at its old URL. Models can also declare computed
values -- counts, sums, groups, and formulas over other pages -- that you read
as page.computed in a template, as $computed in a page body, from accent query, from the REST API, and from MCP and agents. accent content import
brings another site's pages in as stamped copies you reference as
origin/alias. The index file names a directory answers to, default.md,
README.md and index.md by default, are now configurable, and the docs
theme accent init --docs scaffolds gains a Topics page for each version.
Fixes include incremental builds that refresh computed values, accent new
numbering pages on a flat corpus, and a license response header that follows
a config reload. The unused rsa crate is out of the binary, and about 110
dependencies move to their latest compatible releases.
Three changes can need action when you upgrade:
serveandbuildpick the same index file. When a directory holds
more than one index file,accent buildnow follows the documented
priority, asaccent servealways did. A built site that relied on
index.mdwinning overREADME.mdordefault.mdchanges; keep one index
file per directory.- URL paths in
aliasesredirect. A page whose frontmatteraliases
list holds a URL path such as/old-urlnow answers there, on any site:
accent serveredirects it to the page andaccent buildwrites a
redirect stub, unless a page already lives at that path. If you used
aliasesfor something else, rename the key. - Identity checks in
accent validate. Two pages with the sameuid
are now an error on every site, and atype: referencefield that names a
model:now resolves its value, so a value that names no page of that
model is an error. A site that uses neither sees no new findings.
Added
-
Configurable index filenames. A file named
default.md,README.md,
orindex.mdanswers its directory's URL. You can now change that list:
setcontent.index_filesinconfig.yamlto add a name such asHome.md
(the GitHub wiki convention), reorder the priority, or drop a name. To use
a different list in one part of the tree, setindex_filesin a
_model.yamlin that directory; it applies there and in every directory
beneath.default.mdalways counts, andaccent validatereports an
invalid list in a_model.yaml. -
Pages can carry a stable identity. A model that declares
uid:and
alias:gives each page auidthat Accent mints once when the page is
created, and an optional alias, the human label the page is known by,
such asd042. The alias has agrammar(the same segment language as
filename:patterns), ascope(globalorcontainer), and a
renumberpolicy (retireornever). When a page changes its alias,
retirekeeps the old label in analiaseslist, where it stays
claimed and still resolves.accent new, the admin editor, the content
API, agents, and MCP all mint theuid; you never write it by hand. -
Reference fields that follow identity. A
type: referencefield
with amodel:target holds an alias, a retired alias, or auid, and
the content index resolves it to a page.accent validatereports a
duplicateuid, a missing requireduid, a duplicate alias in one
scope, an alias that does not match the grammar, retired aliases on a
renumber: nevermodel, and a reference that resolves to nothing or to
a page of the wrong model. In templates,identity_index()maps every
uid, alias, and retired alias to its page URL. Areferencefield
withoutmodel:stays a plain string that Accent never resolves. -
Moved pages keep answering at their old URLs. A model can declare
alias: { grammar: path }, which makes the page's URL its alias. When
you move such a page in the admin, on the CLI, or through the API,
Accent adds the old URL toaliases.accent serveredirects the old
URL to the page, andaccent buildwrites a redirect stub there, so a
static host needs no extra rules. This works for any retired alias that
is a URL path. -
Claim a label on the shared remote. With
allocation: ref, a model
claims each new alias as a create-only Git ref,
refs/claims/<model>/<alias>, locally and onorigin. Two writers who
share the remote cannot claim the same label: the second push is
rejected and that writer takes the next label. It needs a repository
with anoriginremote and a network connection when you file the page,
and it does not fall back toallocation: local.grammar: path
cannot use it. -
Computed values on models. A model's
computed:block declares
values that every page of the model carries, evaluated when Accent
renders and never stored. A query counts (count), sums (sum, as an
exact decimal string), or groups (group) the pages of another model,
matched through a field withvia, and filters withwhere. A formula
combines the page's fields and its other computed values with
arithmetic, comparisons,and/or/not, and the date and decimal
functions. Read the values in a template aspage.computed, for
examplepage.computed.features_done | default(0).accent validate
reports a failed query or formula, a formula cycle, and an expression
outside the supported subset. -
Computed values in the page body. The same values are Markdoc
variables under$computed, so a page can write
{% $computed.features_done %} of {% $computed.features_total %}or
branch on a value with{% if %}, with no template change.accent validatereports a$computedname the page's model does not declare.
The server re-renders a cached page when its computed values change,
and an incrementalaccent buildrebuilds exactly the pages whose
values changed. -
Read computed values from every query surface.
accent query computed <url>prints a page's URL, resolved model, and computed values
as JSON. The REST API answersGET /api/v1/computed/<url>when
api.enabledis on, the MCP server has aget_computedtool, and
accent agentsessions get a read-onlyget_computedtool. A page
whose model declares no computed values answers 404 on the API, and
accent buildwrites/api/v1/computed/<url>.jsonfor exactly those
pages that have values, so a CDN serving the built output answers the
same way. -
Import another site's pages with
accent content import.
accent content import <source>copies every markdown page of another
site checkout, or of a bare content directory, to
content/imports/<origin>/. Each copy keeps itsuidand relative path
and carriesorigin: <slug>in its frontmatter. The slug comes from
--originor from the source'ssite.origin. Importing again replaces
pages byuid, so a page the source moved replaces its old copy. Add
--dry-runto see what would change. -
Reference imported pages as
origin/alias. A site names itself with
site.origininconfig.yaml. Imported pages keep their aliases
claimed in their own origin, so yourf12and an importedf12
coexist. Writedep: accent-sass/f12to reference the imported page; a
bare alias always names your own page, and a bare alias inside an
imported page keeps meaning its own corpus.accent validatewarns when
a qualified reference names a page that is not imported, and reports a
duplicate alias within one origin as an error. A computedgroup
query on theoriginfield counts pages per corpus. -
A Topics page for each version of the docs site.
accent init --docsscaffolds a docs theme that adds a Topics page to each version
of the documentation, with a sized topic cloud and a filter box. Each
docs page ends with its topics as links, the header has a Topics link,
and/tags/<tag>groups its pages by version, newest release first,
with older versions folded away.
Changed
-
uid,alias,aliases, andoriginare core fields. Every
model inherits them, so strict mode no longer flags them as unknown, and
the admin shows them as read-only. They are not required, and a page
without them is unchanged. -
accent init --docsalso creates amodels/directory. The
scaffolded docs site declares adocs-overviewmodel whose computed
page count the computed-values guide shows, and the default docs theme's
docstemplate now renderspage.computedthe waydefaultdoes. -
Dependency currency pass: every direct and transitive dependency moves
to its latest semver-compatible release (about 110 crates, rmcp 3.8 and
tokio 1.54 among them), anded25519-dalekmoves to 3.0. License key
signing and verification behavior is unchanged. wasmtime stays on the
48 LTS line by policy. -
The Svgbob diagram renderer now builds from the
zoosky/accent-svgbob
fork (0.8.0, rev-pinned) instead of crates.iosvgbob 0.7.2. The fork
removed svgbob's dormantsauronweb-framework dependency, whose
futures = "=0.3.30"exact pin blocked dependency resolution for the
whole workspace, and its SVG output is byte-parity-gated against the
previous renderer. Rendered diagrams are unchanged for the parity
corpus; the one qualification is that the fork'sunicode-width 0.2
follows newer Unicode width tables, so diagram text using characters
whose column width changed there (conjoining Hangul jamo, some
emoji-presentation characters) lays out by the new widths.
Fixed
-
accent serveandaccent buildnow pick the same index file. When a
directory held more than one index file,servefollowed the documented
priority (default.md, thenREADME.md, thenindex.md), butbuild,
navigation, search, and the sitemap took the last file in sort order, so
index.mdwon overREADME.mdanddefault.md, and a lowercase
readme.mdwon overdefault.md. Both now follow the documented
priority. If a built site depended on the old choice, keep one index file
per directory. -
A config reload updates the license response header. After you change
the license key inconfig.yamland reload with SIGHUP or
POST /_admin/reload,accent serve --productionsends the new key's
X-Accent-Licensevalue. It used to keep the value it started with until
it restarted. -
accent newnumbers pages on a flat corpus. With a bare{number}
or{order}in the filename pattern,accent newalways wrote0or
01. It now scans the target directory and uses the number after the
highest one there. A model whose file pattern varies per page now writes
flat into--path, not into a directory per page, and a--paththat
does not exist is an error instead of creating a new tree. -
An incremental build refreshes computed values. When you changed a
page that a computed query counted, filtered, or grouped, an incremental
accent buildrebuilt only the edited page, so the page that showed the
count kept the old number until a clean build. The build now records
each page's computed values and rebuilds the page when they change.
Security
- The
rsacrate is out of the binary. Licence keys, licence
artifacts and signed distribution records are Ed25519 JWTs, but the JWT
library's crypto backend also brought RSA, P-256 and P-384, andrsa
carries a timing advisory with no fix (RUSTSEC-2023-0071). Accent never
used it, so the advisory could not be reached; it was the onecargo auditignore with no fix to wait for. Accent now verifies with an
Ed25519-only backend, andrsa,p256andp384are gone from the
dependency tree, with 15 other packages. Existing licence keys keep
working.
Verifying your download
curl -fsSLO https://raw.githubusercontent.com/AccentCMS/accent/main/release-signing-key.asc
gpg --import release-signing-key.asc
gpg --verify checksums-v0.28.0.txt.asc checksums-v0.28.0.txt
sha256sum -c --ignore-missing checksums-v0.28.0.txt