# motorradclub-giebelwald.de

Static website of the Motorradclub Giebelwald e.V., built with [Hugo](https://gohugo.io).

Currently served at <https://mcg.luxick.de>. Once the site is signed off, the
main domain <https://motorradclub-giebelwald.de> will be pointed at the same
server and the old host retired — see [Changing the domain](#changing-the-domain).

## Requirements

Hugo **0.164.0**. The *non-extended* build is sufficient: the site uses plain CSS,
no Sass.

## Local development

```sh
hugo server -D      # http://localhost:1313
hugo --gc --minify  # production build into public/
```

## Editing content

Everything lives in Markdown under `content/`, edited via git (locally or in
Gitea's web editor).

### Add a news post

Create `content/aktuelles/<slug>/index.md`:

```markdown
---
title: "30. O-Fahrt 2027"
date: 2027-01-15T10:00:00Z
tags: ["O-Fahrt"]
featured: "titelbild.jpg"
---

Text …

{{< gallery "bild1.jpg" "bild2.jpg" >}}
```

Drop the images into the same folder. `featured` picks the teaser image; without
it the first image in the folder is used.

### Add or change a Termin

Edit `data/termine.yaml`. The newest year is shown expanded, older years collapse:

```yaml
"2027":
  - date: "06.02.2027\n18:30"
    description: "Jahreshauptversammlung\nSängerheim Niederndorf"
```

### Members / In Erinnerung

`data/members.yaml` and `data/memoriam.yaml`. Images go in `assets/img/`.

### Downloads

Put the PDF in `static/dokumente/` and link it from `content/downloads.md`:

```markdown
{{< pdf "satzung.pdf" "Unsere Satzung" >}}
```

## Shortcodes

| Shortcode | Purpose |
|---|---|
| `{{< gallery "a.jpg" "b.jpg" >}}` | Thumbnail grid; no arguments = all images in the bundle |
| `{{< figure "bild.jpg" "Bildunterschrift" >}}` | Single image with caption |
| `{{< pdf "datei.pdf" "Titel" >}}` | Download link with file size |

## Site structure

```
content/
  _index.md              Startseite
  aktuelles/             News section (RSS enabled)
  archiv/                Rückblicke auf frühere Fahrten
  termine.md             uses layouts/termine.html + data/termine.yaml
  downloads.md
  impressum.md
data/                    termine, members, memoriam
assets/                  css/main.css, img/ (logo, banner, portraits)
static/dokumente/        PDFs
layouts/                 baseof, home, list, page, termine
  _partials/  _shortcodes/  _markup/
```

## Deployment

`.gitea/workflows/deploy.yml` builds with Hugo and rsyncs `public/` over SSH to
the VPS webroot.

- Push to `main` → builds and deploys
- *Run workflow* → manual re-deploy of the current `main`
- Pull requests are built to catch breakage, but never published

There is one deploy target. For development, run the site locally with
`hugo server`.

### Deploying from a workstation

`scripts/deploy.sh` does the same thing without CI — useful while the Gitea
runner is not set up. It needs `rsync`, so run it from WSL or another Linux
shell, not Git Bash or PowerShell.

```sh
cp scripts/deploy.env.example scripts/deploy.env   # then fill it in (gitignored)
./scripts/deploy.sh --dry-run                      # preview, upload nothing
./scripts/deploy.sh                                # build, preview, confirm, deploy
```

| Flag | Effect |
|---|---|
| `--dry-run` | Stop after the preview |
| `--yes` | Skip the confirmation prompt |
| `--skip-build` | Deploy the existing `public/`, e.g. after building on Windows |

The script previews every change and reports how many files would be **deleted**
on the server before asking to continue. Keep the SSH key inside the WSL
filesystem — a key under `/mnt/c` cannot hold `0600`, and ssh will reject it.

### Required secrets

Set these in the Gitea repository settings:

| Secret | Example |
|---|---|
| `SSH_PRIVATE_KEY` | Deploy key with write access to the webroot |
| `SSH_KNOWN_HOSTS` | Verified output of `ssh-keyscan <host>` |
| `DEPLOY_HOST` | `server.example.de` |
| `DEPLOY_USER` | `www-deploy` |
| `DEPLOY_PATH` | `/var/www/mcg` |

rsync runs with `--delete`, so `DEPLOY_PATH` must point at a directory owned
solely by this site. The workflow refuses to deploy if the path is unset, too
shallow, or if the build produced no `index.html`.

### Changing the domain

`baseURL` in `hugo.toml` is the only place the live domain is configured; it
feeds canonical URLs, `og:url`, the RSS feed and the sitemap. To cut over:

1. Point the DNS record at the VPS.
2. Add the domain to the nginx `server_name` and reissue the certificate.
3. Change `baseURL` in `hugo.toml` and push — the deploy rebuilds every
   absolute URL.
