Medien komplett neu strukturiert: 3 Welten (Dogfather/HasiDog/Casper) statt Galerie/Videos/Aktionen getrennt

Auf Wunsch von Dogi: Medien-Menü zeigt jetzt Dogfather / HasiDog / Casper
statt Galerie / Videos / Aktionen. Jede der 3 neuen Seiten
(medien-dogfather.html / medien-hasidog.html / medien-casper.html) zeigt
alles zu ihrer Welt an einem Ort, sauber in 3 Bereiche kategorisiert:
Fotos, Videos, Events.

- Neu: assets/js/data-media.js (ersetzt gallery.js) - Fotos jetzt mit
  welt: dogfather|hasidog|casper statt dogfather/team/hasidog/manager.
  Team-Mitglieder-Fotos und Logo entfernt (Wunsch Dogi - passen in keine
  der 3 Welten, bleiben weiter auf ihren Profilseiten). Casper-Fotos aus
  der alten "hasidog"-Sammelkategorie sauber herausgelöst. Zusätzliche
  bisher ungenutzte Fotos ergänzt (dogfather-main, char-dogfather,
  manager-dogfather-portrait, char-hasidog, casper-main).
- Neu: assets/js/data-videos.js - Struktur pro Welt vorbereitet (noch
  keine echten Videos vorhanden, Platzhalter "folgt in Kürze")
- data-aktionen.js: alle 4 bestehenden Events als welt:"dogfather"
  getaggt (alles Team-Dogi-weite Community-Aktionen)
- Neu: assets/js/medien-welt.js - eine gemeinsame Render-Logik für alle
  3 Seiten (liest body[data-welt]), rendert Foto-Grid+Lightbox,
  Video-Grid, Events-Grid gefiltert nach Welt
- aktion-detail.html: "Zurück"-Button zeigt jetzt dynamisch auf die
  Events-Sektion der richtigen Welt (aktion.welt)
