ZKRINET Docs
Building blocks

CMS — pages and posts

On Zkrinet: add the block under Building blocks in the panel — one click, your own code is untouched and a snapshot is taken first. The installation steps below apply if you run PocketBase yourself, for example after an export.

Pages and blog posts that you write in the PocketBase admin panel (with a text editor) and display in your app. Publishing with dates, automatic URLs, version history, RSS feed and sitemap.

Tested against PocketBase 0.40.4.

Installation

Copy pb_hooks/ and pb_migrations/ to your PocketBase and restart. The collections zk_cms_sidor and zk_cms_inlagg appear in the admin panel.

Writing

Field
titel, innehall (editor), utdragThe text
slugThe URL. Leave it empty and it is created from the title: "Våra tjänster & priser!" → vara-tjanster-priser (if it already exists it becomes -2).
bildCover image (jpg/png/webp/gif/avif, max 10 MB)
sok_titel, sok_beskrivningOptional texts for Google (otherwise title/excerpt)
publicerad, publicerasVisible only when publicerad is on and the date has passed. A date in the future = scheduled. Checked without a date = published now.
lastid_minCalculated automatically (200 words/minute)
Pages: ordning · Posts: taggar (list), forfattare

Only superusers can write. Visitors read published content without logging in.

Display in your app

// A page by its address
const sida = await pb.collection("zk_cms_sidor").getFirstListItem(`slug = "${slug}"`)

// Latest posts
const inlagg = await pb.collection("zk_cms_inlagg").getList(1, 10, { sort: "-publiceras" })

// Posts with a tag
await pb.collection("zk_cms_inlagg").getList(1, 10, { filter: 'taggar ~ "nyhet"' })

Render the content sanitized. innehall is HTML. The plugin removes scripts, event attributes, javascript: links, embeds and the like when it is saved (tested against around thirty known tricks) — but that is an extra layer of protection. Always render with a real sanitizer in the app, e.g. DOMPurify.sanitize(sida.innehall).

RSS and sitemap

If your site is on a different address than PocketBase, create one row in zk_cms_installningar:

FieldExampleDefault
webbadresshttps://min-sajt.sethe app's address
sida_mall/{slug}/{slug}
inlagg_mall/nyheter/{slug}/blogg/{slug}
rss_titel, rss_beskrivningthe app's name

Tip: point /rss.xml and /sitemap.xml on your site here (proxy/rewrite), and add the sitemap in Google Search Console.

Versions

Every time the title, content or excerpt changes, the previous version is saved in zk_cms_versioner (the 20 latest per page). Restore with:

POST /api/zk/cms/aterstall/{versionens id}     (superuser)

The current version is saved first, so a restore can also be undone.

Limitations

Test

./bank.py cms

11 tests: slug (Swedish characters, duplicates), publishing and scheduling, permissions, sanitizing of dangerous HTML (including encoded and combined tricks) without touching ordinary HTML, reading time, versions and restore, the version cap, RSS and sitemap (valid XML, correct addresses, no drafts). The sanitizer is mutant-verified: every protection has been broken on purpose and caught.