CTAO Science Portal — simple proof of concept

The main branch uses the sibling mockup project's layout, assets, CSS, and header interactions. Astro generates a static site. Sveltia CMS edits exactly four Markdown pages in the separate ctao/content repository.

Scope

Example submenu URL Content file
Lorem ipsum /example/lorem-ipsum/ pages/lorem-ipsum.md
Dolor sit amet /example/dolor-sit-amet/ pages/dolor-sit-amet.md
Consectetur adipiscing /example/consectetur-adipiscing/ pages/consectetur-adipiscing.md
Sed do eiusmod /example/sed-do-eiusmod/ pages/sed-do-eiusmod.md

Home, News, Data, Proposals, Dashboard, Sign in, Search, Support, Privacy, Disclaimer, and Contact have the shared header/footer, a title, and an empty body. Search submits to its placeholder. Only English is available; the other language options are inactive. There are no news articles, news pagination, RSS feeds, search index, service integrations, or public sign-in. /admin/ remains the working CMS entry point.

Run locally

Use Node 22.19 or newer (deployment uses Node 24).

npm ci
npm run dev

Open http://localhost:4321/example/lorem-ipsum/ for the full mockup example. The first run copies bundled sample-content/pages/ and uploads/ into the ignored runtime directories. Existing content is preserved. An incomplete existing set fails with a missing-file error instead of silently mixing sample content with editorial content.

npm run content:setup                  # explicitly restore the four sample pages
npm run content:sync -- ../ctao-content # copy from a separate content checkout
npm run check                          # types, static build, internal links
npm run build
npm run preview                        # inspect the built site

content:setup and content:sync replace the four runtime Markdown files and copy uploads, overwriting same-named media. They do not modify the source content checkout. Only the four allowlisted pages are loaded and rendered; unrelated Markdown files never create public routes.

Edit with Sveltia locally, without Gitea

npm run content:local
npm run dev

In Chrome or Edge, open /admin/, select Work with Local Repository, and choose this project's .tmp/content directory. The setup command creates a local Git repository there, seeded from the bundled content. Re-running it preserves edits in that directory.

Save an Example page, then run this in another terminal to refresh the site:

npm run content:sync -- .tmp/content

The local editor writes files without committing them. This follows Sveltia's local workflow. Choose the content repository root, not the portal code repository root: the CMS expects pages/ and uploads/ directly beneath it.

Content and publishing

The CMS uses a fixed file collection. Editors can change title, introduction, optional image/alternative text/caption, Markdown body, and optional button label/destination. Both button fields are needed to display the button. A Markdown blockquote receives the mockup's highlight styling. Images without alternative text are treated as decorative. Menu labels, ordering, URLs, and the shared site layout remain code-controlled.

Remote editing uses Gitea OAuth and saves to ctao/content, branch main. That branch must contain the four files from sample-content/pages/ and the sample upload before publishing this version. The code mirror is ctao/portal, branch main. Deployment independently selects CODE_BRANCH and CONTENT_BRANCH, overlays content, runs checks, and publishes atomically. CONTENT_BRANCH must match backend.branch in the CMS config.

See deploy/README.md for migration and publishing steps. A push to Bitbucket alone does not deploy the site.

Where things live

Path Purpose
src/layouts/Base.astro Mockup header, navigation, footer, page shell
src/components/PageHero.astro Breadcrumb, title, introduction, nebula
src/pages/example/[slug].astro One reusable editable-page template
src/data/examples.json Fixed submenu labels, order, and slugs
src/data/placeholders.json Empty destinations
src/styles/global.css Mockup styles plus Markdown/placeholder variants
public/assets/, public/header.js Mockup assets and menu behavior
sample-content/ Versioned seed content for local use and Gitea setup
src/content/pages/, public/uploads/ Ignored runtime content overlay
public/admin/config.yml Four fixed CMS files and Gitea configuration
scripts/preview-styles.mjs Generates CMS body preview styles from site CSS

The vendored CMS bundle remains in public/vendor/sveltia-cms.js. Dependencies remain pinned; this simplification adds no application dependencies.

S
Description
No description provided
Readme
106 MiB
Languages
CSS 43.8%
Astro 25.8%
JavaScript 16.6%
Shell 12%
TypeScript 1.8%