130 lines
4.2 KiB
Markdown
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).
|