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:
+113
@@ -0,0 +1,113 @@
|
||||
# WordPress → Hugo Migration
|
||||
|
||||
Record of the one-time import from the WordPress export at
|
||||
`wordpress-export/motorradclubgiebelwaldev.WordPress.2026-07-28.xml`
|
||||
(WordPress 7.0.2, HitMag theme, TablePress, `widgets_on_pages`).
|
||||
|
||||
## Result
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Content files | 26 (9 pages + 17 posts) |
|
||||
| Media placed | 127 / 165 attachments |
|
||||
| Internal links checked | 718, 0 broken |
|
||||
| Stale `wp-content/` URLs | 0 |
|
||||
|
||||
Re-verify at any time with:
|
||||
|
||||
```sh
|
||||
hugo --gc --minify
|
||||
python tools/verify_migration.py
|
||||
```
|
||||
|
||||
## URL changes
|
||||
|
||||
Old permalinks were **not** preserved (deliberate — no redirects were required).
|
||||
|
||||
| Old | New |
|
||||
|---|---|
|
||||
| `/2026/01/13/29-o-fahrt-zum-50-jubilaum/` | `/aktuelles/29-o-fahrt-zum-50-jubilaeum/` |
|
||||
| `/2025/01/03/termin/` | `/aktuelles/28-o-fahrt-2025/` |
|
||||
| `/2022/06/09/o-fahrt-2019/` | `/aktuelles/25-o-fahrt-2022/` |
|
||||
| `/40-jahre-mcg/` | `/archiv/40-jahre-mcg/` |
|
||||
| `/familenausfahrt-2019/` | `/archiv/familienausfahrt-2019/` |
|
||||
| `/bilder-familienausfahrt/` | `/archiv/bilder-familienausfahrt/` |
|
||||
| `/familienfahrt-2022/` | `/archiv/familienfahrt-2022/` |
|
||||
| `/vergangene-o-fahren/` | `/archiv/vergangene-o-fahrten/` |
|
||||
| `/aktuelles/`, `/termine/`, `/downloads/`, `/impressum/` | unchanged |
|
||||
|
||||
Two post slugs were misleading in WordPress and were renamed to match their own
|
||||
titles: `o-fahrt-2019` → `25-o-fahrt-2022`, `termin` → `28-o-fahrt-2025`.
|
||||
Umlaut slugs were transliterated (`jubilaum` → `jubilaeum`).
|
||||
|
||||
## What was dropped, and why
|
||||
|
||||
| WP id | Item | Reason |
|
||||
|---|---|---|
|
||||
| 3 | "Privacy Policy" | Stock English WordPress template, still a draft, references an old bare IP address. Not usable. The Impressum already carries a `Datenschutz` section, which was migrated verbatim. |
|
||||
| 12 | "Home" | Body was the placeholder *"Dies ist nur eine Demo Seite"*. The real homepage came from the HitMag magazine template plus widgets. |
|
||||
| 410 | untitled draft post | Empty. |
|
||||
|
||||
## Things the export did not contain
|
||||
|
||||
The WXR format carries neither media binaries nor widgets. Both were recovered
|
||||
from the live site before it is retired:
|
||||
|
||||
- **Media** — `tools/fetch_media.py` downloads all 165 uploads, caps them at
|
||||
2000 px on the long edge and re-encodes JPEG at q82. Cached in `.cache/`
|
||||
(gitignored); only files actually used are committed.
|
||||
- **Widgets** — the homepage *Unsere Mitglieder* grid (20 portraits) and the
|
||||
sidebar *In Erinnerung* block were WordPress widgets. `tools/build_data.py`
|
||||
scrapes them off the rendered homepage into `data/members.yaml` and
|
||||
`data/memoriam.yaml`.
|
||||
|
||||
Note: the WordPress gallery widget **shuffles member order on every request**,
|
||||
so the original order carried no meaning. Members are now sorted by name.
|
||||
|
||||
## Structural changes
|
||||
|
||||
- **Termine** — the six TablePress tables (`Termine 2020`–`2026`) became
|
||||
`data/termine.yaml`. WordPress only ever embedded table id 7 (*Termine 2026*)
|
||||
on one page; the other five were orphaned. The `/termine/` page now shows the
|
||||
newest year expanded with earlier years in collapsible sections.
|
||||
- **Aktuelles** — was a page containing `[widgets_on_pages id="1"]`. It is now a
|
||||
real Hugo section with an RSS feed.
|
||||
- **Categories** — `uncategorized` and `aktuelles` were noise and were dropped.
|
||||
`ofahrt` became the tag `O-Fahrt`.
|
||||
|
||||
## Data defects found in the export
|
||||
|
||||
- Post 81 (*Ehrungen von Mitgliedern 2018*) references `wp-image-83`, but
|
||||
attachment 83 no longer exists — the media record was deleted while the upload
|
||||
survived. `tools/wp2hugo.py` recovers such references by matching the `src`
|
||||
filename instead.
|
||||
- Almost every page ends with an empty `<p></p>` paragraph; these are stripped.
|
||||
- WordPress wrote emphasis with the whitespace *inside* the markers
|
||||
(`<strong>Samstag </strong>`), which is not valid CommonMark emphasis. The
|
||||
converter moves the whitespace outside.
|
||||
|
||||
## Unused media (38 files, downloaded but not committed)
|
||||
|
||||
These exist in the WordPress media library but appear nowhere on the live site.
|
||||
They are still in `.cache/uploads/` if any are wanted later.
|
||||
|
||||
- **Superseded member portraits (2019)** — `Bene_2`, `Burckhardt_2`, `Christian_2`,
|
||||
`Christoph_2`, `Christopher_2`, `HeikeF`, `HeikeR`, `Henning`, `JensB`,
|
||||
`Katrin_2`, `Marcel_2`, `Marvin_2`, `Rainer`, `Steffi_und_Sabine`, `Sven_2`,
|
||||
`Timo_1`, `Timo_2`, `Udo`, `Uwe`, `Gruppenbildanja`. Replaced by the 2022
|
||||
`*_web.jpg` set.
|
||||
- **Former members** — `Jannik_web.jpg`, `Timo_web.jpg` (present in the library,
|
||||
removed from the live member grid).
|
||||
- **Old theme assets** — `title.jpg`, `cropped-title.jpg`, `bg.jpeg`,
|
||||
`Banner_small_web.jpg` (uncropped), and six `cropped-Emblem_transparent*.png`
|
||||
logo crops. The site now uses `assets/img/logo.png` and `assets/img/banner.jpg`.
|
||||
- **Orphans** — `SZ-Artikel.jpg`, `Banner.jpg` (2023), `1-1.jpeg`, `6-scaled.jpg`,
|
||||
`IMG_20190209_205905-3.jpg`, `jahresfahrt-2019.jpg`.
|
||||
|
||||
## Open items
|
||||
|
||||
- `content/_index.md` carries a **placeholder intro** marked with a `TODO`. There
|
||||
was no homepage text in WordPress to migrate — please replace it.
|
||||
- No separate Datenschutzerklärung page exists. The site is fully static with no
|
||||
cookies, forms or third-party embeds, and the Impressum contains a Datenschutz
|
||||
section. Worth a legal review before the production cutover.
|
||||
Reference in New Issue
Block a user