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:
2026-07-28 19:20:11 +02:00
parent eccf30584a
commit bef5182545
188 changed files with 2770 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
# Normalise to LF in the repository. The CI runner is Linux; shell scripts inside
# the Gitea workflow break if they are checked out with CRLF.
* text=auto eol=lf
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.webp binary
*.pdf binary
+101
View File
@@ -0,0 +1,101 @@
name: Build & Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
inputs:
environment:
description: 'Deployment target'
required: true
default: 'development'
type: choice
options:
- development
- production
env:
HUGO_VERSION: '0.164.0'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Hugo reads git info for lastmod
- name: Install Hugo ${{ env.HUGO_VERSION }}
run: |
set -euo pipefail
curl -sSL -o /tmp/hugo.deb \
"https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.deb"
sudo dpkg -i /tmp/hugo.deb
hugo version
- name: Resolve target
id: target
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "workflow_dispatch" ] \
&& [ "${{ inputs.environment }}" = "production" ]; then
echo "base_url=https://motorradclub-giebelwald.de/" >> "$GITHUB_OUTPUT"
echo "deploy_path=${{ secrets.DEPLOY_PATH_PROD }}" >> "$GITHUB_OUTPUT"
echo "name=production" >> "$GITHUB_OUTPUT"
else
echo "base_url=https://mcg.luxick.de/" >> "$GITHUB_OUTPUT"
echo "deploy_path=${{ secrets.DEPLOY_PATH_DEV }}" >> "$GITHUB_OUTPUT"
echo "name=development" >> "$GITHUB_OUTPUT"
fi
- name: Build
run: |
set -euo pipefail
hugo --gc --minify --baseURL "${{ steps.target.outputs.base_url }}"
# Pull requests are built to catch breakage, but never published.
- name: Deploy to ${{ steps.target.outputs.name }}
if: github.event_name != 'pull_request'
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_PATH: ${{ steps.target.outputs.deploy_path }}
run: |
set -euo pipefail
# rsync runs with --delete, so the destination becomes an exact mirror
# of public/. Refuse to run against an unset, root or shallow path.
case "${DEPLOY_PATH:-}" in
""|"/"|"/root"|"/home"|"/var"|"/etc"|"/usr"|"/srv"|"/opt")
echo "::error::DEPLOY_PATH is unset or unsafe: '${DEPLOY_PATH:-}'" >&2
exit 1
;;
esac
if [ "$(printf '%s' "$DEPLOY_PATH" | tr -cd '/' | wc -c)" -lt 2 ]; then
echo "::error::DEPLOY_PATH '$DEPLOY_PATH' is too shallow to delete into" >&2
exit 1
fi
if [ ! -f public/index.html ]; then
echo "::error::public/index.html missing - refusing to deploy an empty build" >&2
exit 1
fi
sudo apt-get update -qq && sudo apt-get install -y -qq rsync openssh-client
mkdir -p ~/.ssh
chmod 700 ~/.ssh
printf '%s\n' "$SSH_PRIVATE_KEY" > ~/.ssh/id_deploy
chmod 600 ~/.ssh/id_deploy
printf '%s\n' "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
rsync -az --delete --checksum \
-e "ssh -i ~/.ssh/id_deploy -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes" \
public/ "${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/"
rm -f ~/.ssh/id_deploy
+11
View File
@@ -0,0 +1,11 @@
# Hugo build output
/public/
/resources/_gen/
/.hugo_build.lock
# Migration scratch space: originals pulled off the old WordPress host.
# Only the files that get copied into content/, assets/ and static/ are committed.
/.cache/
__pycache__/
*.py[cod]
+113
View File
@@ -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.
+115
View File
@@ -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.
+378
View File
@@ -0,0 +1,378 @@
/* Motorradclub Giebelwald e.V.
Plain CSS on purpose: the project uses the non-extended Hugo binary, which
cannot compile Sass. */
:root {
--ink: #404040; /* carried over from the old HitMag custom CSS */
--ink-soft: #6b6b6b;
--ink-faint: #8c8c8c;
--accent: #9c1c1c;
--accent-dark: #741414;
--bg: #ffffff;
--bg-alt: #f5f4f2;
--border: #e2e0dc;
--font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--measure: 68ch;
--radius: 6px;
--shadow: 0 1px 3px rgb(0 0 0 / 8%), 0 4px 12px rgb(0 0 0 / 6%);
--space-1: 0.5rem;
--space-2: 1rem;
--space-3: 1.5rem;
--space-4: 2.5rem;
--space-5: 4rem;
}
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
margin: 0;
font-family: var(--font);
font-size: 1.0625rem;
line-height: 1.65;
color: var(--ink);
background: var(--bg);
}
img { max-width: 100%; height: auto; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent-dark); }
h1, h2, h3, h4 { line-height: 1.25; font-weight: 700; }
h1 { font-size: clamp(1.75rem, 1.2rem + 2vw, 2.5rem); margin: 0 0 var(--space-2); }
h2 { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.75rem); margin: var(--space-4) 0 var(--space-2); }
h3 { font-size: 1.2rem; margin: var(--space-3) 0 var(--space-1); }
.container {
width: min(100% - 2rem, 68rem);
margin-inline: auto;
}
.skip-link {
position: absolute;
left: -9999px;
background: var(--accent);
color: #fff;
padding: var(--space-1) var(--space-2);
z-index: 100;
}
.skip-link:focus { left: var(--space-2); top: var(--space-2); }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* ---------------------------------------------------------------- header */
.site-header { border-bottom: 1px solid var(--border); }
.site-branding {
display: flex;
align-items: center;
gap: var(--space-2);
padding-block: var(--space-2);
}
.site-logo img { display: block; width: 72px; height: auto; }
.site-titles { min-width: 0; }
.site-title {
margin: 0;
font-size: clamp(1.1rem, 0.9rem + 1.2vw, 1.6rem);
font-weight: 700;
letter-spacing: -0.01em;
}
.site-title a { color: var(--ink); text-decoration: none; }
.site-tagline {
margin: 0;
color: var(--ink-faint);
font-size: 0.95rem;
}
.site-banner {
display: block;
width: 100%;
max-height: 320px;
object-fit: cover;
}
/* ------------------------------------------------------------------ nav */
.site-nav {
background: var(--ink);
position: sticky;
top: 0;
z-index: 20;
}
.nav-toggle { position: absolute; opacity: 0; pointer-events: none; }
.nav-toggle-label {
display: none;
padding: var(--space-2) 0;
color: #fff;
font-weight: 600;
cursor: pointer;
}
.nav-list {
display: flex;
flex-wrap: wrap;
gap: var(--space-3);
list-style: none;
margin: 0;
padding: 0;
}
.nav-list a {
display: block;
padding: 0.85rem 0;
color: #fff;
text-decoration: none;
font-weight: 600;
font-size: 0.95rem;
border-bottom: 3px solid transparent;
}
.nav-list a:hover { color: #fff; border-bottom-color: rgb(255 255 255 / 45%); }
.nav-list a[aria-current="page"] { border-bottom-color: #fff; }
@media (max-width: 640px) {
.nav-toggle-label { display: block; }
.nav-list {
display: none;
flex-direction: column;
gap: 0;
padding-bottom: var(--space-2);
}
.nav-toggle:checked ~ .nav-list { display: flex; }
.nav-list a { padding: 0.6rem 0; border-bottom: 0; }
.nav-list a[aria-current="page"] { text-decoration: underline; }
.nav-toggle:focus-visible ~ .nav-toggle-label { outline: 3px solid #fff; }
}
/* ----------------------------------------------------------------- main */
.site-main { padding-block: var(--space-4) var(--space-5); }
.page-header { margin-bottom: var(--space-3); }
.page-meta {
margin: 0;
color: var(--ink-faint);
font-size: 0.9rem;
}
.tag {
display: inline-block;
margin-left: var(--space-1);
padding: 0.1rem 0.5rem;
background: var(--bg-alt);
border-radius: 999px;
font-size: 0.8rem;
}
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--space-2); }
.prose ul, .prose ol { padding-left: 1.4em; }
.prose hr { border: 0; border-top: 1px solid var(--border); margin-block: var(--space-4); }
.content-figure { margin: var(--space-3) 0; }
.content-figure img { border-radius: var(--radius); display: block; }
.content-figure figcaption {
margin-top: var(--space-1);
color: var(--ink-faint);
font-size: 0.9rem;
}
/* Gallery and post grid escape the reading measure. */
.prose .gallery { max-width: none; }
/* -------------------------------------------------------------- gallery */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
gap: var(--space-1);
margin: var(--space-3) 0;
}
.gallery-item { display: block; border-radius: var(--radius); overflow: hidden; }
.gallery-item img {
display: block;
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
transition: transform 180ms ease;
}
.gallery-item:hover img { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) {
.gallery-item img { transition: none; }
.gallery-item:hover img { transform: none; }
}
/* ---------------------------------------------------------- post grids */
.post-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
gap: var(--space-3);
margin-top: var(--space-2);
}
.post-card {
display: flex;
flex-direction: column;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
}
.post-card:hover { box-shadow: var(--shadow); }
.post-card-image img { display: block; width: 100%; aspect-ratio: 8 / 5; object-fit: cover; }
.post-card-body { padding: var(--space-2); }
.post-card-title { margin: 0 0 0.25rem; font-size: 1.1rem; }
.post-card-title a { color: var(--ink); text-decoration: none; }
.post-card-title a:hover { color: var(--accent); }
.post-card-meta { margin: 0 0 var(--space-1); color: var(--ink-faint); font-size: 0.85rem; }
.post-card-summary { margin: 0; color: var(--ink-soft); font-size: 0.95rem; }
.more-link { margin-top: var(--space-2); font-weight: 600; }
.page-list { padding-left: 1.2em; }
.page-list li { margin-bottom: var(--space-1); }
.post-nav {
display: flex;
justify-content: space-between;
gap: var(--space-2);
margin-top: var(--space-4);
padding-top: var(--space-2);
border-top: 1px solid var(--border);
font-size: 0.95rem;
}
.post-nav .next { margin-left: auto; text-align: right; }
/* ---------------------------------------------------------------- home */
.home-intro { max-width: var(--measure); }
.member-grid, .memoriam-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(120px, 100%), 1fr));
gap: var(--space-2);
list-style: none;
margin: var(--space-2) 0 0;
padding: 0;
}
.member, .memoriam { text-align: center; }
.member img, .memoriam img {
display: block;
width: 100%;
aspect-ratio: 1;
object-fit: cover;
border-radius: 50%;
}
.member-name, .memoriam-name {
display: block;
margin-top: var(--space-1);
font-weight: 600;
font-size: 0.9rem;
}
.memoriam-list { grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); }
.memoriam-date { display: block; color: var(--ink-faint); font-size: 0.85rem; }
/* ------------------------------------------------------------- termine */
.termine {
width: 100%;
border-collapse: collapse;
margin: var(--space-2) 0;
}
.termine th, .termine td {
padding: 0.7rem var(--space-1);
text-align: left;
vertical-align: top;
border-bottom: 1px solid var(--border);
}
.termine th {
white-space: nowrap;
font-weight: 700;
width: 1%;
padding-right: var(--space-2);
}
.termine tr:nth-child(odd) { background: var(--bg-alt); }
.termine-past {
margin-top: var(--space-2);
border-top: 1px solid var(--border);
padding-top: var(--space-1);
}
.termine-past summary {
cursor: pointer;
font-weight: 600;
color: var(--ink-soft);
padding: var(--space-1) 0;
}
@media (max-width: 520px) {
.termine th { white-space: normal; }
}
/* --------------------------------------------------------------- files */
.pdf-link {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2);
margin-bottom: var(--space-1);
border: 1px solid var(--border);
border-radius: var(--radius);
text-decoration: none;
color: var(--ink);
}
.pdf-link:hover { border-color: var(--accent); color: var(--accent); }
.pdf-icon {
flex: none;
padding: 0.2rem 0.45rem;
background: var(--accent);
color: #fff;
border-radius: 3px;
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.05em;
}
.pdf-label { font-weight: 600; }
.pdf-size { margin-left: auto; color: var(--ink-faint); font-size: 0.85rem; }
/* -------------------------------------------------------------- footer */
.site-footer {
border-top: 1px solid var(--border);
background: var(--bg-alt);
padding-block: var(--space-3);
font-size: 0.9rem;
color: var(--ink-soft);
}
.footer-contact { margin: 0 0 var(--space-1); }
.footer-nav { display: flex; gap: var(--space-2); margin-bottom: var(--space-1); }
.footer-copyright { margin: 0; color: var(--ink-faint); }
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

