feat(11.1-03): add the Setup and Console docs sections
- setup: introduction, installation rewritten from install to serve, configuration with the keys an application sets - console: introduction, setup and maintenance, scaffolding, writing commands, utilities; every command name is checker-verified - bonfire ExampleCatalog shows arguments, bare and repeatable flags - index links the section introductions; TestDocsRequiredPages lists the seven new pages
This commit is contained in:
70
docs/setup/configuration.md
Normal file
70
docs/setup/configuration.md
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: Configuration
|
||||
description: Configure an application with YAML files, per-environment directories, plugin defaults and SUMMER_ environment variables, and set the keys it needs.
|
||||
section: setup
|
||||
order: 30
|
||||
---
|
||||
# Configuration
|
||||
|
||||
WinterCMS keeps configuration in `config/*.php` files, per-environment directories and `.env`. SummerCMS keeps the same shape with YAML files, merged by [compass](../../modules/compass/README.md) into one tree that you read with dot paths such as `app.name`.
|
||||
|
||||
## The config directory
|
||||
|
||||
Each YAML file in the application's `config/` directory is a section named after the file, so `config/app.yaml` provides the `app.*` keys and `config/http.yaml` provides `http.*`:
|
||||
|
||||
```yaml
|
||||
# config/app.yaml
|
||||
name: Acme
|
||||
url: http://127.0.0.1:8080
|
||||
timezone: Europe/Warsaw
|
||||
```
|
||||
|
||||
Files for one environment go in `config/env/<environment>/` with the same naming, and override the base files. The environment comes from `SUMMER_ENV` and defaults to `production`, so a development setup sets `SUMMER_ENV=development` and keeps its overrides in `config/env/development/`.
|
||||
|
||||
## Plugin defaults
|
||||
|
||||
A plugin ships its own defaults embedded in the binary through `pact.HasConfig`. Its `config/config.yaml` becomes `<plugin id>.<key>`, so the `posts_per_page` key of `acme.blog` is read as `acme.blog.posts_per_page`. WinterCMS writes the same key as `acme.blog::posts_per_page`. The application overrides a plugin default like any other key: put `posts_per_page` under `blog:` in `config/acme.yaml`.
|
||||
|
||||
## Environment variables
|
||||
|
||||
Any key can be overridden with an environment variable. Take the dot path, replace each dot with a double underscore, upper-case it and prefix `SUMMER_`:
|
||||
|
||||
| Key | Variable |
|
||||
|-----|----------|
|
||||
| `database.dsn` | `SUMMER_DATABASE__DSN` |
|
||||
| `app.key` | `SUMMER_APP__KEY` |
|
||||
| `admin.jwt.secret` | `SUMMER_ADMIN__JWT__SECRET` |
|
||||
|
||||
A `.env` file next to the `config/` directory supplies `KEY=VALUE` lines for variables that are not already set in the real environment. Keep secrets in the environment or in `.env`, never in committed YAML.
|
||||
|
||||
Environment values are strings. Keys that must be numbers, such as `http.body_limits.default_bytes`, belong in a YAML file.
|
||||
|
||||
The layers merge in this order, each overriding the ones before it: plugin defaults, `config/*.yaml`, `config/env/<environment>/*.yaml`, `SUMMER_` variables, then runtime overrides that a command saved to `config/env/<environment>/overrides.yaml`.
|
||||
|
||||
## Keys an application sets
|
||||
|
||||
These are the keys most applications set. Each module's reference page lists all of its keys and their defaults.
|
||||
|
||||
| Key | Purpose | Reference |
|
||||
|-----|---------|-----------|
|
||||
| `database.dsn` | PostgreSQL connection string. Required by every command that opens the database. | [lagoon](../../modules/lagoon/README.md) |
|
||||
| `app.key` | Base64 encoding of 32 random bytes, used to encrypt columns. Generate it with `key:generate`. | [lagoon](../../modules/lagoon/README.md) |
|
||||
| `app.timezone` | Timezone of scheduled commands. Defaults to UTC. | [conga](../../modules/conga/README.md) |
|
||||
| `app.locale`, `app.fallback_locale` | Default and fallback translation locales. | [phrasebook](../../modules/phrasebook/README.md) |
|
||||
| `http.body_limits.default_bytes`, `http.body_limits.upload_bytes` | Request body limits. Required by `serve` and `route:list`. | [surf](../../modules/surf/README.md) |
|
||||
| `http.cors.*`, `http.trusted_proxies` | CORS and the proxies whose forwarded client IP is trusted. | [surf](../../modules/surf/README.md) |
|
||||
| `storage.uploads.bucket_url` | Uploads bucket, `file://` or `mem://`. Required by `serve`. | [lagoon](../../modules/lagoon/README.md) |
|
||||
| `admin.jwt.secret` | Secret for admin tokens. Required as soon as a plugin registers an admin controller. | [cabana](../../modules/cabana/README.md) |
|
||||
| `backend.uri` | Path the admin is served under. Defaults to `/backend`. | [cabana](../../modules/cabana/README.md) |
|
||||
| `mail.driver`, `mail.from`, `mail.smtp.*` | Mail delivery: `memory`, `log` or `smtp`. | [postcard](../../modules/postcard/README.md) |
|
||||
| `queue.work_in_serve`, `queue.queues.*` | Whether `serve` runs the job worker, and workers per queue. | [conga](../../modules/conga/README.md) |
|
||||
| `realtime.driver`, `realtime.centrifugo.*` | The realtime driver and its Centrifugo settings. | [lighthouse](../../modules/lighthouse/README.md) |
|
||||
| `search.driver`, `search.typesense.*` | The search engine and its Typesense settings. | [beachcomber](../../modules/beachcomber/README.md) |
|
||||
| `push.enabled`, `push.public_key`, `push.private_key` | Web Push with VAPID keys. | [flare](../../modules/flare/README.md) |
|
||||
|
||||
> [!NOTE]
|
||||
> The documentation checks every identifier, link and command name it shows against the code, but not configuration keys. The keys on this page are reviewed by hand; the module reference pages are the authority.
|
||||
|
||||
## Reading configuration in a plugin
|
||||
|
||||
Plugins read configuration from `backpack.App.Config`, a `compass.Config`. Use `compass.Config.String`, `compass.Config.Int` and `compass.Config.Bool` for single values, which return the zero value for a missing key, `compass.Config.Has` to tell a missing key from a zero value, and `compass.Config.LoadSection` to decode a whole section into a struct.
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Installation
|
||||
description: Install the Go toolchain, PostgreSQL and the summer CLI you need to build a SummerCMS application.
|
||||
description: Install the Go toolchain, PostgreSQL and the summer CLI, then build, configure, migrate and serve your first SummerCMS application.
|
||||
section: setup
|
||||
order: 20
|
||||
---
|
||||
# Installation
|
||||
|
||||
SummerCMS is a Go module. An application requires it, lists its plugins in a `summer.yaml` manifest and builds everything into one binary with the `summer` CLI.
|
||||
SummerCMS is a Go module. An application requires it, lists its plugins in a `summer.yaml` manifest and builds everything into one binary with the `summer` CLI. This page installs the tool, then builds and runs `examples/hello`, the small reference application in the framework repository.
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -57,3 +57,71 @@ if err := bonfire.Call(context.Background(), commands, "acme:greet", []string{"b
|
||||
```
|
||||
|
||||
If the tests above pass, this example ran and printed `Hello, blog`. See the [bonfire](../../modules/bonfire/README.md) reference for flags, prompts and styled output.
|
||||
|
||||
## Build the example application
|
||||
|
||||
`examples/hello` has three compiled plugins. From the framework root, build it with `summer build`, which generates `plugins.gen.go` and `main.go` from `summer.yaml` and writes the binary to `bin/hello`:
|
||||
|
||||
```sh
|
||||
cd examples/hello
|
||||
summer build
|
||||
./bin/hello --help
|
||||
./bin/hello greeter:hello
|
||||
./bin/hello key:generate
|
||||
```
|
||||
|
||||
`greeter:hello` prints the example's layered configuration and `key:generate` prints a fresh application key. Neither needs a database.
|
||||
|
||||
## Create the database
|
||||
|
||||
The commands that touch data open PostgreSQL. Create a database with the locale lagoon checks for:
|
||||
|
||||
```sql
|
||||
CREATE DATABASE hello TEMPLATE template0 ENCODING 'UTF8' LOCALE_PROVIDER icu ICU_LOCALE 'pl-PL';
|
||||
```
|
||||
|
||||
## Configure the application
|
||||
|
||||
Configuration comes from YAML files in `config/`. Any key can be overridden with a `SUMMER_` environment variable, in which a double underscore separates path segments: `SUMMER_DATABASE__DSN` sets `database.dsn`. [Configuration](configuration.md) explains the layers.
|
||||
|
||||
`serve` and `route:list` need request body limits, and surf reads them as numbers, which the string-valued environment overlay cannot supply. Create `config/http.yaml` in `examples/hello`:
|
||||
|
||||
```yaml
|
||||
body_limits:
|
||||
default_bytes: 1048576
|
||||
upload_bytes: 10485760
|
||||
```
|
||||
|
||||
Then point the binary at the database, give it the application key and an uploads bucket. Replace the `<secret>` markers with your own values, and never commit them:
|
||||
|
||||
```sh
|
||||
export SUMMER_DATABASE__DSN='postgres://acme:<secret>@127.0.0.1:5432/hello?sslmode=disable'
|
||||
export SUMMER_APP__KEY='<value printed by key:generate>'
|
||||
export SUMMER_STORAGE__UPLOADS__BUCKET_URL='mem://'
|
||||
```
|
||||
|
||||
## Migrate and serve
|
||||
|
||||
Run the migrations, list the routes and start the server on the loopback address:
|
||||
|
||||
```sh
|
||||
./bin/hello migrate
|
||||
./bin/hello route:list
|
||||
./bin/hello serve --addr 127.0.0.1:8080
|
||||
curl http://127.0.0.1:8080/items/1
|
||||
```
|
||||
|
||||
From the application directory, `summer migrate`, `summer migrate:status` and `summer serve` run the same commands through the built binary, building it first when it is missing.
|
||||
|
||||
> [!WARNING]
|
||||
> Known issues in the current framework:
|
||||
>
|
||||
> - `examples/hello` ships no `http.body_limits` configuration, so `serve` and `route:list` fail with `surf: config http.body_limits.default_bytes is required` until you add `config/http.yaml` as shown above. The same gap makes the example's `TestTypedItemRoute` fail.
|
||||
> - lagoon refuses any database whose default locale is not ICU `pl-PL`.
|
||||
> - The committed `examples/hello/main.go` is older than what `summer build` generates now, so building the example leaves that file modified. Restore it with `git checkout -- examples/hello/main.go` if you do not intend to commit it.
|
||||
|
||||
## Next steps
|
||||
|
||||
- Read [Coming from WinterCMS](coming-from-wintercms.md) if you are porting a WinterCMS plugin.
|
||||
- Read the [Architecture introduction](../architecture/introduction.md) to see how the pieces fit.
|
||||
- Scaffold your own plugin with `summer make:plugin` as described in [Plugin registration](../plugins/registration.md).
|
||||
|
||||
39
docs/setup/introduction.md
Normal file
39
docs/setup/introduction.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: What SummerCMS is, who it is for, how its headless model works and how this documentation is organised.
|
||||
section: setup
|
||||
order: 10
|
||||
---
|
||||
# Introduction
|
||||
|
||||
SummerCMS is a content management framework for Go, inspired by WinterCMS. It keeps what makes WinterCMS productive (plugins that extend each other, backend lists and forms described in YAML, models, migrations and console scaffolding) and compiles an application into a single binary.
|
||||
|
||||
## Who it is for
|
||||
|
||||
SummerCMS is for developers who build content-driven applications and APIs the WinterCMS way and want a compiled, typed backend. If you already know WinterCMS, most concepts carry over: a plugin still has an ID, requires other plugins, registers and boots, ships migrations and admin YAML, and adds console commands. Start with [Coming from WinterCMS](coming-from-wintercms.md) for a concept-by-concept map.
|
||||
|
||||
## The headless model
|
||||
|
||||
SummerCMS is headless. An application serves:
|
||||
|
||||
- a JSON API, declared route by route by its plugins;
|
||||
- an admin area, a compiled single-page application embedded in the binary, driven by each plugin's `fields.yaml` and `columns.yaml`;
|
||||
- console commands for migrations, workers, the scheduler and your own tasks.
|
||||
|
||||
It does not render public pages. There are no themes, CMS pages, layouts, components or AJAX framework. Build the public site as a separate frontend application that calls the JSON API and, for live updates, subscribes to realtime channels.
|
||||
|
||||
## One binary
|
||||
|
||||
Plugins are Go packages compiled into the application at build time. The `summer` tool reads the application's `summer.yaml` manifest, generates the plugin imports and builds one executable. Nothing is loaded or installed at runtime, so what you tested is exactly what you deploy.
|
||||
|
||||
The data layer supports PostgreSQL only, and SummerCMS targets Go 1.27.
|
||||
|
||||
## How these docs are organised
|
||||
|
||||
- **Setup** covers installation, configuration and the move from WinterCMS.
|
||||
- **Architecture** explains the single binary, Go modules, the application lifecycle and how a request reaches your code.
|
||||
- **Plugins** covers registering a plugin, scheduling, extending other plugins and testing.
|
||||
- **Console** lists the `summer` tool's commands and the commands of every application binary, and shows how to write your own.
|
||||
- **API reference** has one page per framework module.
|
||||
|
||||
Continue with [Installation](installation.md).
|
||||
Reference in New Issue
Block a user