Stadionzeitung: Galerie-Seite als Bento-Raster
Optionale Live-Seite hinter dem Ergebnis-Rückblick mit Fotos vom letzten Spiel. bin/stadionzeitung-add.php liest sie aus <ordner>/galerie/, Kopf und Alt-Texte sind Chat-Pflege und hängen an source. Preflight meldet fehlende Galerie-Dateien. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PCMNXcfkM9RcaVjqoJjRsz
This commit is contained in:
17
CLAUDE.md
17
CLAUDE.md
@@ -548,6 +548,8 @@ Inhalt:
|
|||||||
Rand: Freistellungs-Exporte lassen oft viel leeren, transparenten
|
Rand: Freistellungs-Exporte lassen oft viel leeren, transparenten
|
||||||
Rand stehen, sonst wirkt der Spieler auf dem Cover kleiner als nötig)
|
Rand stehen, sonst wirkt der Spieler auf dem Cover kleiner als nötig)
|
||||||
<ordner>/verfasser.* optional, Porträtfoto für die Signatur im automatischen Vorwort
|
<ordner>/verfasser.* optional, Porträtfoto für die Signatur im automatischen Vorwort
|
||||||
|
<ordner>/galerie/* optional, Fotos vom letzten Spiel (natsort, das erste ist der
|
||||||
|
Aufmacher, höchstens sieben) für die Bento-Galerie-Seite
|
||||||
```
|
```
|
||||||
**Keine Anzeigen im Ablieferordner** (seit 31.07.2026): die kommen aus dem dauerhaften Bestand
|
**Keine Anzeigen im Ablieferordner** (seit 31.07.2026): die kommen aus dem dauerhaften Bestand
|
||||||
`data/anzeigen.json`, gepflegt mit `php bin/anzeige-add.php <bild-oder-ordner>` (Dateiname = Slug,
|
`data/anzeigen.json`, gepflegt mit `php bin/anzeige-add.php <bild-oder-ordner>` (Dateiname = Slug,
|
||||||
@@ -571,6 +573,7 @@ Inhalt ist eine Liste von **Blöcken**, die Anzeigen füllen die Lücken dazwisc
|
|||||||
```
|
```
|
||||||
Cover → [Vorwort → Programm* → Interview → Aufruf (jedes nur wenn die Ausgabe es trägt)] ⌷
|
Cover → [Vorwort → Programm* → Interview → Aufruf (jedes nur wenn die Ausgabe es trägt)] ⌷
|
||||||
[Turnierpläne*: je Turnier eine Seite, EIN Block] ⌷ Ergebnis-Rückblick ⌷
|
[Turnierpläne*: je Turnier eine Seite, EIN Block] ⌷ Ergebnis-Rückblick ⌷
|
||||||
|
[Galerie, nur wenn galerie/ geliefert] ⌷
|
||||||
[Gegnerstatistik: normal nur die tragende Mannschaft, in der Sportfest-Ausgabe je
|
[Gegnerstatistik: normal nur die tragende Mannschaft, in der Sportfest-Ausgabe je
|
||||||
Mannschaft mit Heimspiel am Fest eine — EIN Block, automatisch aus deren Tabelle] ⌷
|
Mannschaft mit Heimspiel am Fest eine — EIN Block, automatisch aus deren Tabelle] ⌷
|
||||||
[je Mannschaft eine Tabelle, Reihenfolge = matchcenter.json — EIN Block, dazwischen nie eine
|
[je Mannschaft eine Tabelle, Reihenfolge = matchcenter.json — EIN Block, dazwischen nie eine
|
||||||
@@ -606,7 +609,7 @@ Lücken bekommen 7 Lücken zwei. Zwei hintereinander ist das Optimum, nicht eins
|
|||||||
Zweier-Paar auf einer Doppelseite landen kann, schlägt man das Heft gelegentlich auf zwei Anzeigen auf.
|
Zweier-Paar auf einer Doppelseite landen kann, schlägt man das Heft gelegentlich auf zwei Anzeigen auf.
|
||||||
Ein `images[]`-Eintrag hat
|
Ein `images[]`-Eintrag hat
|
||||||
`"type": "image"` (wie gehabt, `base`/`widths`/`alt`) oder `"type": "live"` (`page`: `cover` |
|
`"type": "image"` (wie gehabt, `base`/`widths`/`alt`) oder `"type": "live"` (`page`: `cover` |
|
||||||
`vorwort` | `interview` | `programm` | `aufruf` | `turnier` | `tabelle` | `termine` | `news` | `ergebnisse` | `gegner` | `vorschau` | `kontakt` | `mitglied` | `historie` | `sportheim` | `partner` | `danke` | `momente` | `impressum`, kein Bild;
|
`vorwort` | `interview` | `programm` | `aufruf` | `turnier` | `tabelle` | `termine` | `news` | `ergebnisse` | `gegner` | `vorschau` | `kontakt` | `mitglied` | `historie` | `sportheim` | `partner` | `danke` | `momente` | `galerie` | `impressum`, kein Bild;
|
||||||
`tabelle` und `gegner` zusätzlich mit `team`: Team-Key aus `matchcenter.json`, ohne `team` greift der
|
`tabelle` und `gegner` zusätzlich mit `team`: Team-Key aus `matchcenter.json`, ohne `team` greift der
|
||||||
Team-Key der Ausgabe; `turnier` mit `turnier`: Key aus `turniere[]` der Ausgaben-Veranstaltung;
|
Team-Key der Ausgabe; `turnier` mit `turnier`: Key aus `turniere[]` der Ausgaben-Veranstaltung;
|
||||||
`danke` mit `anzeige`: das platzierte Anzeigenmotiv, siehe unten). Fehlt `type` (alte Phase-1-Ausgaben) → Fallback `image`, bricht nicht. **Gerendert
|
`danke` mit `anzeige`: das platzierte Anzeigenmotiv, siehe unten). Fehlt `type` (alte Phase-1-Ausgaben) → Fallback `image`, bricht nicht. **Gerendert
|
||||||
@@ -819,6 +822,18 @@ chat-gepflegt und von `bin/stadionzeitung-add.php` über erneute Läufe durchget
|
|||||||
Nebenbei löst das oft die Seitenzahl: drei Gegnerseiten statt einer sind **zwei Seiten mehr**, und
|
Nebenbei löst das oft die Seitenzahl: drei Gegnerseiten statt einer sind **zwei Seiten mehr**, und
|
||||||
ein Heft, das bei 42 stand, steht damit auf 44.
|
ein Heft, das bei 42 stand, steht damit auf 44.
|
||||||
|
|
||||||
|
**Galerie-Seite (02.10.2026): Fotos vom letzten Spiel als Bento-Raster.** Optional, hinter dem
|
||||||
|
Ergebnis-Rückblick (`stadionzeitung-galerie.php`). Das Feld `galerie` mischt zwei Pfleger, wie bei
|
||||||
|
den Veranstaltungsbildern: `kicker`, `heading`, `text` und die **Alt-Texte** sind Chat-Pflege,
|
||||||
|
`bilder[]` schreibt `bin/stadionzeitung-add.php` aus `<ordner>/galerie/` (Breiten 640/1200).
|
||||||
|
Alt-Texte hängen an `source` (Originaldateiname) und folgen ihrem Bild; neue Fotos bekommen die
|
||||||
|
Überschrift als Platzhalter, das Skript nennt sie per WARN. **Der Ordner ist der komplette
|
||||||
|
Bestand:** ein Lauf ohne `galerie/` lässt die Seite entfallen, weil der Ausgaben-Ordner geleert
|
||||||
|
wurde. Kein Snapshot nötig, die Bilder liegen im Ausgaben-Ordner und kein Sync fasst sie an.
|
||||||
|
Raster: 6×4-Gitter, das erste Foto 4×2, die Anordnung je Anzahl (1 bis 7) als Klasse
|
||||||
|
`__bento--nN` mit `grid-template-areas`. Entstanden als Füllseite, die eine 43-seitige Ausgabe
|
||||||
|
auf 44 brachte.
|
||||||
|
|
||||||
**Gegner- und Ergebnisseite neu gestaltet (19.09.2026).** Beide Seiten waren inhaltlich richtig und
|
**Gegner- und Ergebnisseite neu gestaltet (19.09.2026).** Beide Seiten waren inhaltlich richtig und
|
||||||
gestalterisch leer, der Umbau lief über mehrere verworfene Entwürfe. Was davon bleibt:
|
gestalterisch leer, der Umbau lief über mehrere verworfene Entwürfe. Was davon bleibt:
|
||||||
- **Ergebnisse als Anzeigetafel** (Vorbild kicker/Sofascore): Wappen und Name je Seite, das Ergebnis
|
- **Ergebnisse als Anzeigetafel** (Vorbild kicker/Sofascore): Wappen und Name je Seite, das Ergebnis
|
||||||
|
|||||||
50
app/components/stadionzeitung-galerie.php
Normal file
50
app/components/stadionzeitung-galerie.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Galerie-Seite der Stadionzeitung (Live-Seite, optional) — Fotos vom letzten
|
||||||
|
* Spiel als Bento-Raster: ein großes Aufmacherfoto, die übrigen in kleineren
|
||||||
|
* Kacheln darum. Das Raster füllt die ganze Blattfläche unter dem Kopf, die
|
||||||
|
* Fotos werden per object-fit auf ihre Kachel beschnitten.
|
||||||
|
*
|
||||||
|
* Props: $issue Eintrag aus data/stadionzeitung.json. Gelesen wird das Feld
|
||||||
|
* `galerie`: `kicker`, `heading`, `text?` sind Chat-Pflege, `bilder[]`
|
||||||
|
* (base/widths/alt/source) schreibt bin/stadionzeitung-add.php aus
|
||||||
|
* <ordner>/galerie/. Alt-Texte kommen aus dem Chat und hängen an `source`.
|
||||||
|
*
|
||||||
|
* Die Bilder liegen im Ausgaben-Ordner und werden von keinem Sync angefasst,
|
||||||
|
* deshalb braucht die Seite keinen Snapshot.
|
||||||
|
*/
|
||||||
|
$galerie = is_array($issue['galerie'] ?? null) ? $issue['galerie'] : [];
|
||||||
|
$bilder = array_slice(array_values(array_filter(
|
||||||
|
$galerie['bilder'] ?? [],
|
||||||
|
static fn ($b): bool => is_array($b) && !empty($b['base']) && !empty($b['widths'])
|
||||||
|
)), 0, 7);
|
||||||
|
$kicker = trim((string) ($galerie['kicker'] ?? 'Rückblick'));
|
||||||
|
$heading = trim((string) ($galerie['heading'] ?? 'Fotos vom letzten Spiel'));
|
||||||
|
$text = trim((string) ($galerie['text'] ?? ''));
|
||||||
|
?>
|
||||||
|
<div class="stadionzeitung-galerie">
|
||||||
|
<header class="stadionzeitung-page__head">
|
||||||
|
<?php if ($kicker !== ''): ?>
|
||||||
|
<p class="stadionzeitung-page__kicker"><?= e($kicker) ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<h2 class="stadionzeitung-page__heading"><?= e($heading) ?></h2>
|
||||||
|
<?php if ($text !== ''): ?>
|
||||||
|
<p class="stadionzeitung-galerie__text"><?= e($text) ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</header>
|
||||||
|
<?php if ($bilder !== []): ?>
|
||||||
|
<div class="stadionzeitung-galerie__bento stadionzeitung-galerie__bento--n<?= count($bilder) ?>">
|
||||||
|
<?php foreach ($bilder as $i => $bild): ?>
|
||||||
|
<?php component('img', [
|
||||||
|
'image' => $bild,
|
||||||
|
// Aufmacher gut zwei Drittel der Seitenbreite, die Kacheln ein Drittel.
|
||||||
|
'sizes' => $i === 0 ? '(min-width: 520px) 340px, 70vw' : '(min-width: 520px) 240px, 50vw',
|
||||||
|
'class' => 'stadionzeitung-galerie__foto',
|
||||||
|
]); ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
@@ -11,7 +11,8 @@ declare(strict_types=1);
|
|||||||
* type 'image' (base/widths/alt),
|
* type 'image' (base/widths/alt),
|
||||||
* type 'live' (page: cover|vorwort|interview|programm|aufruf|turnier|
|
* type 'live' (page: cover|vorwort|interview|programm|aufruf|turnier|
|
||||||
* tabelle|termine|news|ergebnisse|gegner|vorschau|kontakt|
|
* tabelle|termine|news|ergebnisse|gegner|vorschau|kontakt|
|
||||||
* mitglied|historie|sportheim|partner|danke|momente|impressum;
|
* mitglied|historie|sportheim|partner|danke|momente|galerie|
|
||||||
|
* impressum;
|
||||||
* tabelle und gegner optional mit team: Team-Key aus
|
* tabelle und gegner optional mit team: Team-Key aus
|
||||||
* matchcenter.json; turnier mit turnier: Key aus
|
* matchcenter.json; turnier mit turnier: Key aus
|
||||||
* veranstaltungen.json → turniere[] der Ausgaben-Veranstaltung),
|
* veranstaltungen.json → turniere[] der Ausgaben-Veranstaltung),
|
||||||
@@ -96,6 +97,9 @@ $type = $entry['type'] ?? 'image';
|
|||||||
wie jede andere Anzeige in images[] eingefroren ist. */ ?>
|
wie jede andere Anzeige in images[] eingefroren ist. */ ?>
|
||||||
<?php component('stadionzeitung-danke', ['anzeige' => $entry['anzeige'] ?? null]); ?>
|
<?php component('stadionzeitung-danke', ['anzeige' => $entry['anzeige'] ?? null]); ?>
|
||||||
<?php break; ?>
|
<?php break; ?>
|
||||||
|
<?php case 'galerie': ?>
|
||||||
|
<?php component('stadionzeitung-galerie', ['issue' => $issue]); ?>
|
||||||
|
<?php break; ?>
|
||||||
<?php case 'momente': ?>
|
<?php case 'momente': ?>
|
||||||
<?php component('stadionzeitung-momente', ['items' => $data['momente'] ?? []]); ?>
|
<?php component('stadionzeitung-momente', ['items' => $data['momente'] ?? []]); ?>
|
||||||
<?php break; ?>
|
<?php break; ?>
|
||||||
|
|||||||
@@ -386,6 +386,24 @@ if (is_file($szFile)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Stadionzeitung: Galerie-Fotos vorhanden? ---
|
||||||
|
// Die Galerie-Bilder liegen im Ausgaben-Ordner, den bin/stadionzeitung-add.php bei
|
||||||
|
// jedem Lauf leert und neu füllt. Fehlt eine Datei (Lauf ohne galerie/ im Ordner,
|
||||||
|
// Bild nicht mitcommittet), zeigt die Seite ein kaputtes Bild.
|
||||||
|
if (is_file($szFile)) {
|
||||||
|
$szData = $szData ?? (json_decode((string) file_get_contents($szFile), true) ?: []);
|
||||||
|
foreach ($szData['issues'] ?? [] as $ausgabe) {
|
||||||
|
foreach ($ausgabe['galerie']['bilder'] ?? [] as $bild) {
|
||||||
|
foreach ($bild['widths'] ?? [] as $w) {
|
||||||
|
$datei = PUBLIC_PATH . '/assets/' . ($bild['base'] ?? '') . "-{$w}.jpg";
|
||||||
|
if (!is_file($datei)) {
|
||||||
|
$errors[] = "Stadionzeitung '{$ausgabe['slug']}': Galerie-Foto fehlt (" . ($bild['base'] ?? '?') . "-{$w}.jpg).";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Inline-Styles (die CSP verwirft sie stillschweigend) ---
|
// --- Inline-Styles (die CSP verwirft sie stillschweigend) ---
|
||||||
// Diese Prüfung existiert wegen eines echten Ausfalls am 31.07.2026: der
|
// Diese Prüfung existiert wegen eines echten Ausfalls am 31.07.2026: der
|
||||||
// Banner-Slider setzte sein Hintergrundbild per style="--banner-bg: url(…)". Auf
|
// Banner-Slider setzte sein Hintergrundbild per style="--banner-bg: url(…)". Auf
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ declare(strict_types=1);
|
|||||||
* <ordner>/spieler.* optional, freigestelltes Spielerfoto (PNG mit Transparenz)
|
* <ordner>/spieler.* optional, freigestelltes Spielerfoto (PNG mit Transparenz)
|
||||||
* fürs Cover — wird unverändert kopiert, nie über GD neu kodiert
|
* fürs Cover — wird unverändert kopiert, nie über GD neu kodiert
|
||||||
* <ordner>/verfasser.* optional, Porträtfoto für die Vorwort-Signatur
|
* <ordner>/verfasser.* optional, Porträtfoto für die Vorwort-Signatur
|
||||||
|
* <ordner>/galerie/* optional, Fotos vom letzten Spiel (natsort = Reihenfolge,
|
||||||
|
* das erste ist der Aufmacher) für die Bento-Galerie-
|
||||||
|
* Seite hinter dem Ergebnis-Rückblick, höchstens sieben
|
||||||
*
|
*
|
||||||
* KEINE Anzeigen im Ordner (seit 31.07.2026): die kommen aus dem dauerhaften
|
* KEINE Anzeigen im Ordner (seit 31.07.2026): die kommen aus dem dauerhaften
|
||||||
* Bestand data/anzeigen.json, gepflegt mit bin/anzeige-add.php. Sponsorenmotive
|
* Bestand data/anzeigen.json, gepflegt mit bin/anzeige-add.php. Sponsorenmotive
|
||||||
@@ -157,6 +160,7 @@ $vorwort = $findOne('vorwort');
|
|||||||
$rueckseite = $findOne('rueckseite');
|
$rueckseite = $findOne('rueckseite');
|
||||||
$spieler = $findOne('spieler');
|
$spieler = $findOne('spieler');
|
||||||
$verfasser = $findOne('verfasser');
|
$verfasser = $findOne('verfasser');
|
||||||
|
$galerieQuellen = $findAll('galerie');
|
||||||
// Anzeigen kommen NICHT mehr aus dem Ablieferordner, sondern aus dem dauerhaften
|
// Anzeigen kommen NICHT mehr aus dem Ablieferordner, sondern aus dem dauerhaften
|
||||||
// Bestand (data/anzeigen.json, gepflegt über bin/anzeige-add.php). Ein noch
|
// Bestand (data/anzeigen.json, gepflegt über bin/anzeige-add.php). Ein noch
|
||||||
// vorhandener anzeigen/-Unterordner wäre also wirkungslos — dann besser sagen,
|
// vorhandener anzeigen/-Unterordner wäre also wirkungslos — dann besser sagen,
|
||||||
@@ -206,6 +210,9 @@ $oldCover = $oldIssue['cover'] ?? null;
|
|||||||
// der BFV-Zeile) und die Liste der Mannschaften, die zusätzlich eine
|
// der BFV-Zeile) und die Liste der Mannschaften, die zusätzlich eine
|
||||||
// Gegnerseite bekommen — beides Chat-Pflege, überlebt erneute Läufe wie vorwort.
|
// Gegnerseite bekommen — beides Chat-Pflege, überlebt erneute Läufe wie vorwort.
|
||||||
$oldOpponentShort = $oldIssue['opponent_short'] ?? null;
|
$oldOpponentShort = $oldIssue['opponent_short'] ?? null;
|
||||||
|
// Galerie-Seite: Kopf (kicker/heading/text) und Alt-Texte sind Chat-Pflege,
|
||||||
|
// die Bilder schreibt dieser Lauf aus <ordner>/galerie/ (siehe unten).
|
||||||
|
$oldGalerie = is_array($oldIssue['galerie'] ?? null) ? $oldIssue['galerie'] : null;
|
||||||
$oldGegnerTeams = is_array($oldIssue['gegner_teams'] ?? null) ? array_values($oldIssue['gegner_teams']) : null;
|
$oldGegnerTeams = is_array($oldIssue['gegner_teams'] ?? null) ? array_values($oldIssue['gegner_teams']) : null;
|
||||||
$veranstaltung = null;
|
$veranstaltung = null;
|
||||||
if (is_string($oldVeranstaltung) && $oldVeranstaltung !== '') {
|
if (is_string($oldVeranstaltung) && $oldVeranstaltung !== '') {
|
||||||
@@ -317,6 +324,61 @@ $bild = static function (string $src, string $name, string $alt) use ($destDir,
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --- Galerie (optional): Fotos vom letzten Spiel als Bento-Seite. Wie bei den
|
||||||
|
// Veranstaltungsbildern ist der Ordner immer der KOMPLETTE Bestand (der
|
||||||
|
// Ausgaben-Ordner wurde oben geleert), Alt-Texte hängen an `source`, dem
|
||||||
|
// Originaldateinamen, und folgen ihrem Bild auch bei neuer Reihenfolge. Zwei
|
||||||
|
// Breiten reichen: der Aufmacher steht mit gut zwei Dritteln der Seitenbreite. ---
|
||||||
|
$galerieMax = 7;
|
||||||
|
$galerie = $oldGalerie;
|
||||||
|
if ($galerieQuellen !== []) {
|
||||||
|
$altBySource = [];
|
||||||
|
foreach ($oldGalerie['bilder'] ?? [] as $b) {
|
||||||
|
if (is_array($b) && !empty($b['source'])) {
|
||||||
|
$altBySource[(string) $b['source']] = (string) ($b['alt'] ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$platzhalter = trim((string) ($oldGalerie['heading'] ?? '')) ?: 'Fotos vom letzten Spiel';
|
||||||
|
if (count($galerieQuellen) > $galerieMax) {
|
||||||
|
$log(sprintf('galerie/ enthält %d Fotos, das Raster fasst %d — die übrigen bleiben weg.', count($galerieQuellen), $galerieMax), 'WARN');
|
||||||
|
}
|
||||||
|
$galerieBilder = [];
|
||||||
|
$ohneAlt = [];
|
||||||
|
foreach (array_slice($galerieQuellen, 0, $galerieMax) as $n => $src) {
|
||||||
|
$source = basename($src);
|
||||||
|
$name = sprintf('galerie-%02d', $n + 1);
|
||||||
|
try {
|
||||||
|
$variants = resize_image_variants($src, "{$destDir}/{$name}", [640, 1200], 80);
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
$fail("Galerie-Foto {$source} fehlgeschlagen: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
$generated = array_values(array_unique(array_column($variants, 'width')));
|
||||||
|
sort($generated);
|
||||||
|
$alt = trim($altBySource[$source] ?? '');
|
||||||
|
if ($alt === '' || $alt === $platzhalter) {
|
||||||
|
$ohneAlt[] = $source;
|
||||||
|
$alt = $platzhalter;
|
||||||
|
}
|
||||||
|
$galerieBilder[] = [
|
||||||
|
'source' => $source,
|
||||||
|
'base' => "img/stadionzeitung/{$slug}/{$name}",
|
||||||
|
'widths' => $generated,
|
||||||
|
'alt' => $alt,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$galerie = ($oldGalerie ?? []) + ['kicker' => 'Rückblick', 'heading' => $platzhalter];
|
||||||
|
$galerie['bilder'] = $galerieBilder;
|
||||||
|
$log(count($galerieBilder) . ' Galerie-Fotos übernommen.');
|
||||||
|
if ($ohneAlt !== []) {
|
||||||
|
$log('Galerie: noch ohne eigenen Alt-Text (im Chat ergänzen): ' . implode(', ', $ohneAlt), 'WARN');
|
||||||
|
}
|
||||||
|
} elseif (!empty($oldGalerie['bilder'])) {
|
||||||
|
// Die Dateien sind mit dem Ausgaben-Ordner weg; ohne galerie/ im Ordner
|
||||||
|
// lieferte die Seite sonst kaputte Bilder.
|
||||||
|
$log('Die Ausgabe hatte eine Galerie, der Ordner liefert aber kein galerie/ mehr — die Galerie-Seite entfällt.', 'WARN');
|
||||||
|
$galerie['bilder'] = [];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inhalt als Liste von BLÖCKEN, Anzeigen kommen anschließend in die Lücken
|
* Inhalt als Liste von BLÖCKEN, Anzeigen kommen anschließend in die Lücken
|
||||||
* dazwischen. Ein Block ist eine Folge von Seiten, die zusammenbleiben MUSS;
|
* dazwischen. Ein Block ist eine Folge von Seiten, die zusammenbleiben MUSS;
|
||||||
@@ -375,6 +437,12 @@ try {
|
|||||||
|
|
||||||
$bloecke[] = ['name' => 'ergebnisse', 'seiten' => [$live('ergebnisse')], 'anzeigen_danach' => true];
|
$bloecke[] = ['name' => 'ergebnisse', 'seiten' => [$live('ergebnisse')], 'anzeigen_danach' => true];
|
||||||
|
|
||||||
|
// Galerie direkt hinter dem Ergebnis-Rückblick: erst das Ergebnis, dann die
|
||||||
|
// Bilder dazu. Eigener Block, eine Anzeige dazwischen ist unbedenklich.
|
||||||
|
if (!empty($galerie['bilder'])) {
|
||||||
|
$bloecke[] = ['name' => 'galerie', 'seiten' => [$live('galerie')], 'anzeigen_danach' => true];
|
||||||
|
}
|
||||||
|
|
||||||
// Gegnerseite(n): normal nur die tragende Mannschaft; in der Sportfest-Ausgabe
|
// Gegnerseite(n): normal nur die tragende Mannschaft; in der Sportfest-Ausgabe
|
||||||
// je Mannschaft mit Heimspiel am Fest eine (drei Heimspiele, drei Seiten), als
|
// je Mannschaft mit Heimspiel am Fest eine (drei Heimspiele, drei Seiten), als
|
||||||
// EIN Block. Welche das sind, entscheidet stadionzeitung_gegner_fixtures() —
|
// EIN Block. Welche das sind, entscheidet stadionzeitung_gegner_fixtures() —
|
||||||
@@ -761,6 +829,7 @@ $issues[] = [
|
|||||||
'aufruf' => $oldAufruf,
|
'aufruf' => $oldAufruf,
|
||||||
'veranstaltung' => $oldVeranstaltung,
|
'veranstaltung' => $oldVeranstaltung,
|
||||||
'cover' => $oldCover,
|
'cover' => $oldCover,
|
||||||
|
'galerie' => $galerie,
|
||||||
'verfasser_photo' => $verfasserPhoto,
|
'verfasser_photo' => $verfasserPhoto,
|
||||||
'termine_snapshot' => $termineSnapshot,
|
'termine_snapshot' => $termineSnapshot,
|
||||||
'images' => $images,
|
'images' => $images,
|
||||||
|
|||||||
@@ -8628,6 +8628,83 @@ p.stadionzeitung-turnier__label:first-of-type {
|
|||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* === stadionzeitung-galerie (Live-Seite, optional: Fotos vom letzten Spiel) === */
|
||||||
|
/* Bento-Raster auf einem 6×4-Gitter: das erste Foto ist der Aufmacher (4×2),
|
||||||
|
die übrigen legen sich je nach Anzahl darum. Die Fläche unter dem Kopf gehört
|
||||||
|
komplett den Fotos, beschnitten wird per object-fit — wie bei den Momenten
|
||||||
|
ohne Bildunterschriften, der Alt-Text trägt die Beschreibung.
|
||||||
|
Das Raster wächst per flex in die feste A5-Höhe; min-height ist der Halt für
|
||||||
|
den gestapelten Viewer ohne JS, wo die Seite keine feste Höhe hat (dann
|
||||||
|
kollabierten die 1fr-Zeilen auf null). 95cqi passt unter jeden Kopf mit
|
||||||
|
Textzeile (gemessen gegen 141,9cqi Blatthöhe). */
|
||||||
|
.stadionzeitung-galerie {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie .stadionzeitung-page__head {
|
||||||
|
margin-bottom: 2.5cqi;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__text {
|
||||||
|
font-size: 3.4cqi;
|
||||||
|
color: var(--clr-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 95cqi;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(6, 1fr);
|
||||||
|
grid-template-rows: repeat(4, 1fr);
|
||||||
|
gap: 1.5cqi;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__foto {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(1) { grid-area: a; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(2) { grid-area: b; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(3) { grid-area: c; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(4) { grid-area: d; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(5) { grid-area: e; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(6) { grid-area: f; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(7) { grid-area: g; }
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n1 {
|
||||||
|
grid-template-areas: "a a a a a a" "a a a a a a" "a a a a a a" "a a a a a a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n2 {
|
||||||
|
grid-template-areas: "a a a a a a" "a a a a a a" "b b b b b b" "b b b b b b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n3 {
|
||||||
|
grid-template-areas: "a a a a a a" "a a a a a a" "b b b c c c" "b b b c c c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n4 {
|
||||||
|
grid-template-areas: "a a a a b b" "a a a a b b" "c c c d d d" "c c c d d d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n5 {
|
||||||
|
grid-template-areas: "a a a a b b" "a a a a c c" "d d d e e e" "d d d e e e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n6 {
|
||||||
|
grid-template-areas: "a a a a b b" "a a a a c c" "d d e e f f" "d d e e f f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n7 {
|
||||||
|
grid-template-areas: "a a a a b b" "a a a a c c" "d d e e f f" "d d e e g g";
|
||||||
|
}
|
||||||
|
|
||||||
/* === stadionzeitung-druck (Druckfassung, Broschüren-Montage) === */
|
/* === stadionzeitung-druck (Druckfassung, Broschüren-Montage) === */
|
||||||
/* Bildschirm-Ansicht der Route ?druck=1: jedes Blatt als A4-quer-Vorschau
|
/* Bildschirm-Ansicht der Route ?druck=1: jedes Blatt als A4-quer-Vorschau
|
||||||
(297:210) mit zwei A5-Seiten, in Broschüren-Reihenfolge (die Montage
|
(297:210) mit zwei A5-Seiten, in Broschüren-Reihenfolge (die Montage
|
||||||
|
|||||||
Reference in New Issue
Block a user