+14
View File
@@ -0,0 +1,14 @@
---
title: "Motorradclub Giebelwald e.V."
---
<!-- TODO: Diesen Einleitungstext ersetzen. Die alte WordPress-Startseite enthielt
nur den Platzhalter "Dies ist nur eine Demo Seite", es gab also keinen Text
zum Übernehmen. -->
Willkommen beim Motorradclub Giebelwald e.V. — gegründet 1976 im Siegerland.
Wir treffen uns regelmäßig zum Fahren, zum Stammtisch und zu unserem jährlichen
Motorradtreffen mit Orientierungsfahrt an der Grillhütte in Niederndorf.
Alle Termine findet ihr unter [Termine](/termine/), Neuigkeiten unter
[Aktuelles](/aktuelles/).
Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

@@ -0,0 +1,37 @@
---
title: "25. O-Fahrt 2022"
date: 2022-06-09T16:08:00Z
lastmod: 2022-09-19T16:43:54Z
tags: ["O-Fahrt"]
featured: "logo.png"
---
![](img-2846-web.jpg)
### Chronik 25 Jahre Orientierungsfahrt
{{< pdf "25-jahre-o-fahrt.pdf" "25 Jahre O-Fahrt" >}}
### Ergebnisse der Orientierungsfahrt
{{< pdf "ergebnisliste-fahrer.pdf" "Ergebnisliste-Fahrer" >}}
{{< pdf "ergebnisliste-sozius.pdf" "Ergebnisliste-Sozius-" >}}
### Termin
**01. - 03. Juli 2022**
Das Treffen und der Start für die O-Fahrt finden an der Grillhütte in
**57258 Freudenberg-Bühl statt.**
**Anfahrt:**
BAB 45 Abfahrt Freudenberg / bei Möbel Zimmermann rechts ab in Richtung Kreuztal bis Ortseingang Bühl fahren. Auf der Kuppe nach rechts abbiegen (Schild MCG)
Die Orientierungsfahrt selbst findet am **Samstag** den **02. Juli** statt.
Gestartet wird zwischen **10:00 Uhr und 12:00 Uhr** an der Grillhütte in Bühl.
Wer sich bereits im Vorfeld anmelden möchte kann, das per Email an [vorstand@motorradclub-giebelwald.de](mailto:vorstand@motorradclub-giebelwald.de) machen.
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

