# 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). ```sh 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. ```sh 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 ```sh 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: ```sh npm run content:sync -- .tmp/content ``` The local editor writes files without committing them. This follows [Sveltia's local workflow](https://sveltiacms.app/en/docs/workflows/local). 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](https://sveltiacms.app/en/docs/collections/files). 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](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.