SEO/GEO-Basics: Descriptions & Titles normalisiert, Outline-Fixes, CLS-Maße
Audit aller 23 indexierbaren Routen (lokaler Crawl) und Fixes: - Descriptions auf ~130-160 Zeichen; Turnen-Disziplinseiten hatten den kurzen Hero-Teaser als Description, jetzt eigene SERP-Texte - Titles: team-erste gekürzt, sportheimbuchung ohne doppelten Brand - h1->h3-Sprünge behoben: visually-hidden h2 aus JSON-Section-Titeln (sportheimbuchung, partner-werden), sichtbarer choice.title auf mitglied-werden; historie bekommt Breadcrumb-Schema - Neuer Helper img_intrinsic_attrs() liefert width/height aus der Bilddatei (PNG via getimagesize, SVG via viewBox) für Partner-Grid- und Banner-Slider-Logos — kein Layout-Shift mehr Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -96,6 +96,35 @@ function json_load(string $name): array
|
||||
return $cache[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Intrinsische Bildmaße als ' width="…" height="…"' für CLS-freie <img>-Tags.
|
||||
* $rel = Pfad relativ zu public/assets/. PNG/JPG via getimagesize, SVG via
|
||||
* viewBox (Fallback: width/height-Attribute, Einheiten werden ignoriert —
|
||||
* fürs Seitenverhältnis reicht die Zahl). Liefert '' wenn nicht bestimmbar.
|
||||
*/
|
||||
function img_intrinsic_attrs(string $rel): string
|
||||
{
|
||||
static $cache = [];
|
||||
if (!isset($cache[$rel])) {
|
||||
$file = PUBLIC_PATH . '/assets/' . ltrim($rel, '/');
|
||||
$w = $h = 0;
|
||||
if (is_file($file)) {
|
||||
if (str_ends_with(strtolower($file), '.svg')) {
|
||||
$svg = (string) file_get_contents($file);
|
||||
if (preg_match('/viewBox="\s*[\d.-]+[\s,]+[\d.-]+[\s,]+([\d.]+)[\s,]+([\d.]+)/', $svg, $m)) {
|
||||
[$w, $h] = [(int) round((float) $m[1]), (int) round((float) $m[2])];
|
||||
} elseif (preg_match('/<svg\b[^>]*\bwidth="([\d.]+)[a-z%]*"[^>]*\bheight="([\d.]+)[a-z%]*"/s', $svg, $m)) {
|
||||
[$w, $h] = [(int) round((float) $m[1]), (int) round((float) $m[2])];
|
||||
}
|
||||
} else {
|
||||
[$w, $h] = (getimagesize($file) ?: [0, 0]);
|
||||
}
|
||||
}
|
||||
$cache[$rel] = ($w > 0 && $h > 0) ? ' width="' . $w . '" height="' . $h . '"' : '';
|
||||
}
|
||||
return $cache[$rel];
|
||||
}
|
||||
|
||||
/**
|
||||
* Komponente rendern: component('hero', ['title' => …]).
|
||||
* Props werden als lokale Variablen extrahiert; Komponenten sind dumme Includes.
|
||||
|
||||
Reference in New Issue
Block a user