@@ -0,0 +1,23 @@
---
title: "26. O-Fahrt 2023"
date: 2023-07-01T18:14:00Z
lastmod: 2023-07-15T11:34:03Z
tags: ["O-Fahrt"]
featured: "emblem.png"
---
![](6-banner.jpg)Die Sieger der diesjährigen Orientierungsfahrt
{{< gallery "4-1.jpeg" "1-2.jpeg" "7-1.jpeg" "8.jpeg" "5-1.jpeg" >}}
#### Liste aller Starter und Platzierungen
{{< pdf "ranking.pdf" "Ergebnisliste O-Fahrt 2023" >}}
#### Das Roadbook der Tour zum selbst abfahren
{{< pdf "roadbook-2023.pdf" "Roadbook 2023" >}}
#### Chronik 25 Jahre Orientierungsfahrt
{{< pdf "25-jahre-o-fahrt.pdf" "25 Jahre O-Fahrt" >}}
@@ -0,0 +1,23 @@
---
title: "27. O-Fahrt 2024"
date: 2023-07-15T11:42:57Z
lastmod: 2024-06-12T08:09:03Z
---
Termin
**05. - 07. Juli 2024**
Das Treffen und der Start für die O-Fahrt finden an der Grillhütte in
**57258 Freudenberg-Bühl statt.**
**Anfahrt:**
BAB 45 Abfahrt Freudenberg / bei Möbel Zimmermann rechts ab in Richtung Kreuztal bis Ortseingang Bühl fahren. Auf der Kuppe nach rechts abbiegen (Schild MCG)
Die Orientierungsfahrt selbst findet am **Samstag** den **06. Juli** statt.
Gestartet wird zwischen **10:00 Uhr und 12:00 Uhr** an der Grillhütte in Bühl.
Wer sich bereits im Vorfeld anmelden möchte kann, das per Email an [vorstand@motorradclub-giebelwald.de](mailto:vorstand@motorradclub-giebelwald.de) machen.
Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

