Plone Aurora training project with a Python CMFPlone backend.
Beyond the standard monorepo scaffold, this training project ships a couple of
examples in the frontend add-on
(frontend/packages/aurora-training-project)
that exercise different Aurora extension points:
- The Likes feature — a slot component, a server-side
rootLoaderDatautility, a resource route, and an extra backend (a Prisma/SQLite database) plugged into an Aurora app alongside Plone. - The Highlight block — a registry ("Plone") block that demonstrates the block anatomy, a schema-driven settings form, block width, and a custom background-color style field with a React Aria color-swatch widget.
Both features are covered by Playwright acceptance tests under
frontend/acceptance.
Every page shows a 👍 Like button with the number of times that URL has been liked; clicking it increments the count in place. Under the hood it wires together:
- A slot component —
LikeButtonis registered into thecontentAreaslot, so it renders on content views (slots/LikeButton.tsx,config/slots.ts). - A
rootLoaderDataserver utility — runs server-side, reads the current path's like count from the database, and merges it into the root loader data (exposed asrootData.likes), so the count is server-rendered (config/server.ts). - A resource route —
/@likes/*returns the count for a path onGETand increments it onPOST; the button'sfetcheruses it for live updates (routes/api.likes.ts,config/routes.ts). - An extra backend — a Prisma ORM + SQLite store (a
single
UrlLikemodel keyed by pathname) that lives entirely outside Plone's ZODB, showing how to integrate a secondary datastore (prisma/schema.prisma,lib/prisma.ts).
The Likes acceptance tests live in
frontend/acceptance/tests/likes.test.ts.
Note
The Likes data lives in a local SQLite database. See the Set up the Likes database (Prisma) section below for the one-time setup.
A registry ("Plone") block that highlights a short message. It is a compact tour
of how a block is built and styled in Aurora
(blocks/Highlight):
- Block registration — the block config (
view,edit,blockSchema, icon, category) is registered intoconfig.blocks.blocksConfig(blocks/Highlight/index.ts,config/blocks.ts). - Inline editing vs. settings form — the title and body are edited inline on
the canvas, while the styling controls live in the schema-driven settings form
(
blocks/Highlight/HighlightBlockEdit.tsx,blocks/Highlight/schema.tsx). - Block width — exposed through the shared
blockWidthstyle field (widget: 'width',styleField: true); the block content fills the selected width in the public view (styles/highlight.css). - A custom style field —
backgroundColoris a project-defined style field. AstyleFieldDefinitionmaps the stored id (for exampleamber) to a--highlight-bgCSS custom property, and a custom settings widget built on React Aria'sColorSwatchPickerpicks the value (config/blocks.ts,blocks/Highlight/HighlightColorWidget.tsx,blocks/Highlight/palette.ts). - Add-on styles — view and editor styles are loaded through the add-on
styles/publicui.cssandstyles/cmsui.cssconvention (styles/publicui.css,styles/cmsui.css).
The Highlight acceptance tests live in
frontend/acceptance/tests/highlight.test.ts.
- An operating system that runs all the requirements mentioned.
- uv
- nvm
- Node.js 24 and pnpm
- Make
- Git
- Docker (optional)
-
Clone this repository, then change your working directory.
git clone git@github.com:collective/aurora-training-project.git cd aurora-training-project -
Install this code base.
make install
The Likes feature stores its data in a local SQLite database managed by Prisma, separate from the Plone backend. Set it up once after installing.
-
Generate the Prisma client. (This also runs automatically as part of
make install, so you can usually skip it.)pnpm --filter aurora-training-project prisma:generate
-
Create the SQLite database and its schema.
pnpm --filter aurora-training-project prisma:db:push
This creates
frontend/packages/aurora-training-project/prisma/dev.dbwith a singleUrlLiketable. The database file and the generated client are git-ignored.
DATABASE_URL is already configured in the frontend package.json scripts
(dev, start, start:prod, and the prisma:* commands), so you don't need to
set any environment variable to run the app or the tools.
Handy Prisma commands (run from the repository root):
| Command | Description |
|---|---|
pnpm --filter aurora-training-project prisma:generate |
Regenerate the Prisma client after editing the schema |
pnpm --filter aurora-training-project prisma:db:push |
Sync the schema to the SQLite database |
pnpm --filter aurora-training-project prisma:migrate |
Create and apply a migration |
pnpm --filter aurora-training-project prisma:studio |
Open Prisma Studio to browse the data |
Once the database exists, start the servers (below) and the 👍 Like button will work on every page.
-
Create a new Plone site on your first run.
make backend-create-site
-
Start the backend at http://localhost:8080/.
make backend-start
-
In a new shell session, start the frontend at http://localhost:3000/.
make frontend-start
Voila! Your Plone site should be live and kicking! 🎉
Deploy a local Docker Compose environment that includes the following.
- Docker images for Backend and Frontend 🖼️
- A stack with a Traefik router and a PostgreSQL database 🗃️
- Accessible at http://aurora-training-project.localhost 🌐
Run the following commands in a shell session.
make stack-create-site
make stack-startAnd... you're all set! Your Plone site is up and running locally! 🚀
This monorepo consists of the following distinct sections:
- backend: Houses the API and Plone installation, utilizing pip instead of buildout, and includes a policy package named aurora.training.project.
- frontend: Contains the Aurora application and project add-on.
- devops: Encompasses Docker stack, Ansible playbooks, and cache settings.
- docs: Scaffold for writing documentation for your project.
- All necessary codebases to run the site are contained within the repository (excluding existing add-ons for Plone and React).
- Specific GitHub Workflows are triggered based on changes in each codebase (refer to .github/workflows).
- Simplifies the creation of Docker images for each codebase.
- Demonstrates Plone installation/setup without buildout.
To check your code against quality standards, run the following shell command.
make checkTo format and rewrite the code base, ensuring it adheres to quality standards, run the following shell command.
make format| Section | Tool | Description | Configuration |
|---|---|---|---|
| backend | Ruff | Python code formatting, imports sorting | backend/pyproject.toml |
| backend | zpretty |
XML and ZCML formatting | -- |
| frontend | ESLint | Fixes most common frontend issues | frontend/.eslintrc.js |
| frontend | prettier | Format JS and Typescript code | frontend/.prettierrc |
| frontend | Stylelint | Format Styles (css, less, sass) | frontend/.stylelintrc |
Formatters can also be run within the backend or frontend folders.
or lint:
make lint| Section | Tool | Description | Configuration |
|---|---|---|---|
| backend | Ruff | Checks code formatting, imports sorting | backend/pyproject.toml |
| backend | Pyroma | Checks Python package metadata | -- |
| backend | check-python-versions | Checks Python version information | -- |
| backend | zpretty |
Checks XML and ZCML formatting | -- |
| frontend | ESLint | Checks JS / Typescript lint | frontend/.eslintrc.js |
| frontend | prettier | Check JS / Typescript formatting | frontend/.prettierrc |
| frontend | Stylelint | Check Styles (css, less, sass) formatting | frontend/.stylelintrc |
Linters can be run individually within the backend or frontend folders.
Generate translation files for Plone and Aurora with ease:
make i18nGenerated using Cookieplone (2.0.0b3) and cookieplone-templates (662183a) on 2026-09-13 11:51:27.245162. A special thanks to all contributors and supporters!