Content Management that can withstand the plundering hoards

Build and distribute example packages

The repository provides thirteen plugins and five themes under examples. They are installed with Plugins and packages (themes can also use Theme import), then selected/applied and published separately. They are examples, not additional built-in themes. The runtime has no automatic registry download client.

Included examples

Package Language/source What it demonstrates
blog Declarative JSON Page-type properties, OAuth creator attribution, dated URLs, conversion actions and field blocks
external-link Declarative JSON Metadata-only external menu links with destination validation, ordering and nesting
callouts JSON/HTML/CSS Notice and download-card block pack
source-text Go WASI command rendering escaped source in a preformatted block
checklist-c Freestanding C Direct WASI I/O imports, line validation and inert task checkboxes, without libc
csv-table-rust Rust standard library CSV quoting, header/body table generation, escaping and invalid-input errors
field-notes Native theme JSON/CSS Warm botanical journal with a green sidebar and reading layout
cobalt-studio Native theme JSON/CSS Bright cobalt/orange portfolio with an oversized masthead and grid layout
back-to-top JSON/HTML/CSS Floating/inline anchors and reduced-motion-aware smooth scrolling
social-links JSON/HTML/CSS Accessible, editable social profile and contact links
reading-tools JSON/HTML/CSS Native details/summary FAQ, section navigation and reading notes
file-carousel JSON/HTML/CSS Periodic right-to-left card carousel with configurable visible count
cover-flow JSON/HTML/CSS Larger foreground card and angled, overlapping neighbours
ring-gallery JSON/HTML/CSS Continuous 3D cylinder rotation
masonry-grid JSON/HTML/CSS Responsive columns of cards with varying heights
harbour Native theme JSON/CSS Journal with collapsing masthead and pinned navigation
folio Native theme JSON/CSS Split portfolio rail and edge-to-edge project covers
atlas Native theme JSON/CSS Handbook with collapsing masthead and chapter rail

Themes each supply default and wide layouts, shared header/footer, generated navigation and live site/copyright bindings. They do not reuse the built-in IDs or modify bundled theme definitions. No external font/image fetch is required.

Build with Docker (same path as CI)

From repository root, with Docker running and network access for toolchain images, APT packages, Rust target installation and Go dependencies:

scripts/build-examples.sh

This uses examples/Dockerfile with repository-root context, builds using Go 1.27, Rust 1.92 plus wasm32-wasip1, Clang/LLD and Python 3, and runs the real CMS package-integration test before extracting ZIPs to ignored dist/examples/. It never runs the scratch artifact image or uploads locally. A temporary container/image is removed afterward; Docker's build cache remains available. An optional first argument chooses an output directory.

The tests install every ZIP through /api/plugins/install, execute valid and invalid renderer fixtures with the CMS WASI runtime, check escaping, and publish rendered pages/selected themes. A build or test failure prevents artifact export.

Build one package with local compilers

Every plugin and theme has an executable build.sh. It resolves source paths from its own location, can be invoked from any directory and accepts an optional output directory. The default is repository-root dist/examples.

examples/plugins/source-text/build.sh
examples/plugins/checklist-c/build.sh
examples/plugins/csv-table-rust/build.sh
examples/themes/field-notes/build.sh
examples/themes/cobalt-studio/build.sh
examples/plugins/callouts/build.sh
examples/plugins/blog/build.sh

Requirements: Python 3 for every script; Go 1.27+ for source-text; Clang/LLD with wasm32 support for checklist-c (no WASI sysroot/libc); and rustc with installed wasm32-wasip1 standard library for csv-table-rust. Install the Rust target with rustup target add wasm32-wasip1. WASI_CC=/path/to/clang overrides the C compiler. examples/build.sh runs all scripts using those local tools. The Docker wrapper is the portable option if you do not have every compiler installed.

examples/package.py writes sorted ZIP entries with fixed timestamps/modes. Only root plugin.json plus optional renderer.wasm, or assembled theme.json, enter these example archives. README/source/testcases/build scripts stay outside the ZIP. Theme styles.css is assembled into manifest CSS. Output filenames are <id>-<manifest-version>.viking-plugin.zip or .viking-theme.zip. Toolchain versions affect compiled Wasm; fixed archive metadata alone does not make binaries from different compilers identical.

CI generic-registry publishing

The example-packages job runs in build, uses a Docker-capable x86_64 runner, builds all examples through the wrapper and includes the publisher from tlspu/ci-utils at /templates/generic-repo/publish.yaml. The current template expects PUBLISH file globs; it does not invoke build scripts automatically. The job explicitly builds before referencing .generic-publish's script.

Setting Job value / effect
PACKAGE ${CI_PROJECT_NAME}-examples
VERSION Exact tag for tag pipelines; CI_COMMIT_REF_SLUG for branches
PUBLISH Both generated plugin and theme ZIP globs under dist/examples/
Authentication Template uses CI_JOB_TOKEN and the current project's API/project ID
Artifacts ZIPs are also available as job artifacts for one week
Serialization Resource group by ref slug prevents concurrent same-ref replacement

Registry location:

${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE}/${VERSION}/${FILENAME}

The registry version identifies the repository build; the manifest's 1.0.0 identifies a package's local schema-compatible release. Neither is a website content release ID. An existing installed package ID cannot be overwritten just because its registry version changed. Review migration/removal requirements in extensions.

The inherited template replaces same-named files in an existing registry package/version. The job requires curl HTTP failures to return nonzero so a rejected upload cannot look successful. Project job-token permissions and a Docker-capable runner must be configured for the pipeline. Publishing is a CI side effect of the branch/tag pipeline, not of running build.sh locally.

Catalogue design and compatibility

Harbour, Folio and Atlas use optional featured-image slots and require a CMS with that binding. Their paired layouts exercise different structures rather than just colour variants. Harbour and Atlas collapse their mastheads through CSS sticky positioning: the large banner scrolls out while the navigation bar remains pinned. Folio uses a desktop navigation rail. Small-screen layouts retain all navigation links; no browser scripts or external assets are needed.

The new block packs remain ordinary editable HTML/CSS after insertion. Back to top is a native anchor; social links need real profile URLs; FAQs use native details/summary. Preview and publication tests cover installed block markup, styles, theme layouts, featured-image slots and actual browser interactions.

These manifests form a starter collection for Forge, not an implemented remote catalogue or upgrade protocol. Package IDs/versions and the current installation contract remain unchanged. Per-package README files explain customisation and limitations. Existing installed IDs cannot be overwritten.

The four file-gallery block packs use Repeat Files' URI selection, field binding and publication expansion. A fixed CMS-owned runtime supplies their presentation and controls; the ZIP format still accepts no browser scripts. They require a CMS build with file-gallery support. Their templates remain editable after package removal. See gallery markup and browser use.