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.
