News: redaktionell eingefuegtes FAQPage-JSON als echtes Schema ausgeben
17 SEO-Artikel tragen ein rohes FAQPage-JSON-Objekt in einem abschliessenden Absatz ihres Bodytexts - das Frontend renderte es als sichtbaren Text, Google sah es nie als strukturierte Daten. Neue Klasse Seo\EmbeddedJsonLd trennt solche schema.org-Bloecke aus dem RTE-HTML (fail-safe: was nicht sauber dekodiert, bleibt stehen): - NewsJsonRenderer: Detail-bodytext und Listen-Exzerpt ohne die Bloecke - PageJsonLdRenderer: die dekodierten Nodes wandern in den @graph der Seite (FAQPage landet damit als <script type=application/ld+json> im Head, den das Frontend bereits injiziert) - VitecMetaHandler: Description-Fallback aus dem Bodytext ohne JSON-Muell Verifiziert an 3 Artikeln: @graph mit NewsArticle + FAQPage (8-9 Fragen), kein FAQPage-Rest im Textkoerper, kein sichtbarer JSON-Absatz im HTML. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c9b00e6f10
commit
5c640d02f7
4 files changed
+71
-2
No files matched your search
@@ -375,9 +375,12 @@ final class NewsJsonRenderer
|
||||
// SSR HTML to 2.8 MB). Cards render from `teaser`; only records
|
||||
// WITHOUT a teaser get a plain-text excerpt in `bodytext` so no
|
||||
// card goes blank. The detail mode is unchanged.
|
||||
// Editor-pasted schema.org blocks (FAQPage JSON in a trailing
|
||||
// paragraph) are split out of the body - they reach Google via
|
||||
// the page-level jsonLd @graph instead (PageJsonLdRenderer).
|
||||
'bodytext' => $mode === 'list'
|
||||
? (trim((string)($news['teaser'] ?? '')) !== '' ? '' : $this->listExcerpt((string)($news['bodytext'] ?? '')))
|
||||
: RteResolver::html($news['bodytext'] ?? ''),
|
||||
: \Evomedien\Vitec\Seo\EmbeddedJsonLd::extract(RteResolver::html($news['bodytext'] ?? ''))['html'],
|
||||
'datetime' => (int)($news['datetime'] ?? 0),
|
||||
'archive' => (int)($news['archive'] ?? 0),
|
||||
'istopnews' => (bool)($news['istopnews'] ?? false),
|
||||
@@ -579,6 +582,7 @@ final class NewsJsonRenderer
|
||||
*/
|
||||
private function listExcerpt(string $html): string
|
||||
{
|
||||
$html = \Evomedien\Vitec\Seo\EmbeddedJsonLd::extract($html)['html'];
|
||||
$text = trim((string)preg_replace('/\s+/u', ' ', strip_tags($html)));
|
||||
if (mb_strlen($text) <= 300) {
|
||||
return $text;
|
||||
|
||||
Reference in new issue
Block a user