Files
Elternbeirat/docs/inhalte-pflegen.md
T

130 lines
4.2 KiB
Markdown

# Editing content
How to add or change the visitor-facing content of the site. All content lives
as files under `Elternbeirat.Web/Content/` — there is no database and no admin
interface. Every change needs a **commit** and a **rebuild** of the image, since
the content ships inside the image, not in a volume.
> **Language convention.** File and folder names, front-matter keys and YAML keys
> are English (`posts/`, `title:`, `start:`). The text a visitor reads stays
> German — that includes the *value* after a key (`title: Vorstandsteam`) and the
> Markdown body. So you write English keys with German values.
The three content kinds:
| Kind | Where | New entry = |
|---|---|---|
| Page | `Content/pages/*.md` | one Markdown file |
| Post (news) | `Content/posts/*.md` | one Markdown file |
| Event (calendar) | `Content/events.yml` | one entry in the list |
None of these touch a `.razor` file.
---
## Pages
A page is a standalone Markdown file in `Content/pages/`. The file name (without
`.md`) is the slug and therefore the URL: `vorstandsteam.md` is served at
`/vorstandsteam`.
Front matter at the top sets the title; the body is the content:
```markdown
---
title: Vorstandsteam
---
# Vorstandsteam
Hier stellt sich das Team vor …
```
- **Slugs have no umlauts.** Use `ueber-uns`, not `über-uns`; `foerderverein`,
not `förderverein`. The visible heading in the body may of course use umlauts.
- If you omit `title:`, the slug is used as the title — so always set it.
- Add the new page to the navigation only if it should appear there: edit
`Components/Layout/MainLayout.razor`. Pages that are only linked from other
pages (like the FAQ sub-pages) do not need a nav entry.
---
## Posts (news)
A post is a Markdown file in `Content/posts/`, same idea as a page but with a
date. Posts show up in the news list at `/beitraege`, newest first, and each has
its own URL at `/beitraege/<slug>`.
```markdown
---
title: Neue Sporthalle feierlich eröffnet
date: 2025-10-05
---
# Neue Sporthalle feierlich eröffnet
Der Text des Beitrags …
```
- `date:` is an ISO date, **`yyyy-MM-dd`**. It drives the sort order (newest
first) and the displayed date. A missing or malformed date sorts the post last
rather than breaking the build.
- The three most recent posts are also teased on the home page automatically —
nothing to do there.
---
## Events (calendar)
Events are **not** separate files. They all live in the single list
`Content/events.yml`. Add an entry to the list:
```yaml
- title: Elternbeiratssitzung
start: "2026-10-08 19:30"
location: Lehrerzimmer
note: Themen bitte vorab per E-Mail einreichen.
```
Keys:
| Key | Required | Meaning |
|---|---|---|
| `title` | yes | Short name shown in the list and calendar |
| `start` | yes | When it starts — see date formats below |
| `end` | no | End, for entries that span hours or days |
| `location` | no | e.g. `Aula`, `Mensa` |
| `note` | no | Free text shown below the entry |
**Date formats** for `start` and `end`:
- Date only → all-day event: `"2026-03-15"`
- Date with time: `"2026-03-15 19:30"` (24-hour clock)
Always keep the value in quotes so YAML treats it as text.
The overview at `/termine` splits the list automatically: entries today or later
appear under *Kommende Termine* (earliest first), past ones under *Vergangene
Termine* (most recent first). You do not sort the file yourself — order in the
YAML does not matter.
Visitors can subscribe to `/termine.ics` in their own calendar app; that feed is
generated from the same file, so a new entry appears there too.
> A malformed `start` drops just that one entry instead of breaking the whole
> page, so a typo in one event will not take the calendar down — but the entry
> silently disappears. If an event does not show up, check its `start` value.
---
## Publishing a change
A content change is not live until the image is rebuilt and redeployed:
1. Edit or add the file under `Content/`.
2. Check it locally with `dotnet run --project Elternbeirat.Web`. Content is read
once at startup, so after editing a file **restart the process** to see the
change (or use `dotnet watch` to restart on save automatically).
3. Commit the change.
4. Rebuild and redeploy the image — see [deployment](deployment.md).