@@ -0,0 +1,23 @@
---
title: "28. O-Fahrt 2025"
date: 2025-01-03T16:49:54Z
lastmod: 2025-06-05T19:24:29Z
tags: ["O-Fahrt"]
featured: "emblem.png"
---
**27. 29. Juni 2025**
Das Treffen und der Start für die O-Fahrt finden an der Grillhütte in
**57258 Freudenberg-Bühl statt.**
**Anfahrt:**
BAB 45 Abfahrt Freudenberg / bei Möbel Zimmermann rechts ab in Richtung Kreuztal bis Ortseingang Bühl fahren. Auf der Kuppe nach rechts abbiegen (Schild MCG)
Die Orientierungsfahrt selbst findet am **Samstag** den **28. Juni** statt.
Gestartet wird zwischen **10:00 Uhr und 12:00 Uhr** an der Grillhütte in Bühl.
Wer sich bereits im Vorfeld anmelden möchte kann, das per Email an [vorstand@motorradclub-giebelwald.de](mailto:vorstand@motorradclub-giebelwald.de) machen.
Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

@@ -0,0 +1,22 @@
---
title: "29. O-Fahrt zum 50. Jubiläum"
date: 2026-01-13T10:05:22Z
lastmod: 2026-06-13T07:42:53Z
featured: "logo.png"
---
**10. 12. Juli 2026**
Das Treffen und der Start für die O-Fahrt finden an der Grillhütte in
**57258 Freudenberg-Niederndorf statt.**
![](image.png)
[Google Maps Link](https://maps.app.goo.gl/LL2YBPYZmeE3nnUr9)
Die Orientierungsfahrt selbst findet am **Samstag** den **11. Juli** statt.
Gestartet wird zwischen **09:00 Uhr und 11:00 Uhr** an der Grillhütte in Niederndorf.
Anmeldungen sind erst Samstag morgen möglich. Wer sich allerdings zur Planung schon vorher ankündigen möchte kannd das gerne per Email an [vorstand@motorradclub-giebelwald.de](mailto:vorstand@motorradclub-giebelwald.de) machen.
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

@@ -0,0 +1,10 @@
---
title: "600 Jahre Niederndorf"
date: 2023-06-26T09:36:00Z
lastmod: 2023-07-02T09:42:32Z
featured: "banner.jpeg"
---
Am 18.06.2023 hat zur Feier des 600 jährigen bestehens von Niederndorf ein "stehender" Umzug an der Reithalle im Ort stattfgefunden. HIer war der Motorradclub natürlich auch vertreten
{{< gallery "1.jpeg" "2.jpeg" "3.jpeg" "4.jpeg" "5.jpeg" "6.jpeg" "7.jpeg" >}}
+8
View File
@@ -0,0 +1,8 @@
---
title: "Aktuelles"
date: 2018-08-06T07:41:40Z
lastmod: 2020-06-28T08:19:29Z
---
Neuigkeiten aus dem Verein.
Binary file not shown.

After

Width:  |  Height:  |  Size: 894 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

@@ -0,0 +1,19 @@
---
title: "Biker-Demo gegen Fahrverbote am 4.7.2020"
date: 2020-07-06T09:53:33Z
lastmod: 2020-07-06T09:54:16Z
featured: "image-4.png"
---
![](image.png)
![](image-1.png)**Treffpunkt Siegen-Siegerlandhalle**
![](image-2.png)**Um 8:15 starteten die Biker durch Siegen Richtung Littfeld**
![](image-3.png)**Zur Demo auf dem Düsseldorfer Messegelände ging es über Landstraße in
mehreren Gruppen.**
![](image-4.png)**Auf dem Messeparkplatz in Düsseldorf fanden sich etwa 10 000 Biker ein.**
![](image-5.png)
Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

@@ -0,0 +1,14 @@
---
title: "Ehrungen von Mitgliedern 2018"
date: 2018-08-07T08:24:48Z
lastmod: 2020-04-02T15:23:05Z
featured: "20180317-203519.jpg"
---
![](20180317-203519.jpg)
von links: Roland für 40 Jahre; Burkhard für 30 Jahre; Jens und Jürgen für 25 Jahre
![](20180317-203949.jpg)
**Siegerehrung der Jahresfahrt 2017**
@@ -0,0 +1,10 @@
---
title: "Grillen nach Photoshooting"
date: 2022-05-16T13:58:00Z
lastmod: 2022-06-10T14:04:01Z
featured: "whatsapp-image-2022-05-26-at-17-47-06-1.jpeg"
---
Am 14.05.2022 Haben wir uns noch einmal in gemütlicher Runde zusammengefunden um am Abend die Reste des Season Openings zu vergrillen.
![](whatsapp-image-2022-05-26-at-17-47-06.jpeg)
Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

@@ -0,0 +1,22 @@
---
title: "Kundgebung gegen Fahrverbote"
date: 2020-06-30T14:49:16Z
lastmod: 2020-06-30T14:49:17Z
featured: "kundgebung-landtag-nrw.jpg"
---
![](kundgebung-siegen.png)
Wenn Du Dich, ebenso wie wir, gegen die geplanten Fahrverbote für Motorradfahrer an Sonn- und Feiertagen wendest, dann unterstütze uns bei unserer Kundgebung am **04.07.2020**
Wir starten an diesem Tag gemeinsam mit unseren Motorrädern
an der Siegerlandhalle (P&R-Parkplatz) und fahren in einem angemeldeten Korso durch
Siegen bis Kreuztal-Krombach
Von dort kannst Du optional mit uns in Kleingruppen bis zur Hauptveranstaltung nach Düsseldorf fahren.
Jedes Bike zählt!! Du zählst!! Hilf uns und mach mit!!
### Weitere Infos
[https://motorcycles.news/event/kundgebung-gegen-motorradfahrverbote-vor-dem-landtag-nrw/](https://motorcycles.news/event/kundgebung-gegen-motorradfahrverbote-vor-dem-landtag-nrw/)
Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

@@ -0,0 +1,10 @@
---
title: "MCG auf der Rennstrecke"
date: 2021-08-10T14:00:00Z
lastmod: 2022-07-01T06:52:45Z
featured: "img-20211104-wa0000.jpg"
---
Unser erster Vorsitzender Christopher Lorscheiter zeigt auf der Rennstrecke was er kann
{{< gallery "img-20211104-wa0000.jpg" "img-20211104-wa0001.jpg" "img-20211104-wa0002.jpg" "img-20211104-wa0003.jpg" "img-20211104-wa0004.jpg" "img-20211104-wa0005.jpg" "img-20211104-wa0006.jpg" "img-20211104-wa0007.jpg" >}}
Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

@@ -0,0 +1,18 @@
---
title: "Mitgliederehrungen 2019"
date: 2019-03-08T15:12:25Z
lastmod: 2020-04-02T15:22:58Z
featured: "img-20190209-205905-2.jpg"
---
Auch dieses Jahr wurden wieder Mitglieder für Ihre langjährige Mitgliedschaft im Verein Geehrt
![](img-20190209-205905-2.jpg)von links: Uwe und Steffi , Dirk L. und Jens G. (Für 10 Jahre)
---
Den zweiten Platz der Jahresfahrt von 2018 Teilen sich dieses Jahr **Heike und Udo Ratgeber**.
Der erste Platz geht an **Sven Rehm.**
![](img-20190209-210323.jpg)von links: Heike R., Sven, Udo
Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

@@ -0,0 +1,18 @@
---
title: "Mitgliederehrungen 2020"
date: 2020-04-02T15:20:30Z
lastmod: 2020-04-02T15:22:41Z
featured: "10jahre.jpeg"
---
Auch dieses Jahr wurden wieder Mitglieder für Ihre langjährige Mitgliedschaft im Verein Geehrt
![](10jahre.jpeg)von links nach rechts: Marcel Fries, Kai Dietzel, Peter Uebach
Für langjährige Mitgliedschaft im Verein wurden dieses Jahr geehrt:
Marcel Fries für **10 Jahre** Mitgliedschaft
Kai Dietzel für **30 Jahre** Mitgliedschaft
Peter Uebach für **25 Jahre** Mitgliedschaft
Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

@@ -0,0 +1,16 @@
---
title: "Mitgliederehrungen 2022"
date: 2022-11-20T17:11:53Z
lastmod: 2022-11-20T17:12:27Z
featured: "ehrungen1.jpg"
---
Auf der Jahreshauptversammlung im November 2022 wurden zwei Mitglieder des Clubs für ihre langjährige Mitgliedschaft ausgezeichnet.
![](ehrungen1.jpg)
Christiane (links im Bild) wird für **30 Jahre** Mitgliedschaft im Verein geehrt
![](ehrungen2.jpg)
Marvin (links im Bild) wird für **10 Jahre** Mitgliedschaft im Verein geehrt
@@ -0,0 +1,9 @@
---
title: "Regelmäßger Stammtisch"
date: 2022-09-19T16:20:42Z
lastmod: 2022-09-19T16:20:43Z
---
Ab dem 5. Oktober wird ein regelmäßiger Stammtisch im Backes in Niederndorf stattfinden.
Der Termin ist der **erste Mittwoch** des Monats um **19:00 Uhr**
@@ -0,0 +1,10 @@
---
title: "Saison Abschlussgrillen"
date: 2022-09-19T16:23:35Z
---
Am 15. Oktober findet das Abschlussgrillen für die Saison 2022 statt.
Wir Treffen uns um 19:00 Uhr bei Lurchi.
Grillgut ist noch reichlich vorhanden, Getränke werden besorgt.
@@ -0,0 +1,15 @@
---
title: "Vorankündigung MCG Wochenende 2024"
date: 2023-03-11T10:03:48Z
featured: "whatsapp-image-2022-05-26-at-17-47-34.jpeg"
---
![](whatsapp-image-2022-05-26-at-17-47-34.jpeg)
*Save the Date!*
Das MCG Wochenende im Haus Marienmünster in Hövelhof wird nächstes Jahr an folgendem Datum stattfinden:
**09.-12. Mai 2024** Wochenende Himmelfahrt
Weitere Infos und Anmeldung folgen im laufe des Jahres
Binary file not shown.

After

Width:  |  Height:  |  Size: 351 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Some files were not shown because too many files have changed in this diff Show More