Migrate WordPress site to Hugo
Replaces the WordPress 7.0.2 / HitMag site with a static Hugo build,
deployed by Gitea Actions over rsync/SSH.
Content: 26 files (9 pages + 17 posts) as Markdown page bundles, plus
127 of 165 media attachments. The remaining 38 are media-library
leftovers that appear nowhere on the live site; they are listed in
MIGRATION.md.
The WXR export contains neither media binaries nor widgets, so both were
recovered from the live host before it is retired:
- tools/fetch_media.py downloads all uploads, capping them at 2000px
- tools/build_data.py scrapes the "Unsere Mitglieder" and
"In Erinnerung" widgets into data/*.yaml
TablePress' six Termine tables became data/termine.yaml, rendered with
the newest year expanded and earlier years collapsed. Old permalinks are
not preserved (clean slugs, no redirects, as agreed).
Custom layouts, no third-party theme. Plain CSS, since the pinned Hugo
0.164.0 is the non-extended build and cannot compile Sass.
Verified: clean build with zero warnings, 718 internal links checked and
none broken, no surviving wp-content URLs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# motorradclub-giebelwald.de
|
||||
|
||||
Static website of the Motorradclub Giebelwald e.V., built with [Hugo](https://gohugo.io).
|
||||
|
||||
- Development: <https://mcg.luxick.de>
|
||||
- Production: <https://motorradclub-giebelwald.de>
|
||||
|
||||
Migrated from WordPress in July 2026 — see [MIGRATION.md](MIGRATION.md).
|
||||
|
||||
## 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`. 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 |
|
||||
|
||||
## Deployment
|
||||
|
||||
`.gitea/workflows/deploy.yml` builds with Hugo and rsyncs `public/` over SSH.
|
||||
|
||||
- Push to `main` → deploys to **mcg.luxick.de**
|
||||
- Manual *Run workflow* with `environment: production` → deploys to
|
||||
**motorradclub-giebelwald.de**
|
||||
- Pull requests are built but never published
|
||||
|
||||
### 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` | Output of `ssh-keyscan <host>` |
|
||||
| `DEPLOY_HOST` | `server.example.de` |
|
||||
| `DEPLOY_USER` | `www-deploy` |
|
||||
| `DEPLOY_PATH_DEV` | `/var/www/mcg-dev` |
|
||||
| `DEPLOY_PATH_PROD` | `/var/www/mcg` |
|
||||
|
||||
rsync runs with `--delete`, so each `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`.
|
||||
|
||||
## Migration tooling
|
||||
|
||||
`tools/` holds the one-shot WordPress importer, kept so the import stays
|
||||
reproducible and reviewable. It is not part of the build.
|
||||
|
||||
```sh
|
||||
python tools/fetch_media.py # download uploads from the live WP host
|
||||
python tools/build_data.py # termine / members / memoriam
|
||||
python tools/wp2hugo.py # content bundles (won't overwrite; --force to do so)
|
||||
python tools/verify_migration.py # inventory + link checks (run after `hugo`)
|
||||
```
|
||||
|
||||
Requires Python 3.11+ and Pillow.
|
||||
Reference in New Issue
Block a user