- main.js NAV: Medien-Untermenü aktualisiert
- Alle Querverweise site-weit korrigiert (casper.html, community.html,
  hasidog.html, index.html, streamer.html) - Anker-Links (#fotos/#videos/
  #events) für Deep-Links direkt in den passenden Bereich
- Alte Dateien gelöscht: medien.html, videos.html, aktionen.html,
  gallery.js
- sitemap.xml aktualisiert
This commit is contained in:
2026-08-01 16:30:36 +02:00
parent 47350df0c7
commit e9d0c98aed
19 changed files with 393 additions and 294 deletions
+11 -4
View File
@@ -1,15 +1,18 @@
/* =====================================================================
data-aktionen.js — Aktionen & Projekte-Datenobjekt
aktionen.html rendert daraus die Übersichtskarten, aktion-detail.html
liest per URL-Parameter (?id=slug) den passenden Eintrag aus und
zeigt die Detailansicht — so gibt es EIN Template für alle Aktionen,
ohne für jede neue Aktion eine neue HTML-Datei zu brauchen.
Die 3 Welten-Medienseiten (medien-dogfather.html / medien-hasidog.html
/ medien-casper.html) rendern daraus je Welt die passenden Events,
aktion-detail.html liest per URL-Parameter (?id=slug) den passenden
Eintrag aus und zeigt die Detailansicht — so gibt es EIN Template für
alle Aktionen, ohne für jede neue Aktion eine neue HTML-Datei zu
brauchen.
Felder:
id eindeutiger Slug (für aktion-detail.html?id=...)
title, summary, description (Array von Absätzen)
status "geplant" | "läuft" | "abgeschlossen"
welt "dogfather" | "hasidog" | "casper"
tag kurzer Kategorie-Text fürs Badge
photo Pfad zu assets/img/... oder "" für Platzhalter
===================================================================== */
@@ -20,6 +23,7 @@ const AKTIONEN = [
title: "Weihnachtsaktion & Portugal-Trip",
tag: "Tierwohl",
status: "geplant",
welt: "dogfather",
summary: "Weihnachtsaktion für Tierheime in Portugal — Team Dogi hilft Tieren in Not.",
description: [
"Jedes Jahr organisiert Team Dogi eine Weihnachtsaktion zugunsten von Tierheimen in Portugal.",
@@ -32,6 +36,7 @@ const AKTIONEN = [
title: "Community-Treffen (Geburtstag)",
tag: "Community",
status: "geplant",
welt: "dogfather",
summary: "Ein persönliches Treffen mit der Community rund um Dogfathers Geburtstag.",
description: [
"Team Dogi ist Familie — deshalb gibt es ein reales Treffen mit der Community.",
@@ -44,6 +49,7 @@ const AKTIONEN = [
title: "Kooperation: VanVan Teddys",
tag: "Merchandise",
status: "läuft",
welt: "dogfather",
summary: "Merchandise-Kooperation rund um VanVan — Teddys für die Community.",
description: [
"Gemeinsam mit VanVan entstehen limitierte Teddys als Teil des Merchandise-Angebots.",
@@ -56,6 +62,7 @@ const AKTIONEN = [
title: "Online-Shop (in Planung)",
tag: "Merchandise",
status: "geplant",
welt: "dogfather",
summary: "Der eigene Online-Shop für Tassen, Decken, Popsockets, Schlüsselanhänger, Sticker & mehr.",
description: [
"Aktuell läuft der Merchandise-Vertrieb nur über private Einzelbestellungen.",
+38
View File
@@ -0,0 +1,38 @@
/* =====================================================================
data-media.js — Foto-Datenobjekt für die 3 Welten-Medienseiten
(medien-dogfather.html / medien-hasidog.html / medien-casper.html)
Ersetzt das frühere gallery.js (eine gemeinsame Galerie mit
"dogfather/team/hasidog/manager"-Filter) — auf Wunsch von Dogi gibt es
jetzt genau 3 Welten: dogfather, hasidog, casper. Team-Mitglieder-Fotos
und das Logo passen in keine der 3 Welten und wurden bewusst entfernt
(bleiben aber weiterhin auf ihren eigenen Profilseiten sichtbar).
Felder pro Foto: { id, welt: "dogfather"|"hasidog"|"casper", alt, src }
===================================================================== */
const MEDIA = [
// ---- Dogfather ----
{ id: 1, welt: "dogfather", alt: "Dogfather Profilbild", src: "assets/img/dogfather-portrait.jpg" },
{ id: 2, welt: "dogfather", alt: "Dogfather — Team Dogi Karte", src: "assets/img/card-dogfather.jpg" },
{ id: 3, welt: "dogfather", alt: "Dogfather Hauptfoto", src: "assets/img/dogfather-main.jpg" },
{ id: 4, welt: "dogfather", alt: "Dogfather Charakter-Artwork", src: "assets/img/char-dogfather.jpg" },
{ id: 5, welt: "dogfather", alt: "Dogfather als Manager", src: "assets/img/manager-dogfather-portrait.jpg" },
// ---- HasiDog ----
{ id: 6, welt: "hasidog", alt: "HasiDog — das Maskottchen", src: "assets/img/char-hasidog.jpg" },
{ id: 7, welt: "hasidog", alt: "HasiDog & Casper Sticker", src: "assets/img/sticker-hasidog-casper.png" },
{ id: 8, welt: "hasidog", alt: "Schlaft schön — Buch-Illustration", src: "assets/img/hasidog-casper-book.jpg" },
// ---- Casper ----
{ id: 9, welt: "casper", alt: "Casper Hauptfoto", src: "assets/img/casper-main.jpg" },
{ id: 10, welt: "casper", alt: "Husky Casper", src: "assets/img/casper-1.jpg" },
{ id: 11, welt: "casper", alt: "Casper unterwegs", src: "assets/img/casper-2.jpg" },
{ id: 12, welt: "casper", alt: "Casper", src: "assets/img/casper-3.jpg" },
{ id: 13, welt: "casper", alt: "Casper", src: "assets/img/casper-4.jpg" },
{ id: 14, welt: "casper", alt: "Casper & Dogfather", src: "assets/img/dogfather-casper-1.jpg" },
{ id: 15, welt: "casper", alt: "Dogfather & Casper Nase an Nase", src: "assets/img/dogfather-casper-2.jpg" },
// TODO: Aktionen-Fotos (Weihnachtsaktion, VanVan-Teddys) ergänzen, sobald vorhanden.
];
if (typeof window !== "undefined") window.MEDIA = MEDIA;
+21
View File
@@ -0,0 +1,21 @@
/* =====================================================================
data-videos.js — Video-Datenobjekt für die 3 Welten-Medienseiten
Bisher gibt es noch keine echten TikTok-Video-Links/Embeds — die
Struktur steht aber pro Welt bereit, damit nur noch echte Videos
eingetragen werden müssen (src leer = Platzhalter "folgt in Kürze").
Felder pro Video: { id, welt: "dogfather"|"hasidog"|"casper", title, src }
===================================================================== */
const VIDEOS = [
{ id: 1, welt: "dogfather", title: "Streamer-Highlight", src: "" },
{ id: 2, welt: "dogfather", title: "Halligalli-Moment", src: "" },
{ id: 3, welt: "hasidog", title: "HasiDog-Chaos", src: "" },
{ id: 4, welt: "hasidog", title: "Musik-Clip", src: "" },
{ id: 5, welt: "casper", title: "Casper-Moment", src: "" },
{ id: 6, welt: "casper", title: "Husky-Chaos", src: "" },
// TODO: Echte TikTok-Video-Links/Embeds ergänzen, sobald verfügbar.
];
if (typeof window !== "undefined") window.VIDEOS = VIDEOS;
-94
View File
@@ -1,94 +0,0 @@
/* =====================================================================
gallery.js — filterbare Mediengalerie + Lightbox (für medien.html)
MEDIA-Array unten mit echten Bildern befüllen sobald verfügbar
(assets/img/...). Bis dahin rendert jeder Eintrag ohne "src" einen
Platzhalter-Block mit passendem Alt-Text, damit die Struktur schon
steht und nur noch Bilder eingehängt werden müssen.
===================================================================== */
const MEDIA = [
{ id: 1, category: "dogfather", alt: "Dogfather Profilbild", src: "assets/img/dogfather-portrait.jpg" },
{ id: 2, category: "dogfather", alt: "Dogfather — Team Dogi Karte", src: "assets/img/card-dogfather.jpg" },
{ id: 3, category: "team", alt: "VanVan — Team Dogi Karte", src: "assets/img/card-vanvan.jpg" },
{ id: 4, category: "team", alt: "Diene — Team Dogi Karte", src: "assets/img/card-diene.jpg" },
{ id: 5, category: "team", alt: "Miss — Team Dogi Karte", src: "assets/img/card-miss.jpg" },
{ id: 6, category: "team", alt: "Marina alias FlauschiRex — Team Dogi Karte", src: "assets/img/card-marina.jpg" },
{ id: 7, category: "hasidog", alt: "HasiDog & Casper Sticker", src: "assets/img/sticker-hasidog-casper.png" },
{ id: 8, category: "hasidog", alt: "Husky Casper", src: "assets/img/casper-1.jpg" },
{ id: 9, category: "hasidog", alt: "Casper & Dogfather", src: "assets/img/dogfather-casper-1.jpg" },
{ id: 10, category: "hasidog", alt: "Casper", src: "assets/img/casper-3.jpg" },
{ id: 11, category: "hasidog", alt: "Casper", src: "assets/img/casper-4.jpg" },
{ id: 12, category: "hasidog", alt: "Dogfather & Casper Nase an Nase", src: "assets/img/dogfather-casper-2.jpg" },
{ id: 13, category: "hasidog", alt: "Schlaft schön — Buch-Illustration", src: "assets/img/hasidog-casper-book.jpg" },
{ id: 14, category: "hasidog", alt: "Casper unterwegs", src: "assets/img/casper-2.jpg" },
{ id: 15, category: "manager", alt: "Dogfather Logo", src: "assets/img/logo-dogfather.png" },
// TODO: Aktionen-Fotos (Weihnachtsaktion, VanVan-Teddys) ergänzen, sobald vorhanden.
];
function renderGalleryItem(item) {
const media = item.src
? `<img src="${item.src}" alt="${item.alt}" loading="lazy" />`
: `<div class="img-placeholder">${item.alt}<br><span class="small">Foto folgt</span></div>`;
return `
<figure class="gallery-item card" data-category="${item.category}" data-index="${item.id}">
${media}
<figcaption class="small muted" style="margin-top:.6rem;">${item.alt}</figcaption>
</figure>`;
}
function initGallery() {
const grid = document.getElementById("gallery-grid");
const filterBar = document.getElementById("gallery-filters");
if (!grid || !filterBar) return;
const categories = ["alle", ...new Set(MEDIA.map((m) => m.category))];
filterBar.innerHTML = categories
.map(
(c, i) =>
`<button class="filter-btn${i === 0 ? " active" : ""}" data-filter="${c}">${c[0].toUpperCase() + c.slice(1)}</button>`
)
.join("");
function draw(filter) {
const items = filter === "alle" ? MEDIA : MEDIA.filter((m) => m.category === filter);
grid.innerHTML = items.map(renderGalleryItem).join("") || `<p class="muted">Keine Bilder in dieser Kategorie.</p>`;
bindLightbox();
}
filterBar.addEventListener("click", (e) => {
const btn = e.target.closest(".filter-btn");
if (!btn) return;
filterBar.querySelectorAll(".filter-btn").forEach((b) => b.classList.remove("active"));
btn.classList.add("active");
draw(btn.dataset.filter);
});
function bindLightbox() {
const lb = document.getElementById("lightbox");
const lbContent = document.getElementById("lightbox-content");
if (!lb || !lbContent) return;
grid.querySelectorAll(".gallery-item").forEach((el) => {
el.addEventListener("click", () => {
lbContent.innerHTML = el.innerHTML;
lb.classList.add("open");
});
});
}
draw("alle");
const lb = document.getElementById("lightbox");
if (lb) {
lb.addEventListener("click", (e) => {
if (e.target === lb || e.target.closest(".lightbox-close")) {
lb.classList.remove("open");
}
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") lb.classList.remove("open");
});
}
}
document.addEventListener("DOMContentLoaded", initGallery);
+7 -3
View File
@@ -43,11 +43,15 @@
],
},
{
// Medien ist bewusst nach den 3 Welten aufgeteilt statt nach
// Foto/Video/Aktionen getrennt zu sein — Wunsch von Dogi: pro Welt
// (Dogfather/HasiDog/Casper) gibt es EINE Seite mit allem
// kategorisiert (Fotos, Videos, Events), siehe medien-*.html.
label: "Medien",
children: [
{ label: "Galerie", href: "medien.html" },
{ label: "Videos", href: "videos.html" },
{ label: "Aktionen", href: "aktionen.html" },
{ label: "Dogfather", href: "medien-dogfather.html" },
{ label: "HasiDog", href: "medien-hasidog.html" },
{ label: "Casper", href: "medien-casper.html" },
],
},
{ label: "Links", href: "links.html" },
+78
View File
@@ -0,0 +1,78 @@
/* =====================================================================
medien-welt.js — gemeinsame Render-Logik für die 3 Welten-Medienseiten
(medien-dogfather.html / medien-hasidog.html / medien-casper.html)
Jede der 3 Seiten setzt <body data-welt="dogfather|hasidog|casper"> und
lädt data-media.js, data-videos.js, data-aktionen.js VOR dieser Datei —
so gibt es EIN Template/Skript für alle 3 Welten, ohne Code-Verdopplung.
===================================================================== */
function renderFotoItem(item) {
const media = item.src
? `<img src="${item.src}" alt="${item.alt}" loading="lazy" />`
: `<div class="img-placeholder">${item.alt}<br><span class="small">Foto folgt</span></div>`;
return `<figure class="gallery-item card">${media}<figcaption class="small muted" style="margin-top:.6rem;">${item.alt}</figcaption></figure>`;
}
function renderVideoItem(item) {
const media = item.src
? `<video src="${item.src}" controls style="width:100%;aspect-ratio:9/16;object-fit:cover;border-radius:8px;"></video>`
: `<div class="img-placeholder" style="aspect-ratio:9/16;">${item.title}<br><span class="small">Video folgt</span></div>`;
return `<figure class="card">${media}<figcaption class="small muted" style="margin-top:.6rem;">${item.title}</figcaption></figure>`;
}
function renderAktionItem(a) {
return `
<a class="card" href="aktion-detail.html?id=${a.id}">
<span class="tag">${a.tag} · ${a.status}</span>
<h3>${a.title}</h3>
<p>${a.summary}</p>
<span class="small" style="color:var(--accent);">Details ansehen →</span>
</a>`;
}
function bindLightbox() {
const lb = document.getElementById("lightbox");
const lbContent = document.getElementById("lightbox-content");
if (!lb || !lbContent) return;
document.querySelectorAll("#foto-grid .gallery-item").forEach((el) => {
el.addEventListener("click", () => {
lbContent.innerHTML = el.innerHTML;
lb.classList.add("open");
});
});
}
document.addEventListener("DOMContentLoaded", () => {
const welt = document.body.dataset.welt;
if (!welt) return;
const fotoGrid = document.getElementById("foto-grid");
if (fotoGrid) {
const fotos = (window.MEDIA || []).filter((m) => m.welt === welt);
fotoGrid.innerHTML = fotos.map(renderFotoItem).join("") || `<p class="muted">Noch keine Fotos in dieser Welt.</p>`;
bindLightbox();
}
const videoGrid = document.getElementById("video-grid");
if (videoGrid) {
const videos = (window.VIDEOS || []).filter((v) => v.welt === welt);
videoGrid.innerHTML = videos.map(renderVideoItem).join("") || `<p class="muted">Noch keine Videos in dieser Welt.</p>`;
}
const aktionenGrid = document.getElementById("aktionen-grid");
if (aktionenGrid) {
const aktionen = (window.AKTIONEN || []).filter((a) => a.welt === welt);
aktionenGrid.innerHTML = aktionen.map(renderAktionItem).join("") || `<p class="muted">Aktuell keine Events in dieser Welt.</p>`;
}
const lb = document.getElementById("lightbox");
if (lb) {
lb.addEventListener("click", (e) => {
if (e.target === lb || e.target.closest(".lightbox-close")) lb.classList.remove("open");
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") lb.classList.remove("open");
});
}
});