SEO-Schema-Helper: Breadcrumb, FAQPage, SportsTeam
breadcrumb_schema(), faq_schema(), page_schema() und team_schema() bauen JSON-LD-Knoten für $meta['schema']. team_schema verweist via #club auf den Organization-Knoten. Leere FAQ-Paare werden übersprungen. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
This commit is contained in:
@@ -143,3 +143,86 @@ function form_token_valid(string $token, int $min = 3, int $max = 7200): bool
|
||||
$age = time() - (int) $ts;
|
||||
return $age >= $min && $age <= $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* BreadcrumbList-Knoten: $items = [['name'=>…, 'slug'=>…], …] (Reihenfolge = Pfad).
|
||||
*/
|
||||
function breadcrumb_schema(array $items): array
|
||||
{
|
||||
$list = [];
|
||||
foreach (array_values($items) as $i => $item) {
|
||||
$list[] = [
|
||||
'@type' => 'ListItem',
|
||||
'position' => $i + 1,
|
||||
'name' => $item['name'],
|
||||
'item' => abs_url($item['slug']),
|
||||
];
|
||||
}
|
||||
return ['@type' => 'BreadcrumbList', 'itemListElement' => $list];
|
||||
}
|
||||
|
||||
/**
|
||||
* FAQPage-Knoten aus [['q'=>…, 'a'=>…], …]. Leere Paare werden übersprungen;
|
||||
* ohne Fragen wird ein leerer Array zurückgegeben (Aufrufer filtert das raus).
|
||||
*/
|
||||
function faq_schema(array $faq): array
|
||||
{
|
||||
$questions = [];
|
||||
foreach ($faq as $item) {
|
||||
if (empty($item['q']) || empty($item['a'])) {
|
||||
continue;
|
||||
}
|
||||
$questions[] = [
|
||||
'@type' => 'Question',
|
||||
'name' => $item['q'],
|
||||
'acceptedAnswer' => ['@type' => 'Answer', 'text' => $item['a']],
|
||||
];
|
||||
}
|
||||
return $questions === [] ? [] : ['@type' => 'FAQPage', 'mainEntity' => $questions];
|
||||
}
|
||||
|
||||
/**
|
||||
* Seiten-Schema-Knoten zusammenstellen (für $meta['schema']):
|
||||
* Breadcrumb + optional FAQPage. Generisch für Übersichts-/Jugendseiten.
|
||||
*/
|
||||
function page_schema(array $breadcrumb, array $faq = []): array
|
||||
{
|
||||
$nodes = [];
|
||||
if ($breadcrumb !== []) {
|
||||
$nodes[] = breadcrumb_schema($breadcrumb);
|
||||
}
|
||||
if ($faq !== [] && ($faqNode = faq_schema($faq)) !== []) {
|
||||
$nodes[] = $faqNode;
|
||||
}
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schema-Knoten für eine Mannschafts-Seite: SportsTeam (verweist auf den Club
|
||||
* via #club) + Breadcrump (Start → Fußball → Team) + optional FAQPage.
|
||||
* $team: Eintrag aus data/teams.json; $slug: voller Seiten-Slug.
|
||||
*/
|
||||
function team_schema(array $team, string $slug): array
|
||||
{
|
||||
$teamNode = [
|
||||
'@type' => 'SportsTeam',
|
||||
'name' => $team['name'],
|
||||
'sport' => 'Fußball',
|
||||
'url' => abs_url($slug),
|
||||
'memberOf' => ['@id' => abs_url() . '#club'],
|
||||
];
|
||||
if (!empty($team['hero']['text'])) {
|
||||
$teamNode['description'] = $team['hero']['text'];
|
||||
}
|
||||
|
||||
$nodes = [$teamNode];
|
||||
$nodes = array_merge($nodes, page_schema(
|
||||
[
|
||||
['name' => 'Startseite', 'slug' => ''],
|
||||
['name' => 'Fußball', 'slug' => 'fussball'],
|
||||
['name' => $team['name'], 'slug' => $slug],
|
||||
],
|
||||
$team['faq'] ?? []
|
||||
));
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user