Minor Changes
-
#1535
0360900Thanks @MA2153! - Adds an HTTP API for content references: relation-definition CRUD under/_emdash/api/relations(editor-readable, admin-writable) and directed reference edges on content entries under/_emdash/api/content/:collection/:id/references/:relation/{children,parents}(ownership-aware). References are stored only in the references table — no collection column. The edge reads are cursor-paginated (?cursor/?limit, default 50, max 100) and returnnextCursor; each resolved entry carries thelocaleof the variant returned. -
#1874
1526f96Thanks @Vallhalen! - MCPcontent_createandcontent_updatenow accept ataxonomiesfield
({ [taxonomyName]: [termSlug, ...] }) that assigns taxonomy terms in the
same transaction as the content write. Term slugs are resolved in the entry's
locale via the same code path as the/terms/{taxonomy}REST route, so the
two entry points can't drift. Also exposed on the RESTPOSTandPUT
content endpoints for parity. Fixes #953. -
#1719
7c5de08Thanks @swissky! - Adds ataxonomies:readplugin capability with read-only taxonomy access: plugins that declare it getctx.taxonomiesto list taxonomy definitions (getAll()), fetch the terms of a taxonomy (getTerms()), and read the terms assigned to a content entry (getEntryTerms()) — in-process and in both sandbox runners. -
#1578
58f594bThanks @marcusbellamyshaw-cell! - Implements pagination forsearch()andsearchCollection()search()advertised keyset pagination through its types (options.cursor,SearchResponse.nextCursor) but never read the cursor or returned one, so results were silently capped atlimitwith no way to load a second page.Both
search()andsearchCollection()now honourcursorand return anextCursorwhenever more matches exist. Pass the previousnextCursorback ascursorto walk subsequent pages; it becomesundefinedon the last page. The/_emdash/api/searchendpoint accepts acursorquery parameter and returnsnextCursorin its response (a malformed cursor returns a 400INVALID_CURSOR).let cursor: string | undefined; do { const { items, nextCursor } = await search("quarterly report", { limit: 20, cursor, }); render(items); cursor = nextCursor; } while (cursor);
-
#1867
c57b12bThanks @khoinguyenpham04! - Adds an admin REST endpoint andEmDashClient.mediaRepairUsage()client method for repairing content media usage indexes by collection or across all collections. -
#1886
60811c0Thanks @swissky! - Adds atoolbarconfig option for reliable editor-toolbar delivery behind shared caches.toolbar: "client"keeps public HTML identical for every visitor and shows a client-side "Edit" pill for logged-in editors that opens a fresh, uncached editor render via an_editquery param;toolbar: falsedisables the toolbar entirely. The toolbar can now also be dismissed in the browser via its × button. The default ("server") is unchanged.
Patch Changes
-
#1865
582ea2cThanks @khoinguyenpham04! - Fixes the admin dashboard scheduled-content summary so it counts entries with pending schedules instead of inferring the count from other statuses. -
#1857
77e8968Thanks @swissky! - Speeds up the admin content-list search on collections with full-text search enabled: the filter is now served from the FTS5 index (token-prefix matching plus slug-prefix lookup) instead of scanning every row. Collections without search enabled, and PostgreSQL databases, keep the previous substring matching. -
#1905
e12f393Thanks @swissky! - Fixes multi-paragraph blockquotes splitting into separate quotes: consecutive quote paragraphs now render as a single blockquote on the site and load as one quote block in the editor, so merging them no longer reverts on reload. -
#1854
e4e76f5Thanks @swissky! - Fixes comment submissions bypassing Turnstile: when theEMDASH_TURNSTILE_SECRET_KEY(orTURNSTILE_SECRET_KEY) environment variable is set, the public comment endpoint now verifies the submitted Turnstile token server-side and rejects submissions without a valid one. Sites without a configured secret key are unaffected. -
#1550
cbc7d6bThanks @marcusbellamyshaw-cell! - Fixes search across all collections failing withD1_ERROR: no such column: c.titlewhen any search-enabled collection has notitlefield (#1178).titleis an optional field, not a guaranteed column, so callingsearch(or the MCPsearchtool) without acollectionsfilter could error instead of searching everything. Cross-collection search now works regardless of which collections define a title; results from a collection without one simply omit the title, and autocomplete suggestions skip such collections rather than erroring. -
#1907
15f4057Thanks @swissky! - Adds hreflang alternate links to the page head for translated content.<EmDashHead>now emits a<link rel="alternate" hreflang="...">per published translation (plusx-default) automatically, and a newgetHreflangAlternates()helper resolves the same set for hand-rolled heads. -
#1875
b116525Thanks @ascorbic! - Fixes a database stampede on Postgres when a pending migration fails at runtime: requests no longer pile up waiting on the migration lock, failed migrations are retried with a backoff instead of on every request, and failed attempts no longer leak idle database connections. -
#1855
450ea81Thanks @swissky! - Fixes preview and editor-toolbar responses being stored in the shared edge cache when route caching is enabled: requests with a_previewtoken and toolbar-injected editor pages now opt out of the route cache, so draft content is no longer served from the cache without token verification and toolbar markup no longer leaks to anonymous visitors. -
#1892
9c0733fThanks @ascorbic! - Fixes taxonomy term counts (Categories/Tags widgets, term pages, and the admin term list) so they only include content that is publicly visible: published or scheduled-and-due entries that have not been trashed. Counts are now also scoped to the taxonomy's declared collections. -
Updated dependencies [
582ea2c,582ea2c,d2f5ddc,d237e96,9792226,7c5de08,60811c0]:- @emdash-cms/admin@0.29.0
- @emdash-cms/plugin-types@0.2.0
- @emdash-cms/registry-client@0.3.3
- @emdash-cms/auth@0.29.0
- @emdash-cms/gutenberg-to-portable-text@0.29.0