CMS-krønike·marts 2026·4 minutter at læse

CMS Chronicle #07: Opsummering af nye funktioner Syv funktioner i én session

Horisontale linjer, kloning, video-embeds, relationsvælgere, et ordentligt mediebibliotek med mapper, planlagt publicering og revisionshistorik — alt sammen lanceret i én session. Plus hvad hver enkelt funktion egentlig gør under overfladen.

Listen

Vi havde en backlog på syv funktioner, der havde ligget i notaterne i et stykke tid. I stedet for at gøre dem én ad gangen over flere sessioner, gjorde vi dem alle på én gang:

  1. Knap til horisontal linje i værktøjslinjen
  2. Klon (dokumenter og blokke)
  3. Video-embed (felt-type + TipTap-node)
  4. Relationsvælger
  5. Mediebibliotek
  6. Planlagt publicering
  7. Revisionshistorik

Her er hvad hver enkelt funktion gør.


Horisontal linje

Den simpleste funktion. En knap i værktøjslinjen for rigt tekst kalder editor.chain().focus().setHorizontalRule().run(). StarterKit inkluderer allerede udvidelsen. Serialiseres til --- i Markdown.

Klon

En Klon knap vises både i samlingslisten (række niveau) og i dokumenteditorens overskriftslinje. Den sender POST /api/cms/{collection}/{slug} med { action: "clone" }. API’en finder det første ledige slug — {slug}-copy, derefter -copy-2, -copy-3 — opretter et nyt udkast med de samme data og omdirigerer editoren til det.

Anvendeligt til: oprette varianter af en side, duplicere et skabelonindlæg, teste ændringer uden at røre det live dokument.

Video-embed

To overflader:

Som felt-type — tilføj { name: 'intro', type: 'video' } til enhver samling. Felteditoren viser en URL-indtastningsfelt + en live 16:9 iframe-forhåndsvisning. YouTube-, Vimeo- og youtu.be-links parses automatisk.

Inde i rigt tekst — en 🎬 knap i værktøjslinjen åbner en URL-prompt og indsætter en videoEmbed TipTap-node. Noden gengiver iframe’en i editoren. Under den viser en foderknap URL’en med Rediger- og ✕-knapper. Serialiseres til [video:URL] i Markdown og parses tilbage ved indlæsning.

Less

  • Plain text field for everything
  • Paste a YouTube URL, hope it works
  • Type a slug manually for relations
  • Uploads dumped in one flat folder
  • No save history — ctrl+Z or nothing

More

  • video, relation, image-gallery, tags, select — typed fields
  • video field shows live embed preview
  • relation field searches and picks from collection
  • Media library with folders, grid/list, drag-drop
  • Revision history panel — restore any previous save

Relationsvælger

Feltet relation faldt tidligere tilbage til et almindeligt tekstfelt. Nu henter det GET /api/cms/{collection} og gengiver en søgbar dropdown-menu. Hver mulighed viser dokumentets title, name eller label felt (hvad der end findes) med slug’en vist mindre nedenunder.

Definere en relation: { name: 'author', type: 'relation', collection: 'team' }.

Mediebibliotek

En dedikeret /admin/media side, der er linket fra sidepanelet.

Mapper — én niveau dyb. Filer uploadet til en mappe lander i {UPLOAD_DIR}/{folder}/filename. Sidepanelet viser alle mapper med filantal. Angiv en mappe i indtastningsfeltet "Upload til mappe", og alle nye uploads går derhen — inklusive træk-og-slip.

Træk-og-slip — hele siden er en dropzone. Træk 200 billeder fra Finder, og de uploades alle parallelt. En overlay viser hvilken mappe de lander i.

Gitter-/liste-skift — gitteret viser miniaturebilleder, listen viser en tabel med navn, mappe, størrelse, dato og handlingsknapper.

Paginering — 48 filer pr. side i gitteret, 100 i listen. Siden nulstilles, når mappe eller søgefiltre ændres.

Tip

The entire Media page is a drop zone. Drag 200 images from Finder directly onto the page — they all upload in parallel. Set a folder name in the sidebar first and all dropped files land there automatically.

Planlagt publicering

Udkast til dokumenter får en Planlæg knap i editorens overskriftslinje. Den åbner en datetime-local vælger. Det valgte tidspunkt gemmes som data.publishAt (ISO-streng) og gemmes med dokumentet.

En POST /api/publish-scheduled endpoint scanner alle samlinger for udkast med publishAt <= nu og publicerer dem. Kald det fra en ekstern cron, en Fly.io proces eller manuelt.

Warning

The scheduler runs on demand via POST /api/publish-scheduled. There is no background cron yet — call the endpoint from an external cron job, a Fly.io machine process, or manually from the dashboard. Automation is coming in a later phase.

Revisionshistorik

Hver gang et dokument gemmes via PATCH, tages et øjebliksbillede af den aktuelle tilstand og gemmes i {projectDir}/_revisions/{collection}/{slug}.json før opdateringen skrives. De sidste 20 revisioner gemmes.

En Historik knap i dokumenteditorens overskriftslinje åbner en skydepanel, der viser alle revisioner med tidsstempler og status. Klik Gendan for at genanvende ethvert øjebliksbillede — den aktuelle tilstand gemmes som en ny revision først, så gendannelsen er selv reversibel.

Nina Munkholm
Christian Broberg
1 / 2

Nina Munkholm


Hvad kommer næst

De syv funktioner ovenfor var de åbenlyse huller. Hvad der kommer herefter er mindre åbenlyst — sandsynligvis ⌘K global søgning på tværs af alt indhold, flersproget routing og blokkomponenter med egentlig design på webhouse-site. Infrastruktur er solid nok til at begynde at bygge ovenpå det.