JSON-LD w Drupalu: jak generować dane strukturalne z pól za pomocą Schema.org Metatag
Najbezpieczniejszym sposobem dodania JSON-LD do Drupala jest mapowanie właściwości Schema.org na istniejące pola treści. Skonfiguruj mapowanie raz na content type w Metatag i Schema.org Metatag. Redaktorzy aktualizują produkt, artykuł lub usługę jak dotychczas, a Drupal generuje JSON-LD z tych samych wartości, które widać na stronie.
JSON-LD w Drupalu działa najlepiej wtedy, gdy dane strukturalne są generowane z tego samego modelu danych, który zasila widoczną treść strony. Ten wzorzec eliminuje drugą, ukrytą kopię cen, nazw i dostępności. Zapewnia również zespołowi deweloperskiemu konfigurację, którą można eksportować, przeglądać i testować. Przeczytaj też: Schema.org i metadane w Drupalu - szerszy kontekst, zanim zmapujesz poszczególne bundle w Schema.org Metatag.
To znacznie lepsze rozwiązanie niż wymaganie od redaktorów utrzymywania drugiej, ukrytej kopii tych samych danych. Konfiguracja jest prosta. Trudniejsza jest decyzja, które pola są autorytatywne, obsługa pustych wartości i zabezpieczenie przed wejściem nowego content type do produkcji bez mapowania. SEO techniczne też wymaga markupu zgodnego z tym, co widzi użytkownik, a nie tylko składni, która przechodzi walidator.
W tym artykule:
- Dlaczego ręcznie pisany JSON-LD rozjeżdża się z treścią strony?
- Które submoduły Schema.org Metatag warto włączyć?
- Jak skonfigurować domyślne ustawienia Metatag przed mapowaniem właściwości?
- Jak zmapować pola Drupal na JSON-LD Product?
- Jak wyeksportować mapowanie Schema.org Metatag jako config Drupal?
- Co się dzieje, gdy pola ceny w JSON-LD są puste?
- Jak utrzymać wielojęzyczny JSON-LD zgodny z każdą przetłumaczoną stroną?
- Jak walidować JSON-LD na wyrenderowanych stronach Drupal?
- Jak testować pokrycie Schema.org w CI?
- Jak zbudować kolejkę redakcyjną do przeglądu structured data?
- Jak włączyć mapowanie JSON-LD do workflow content type?
Dlaczego ręcznie pisany JSON-LD rozjeżdża się z treścią strony?
Załóżmy, że strona produktu pokazuje cenę EUR 249. Szablon czyta tę wartość z field_price, ale ktoś wpisał tę samą liczbę ręcznie w bloku JSON-LD.
Zespół handlowy zmienia cenę na EUR 269. Widoczna strona się aktualizuje. Ukryty markup nie.
Strona podaje wtedy dwie informacje o tym samym produkcie. Walidacja składni może nadal przejść, bo obie wartości to poprawne liczby. Problemem jest niespójność danych.
Wytyczne Google dotyczące structured data mówią, że markup powinien opisywać treść widoczną dla czytelnika. Nazwa produktu, cena lub dostępność w JSON-LD powinny więc pochodzić z tego samego źródła co wartość na stronie. Ta sama zasada dotyczy sytuacji, gdy tekst w obrazach ukrywa fakty przed wyszukiwarką i fetcherami AI - jeśli fakt nie jest w HTML, structured data nie zastąpi go wiarygodnie.
Drupal udostępnia już takie źródło prawdy: pola treści.
Schema.org Metatag rozszerza moduł Metatag. Definiuje grupy dla typów takich jak Article, Product, Service, Organization i WebSite, a następnie renderuje skonfigurowane właściwości jako skrypt application/ld+json w head strony. Tokeny łączą te właściwości z polami encji.
Jedna zmiana aktualizuje zarówno zawartość strony, jak i dane strukturalne.
Które submoduły Schema.org Metatag warto włączyć?
Schema.org Metatag 3.0.4 obsługuje Drupal 9, 10 i 11. Moduł bazowy wymaga Metatag i PHP 8 lub nowszego. Zainstaluj pakiet przez Composer:
composer require 'drupal/schema_metatag:^3.0'Włącz moduł bazowy i submoduły pasujące do stron, które będziesz oznaczać. Dla katalogu produktów:
drush en schema_metatag schema_product schema_organization schema_web_site -y
drush crNie włączaj wszystkich submodułów automatycznie. Każdy dodaje kolejną grupę ustawień i typ, który zespół może poczuć się zobowiązany skonfigurować. Zacznij od stron z użytecznymi, utrzymywanymi danymi.
Sensowny pierwszy krok:
schema_web_siteischema_organizationdla tożsamości całego serwisu,schema_articledla artykułów i newsów,schema_productdla prawdziwych stron produktowych,schema_servicedla stron usług, gdy właściwości opisują widoczną treść,- wsparcie breadcrumb modułu tam, gdzie serwis już renderuje okruszki.
Schema.org zawiera znacznie więcej typów, niż udostępnia moduł. Google obsługuje rich results dla mniejszego zbioru niż definiuje Schema.org. Wybieraj typ, ponieważ faktycznie opisuje daną stronę i ma praktyczne zastosowanie, a nie tylko dlatego, że znajduje się na liście dostępnych opcji.
Jak skonfigurować domyślne ustawienia Metatag przed mapowaniem właściwości?
Przejdź do:
Configuration → Search and metadata → Metatag
Ścieżka:
/admin/config/search/metatag
Metatag łączy wartości przez hierarchię:
- Global defaults obowiązują w całym serwisie.
- Entity defaults dotyczą typu encji, np. Content.
- Bundle defaults nadpisują je dla content type, np. Product.
- Entity-level values mogą nadpisać domyślne ustawienia, gdy do rekordu dołączono pole Metatag.
Większość konfiguracji powinna znajdować się na poziomie bundle. Content type Product potrzebuje jednego sprawdzonego mapowania, które dziedziczą wszystkie node produktowe.
Unikaj konfigurowania Schema.org na poziomie pojedynczej encji, chyba że dana strona stanowi rzeczywisty wyjątek. Wymaga od redaktorów utrzymywania metadanych technicznych, których nie widać w normalnym układzie strony. Sprawia też, że dwa produkty tego samego content type zachowują się inaczej.
Global defaults pasują do tożsamości, która nie zmienia się między stronami, np. organizacji wydawcy. Bundle defaults pasują do właściwości powiązanych z polami, np. nazwy produktu, SKU i opisu. Ta sama zasada działa, gdy uczysz redaktorów pracy w komponentach zamiast jednego długiego pola body - jedno autorytatywne źródło, wiele wyjść.
Jak zmapować pola Drupal na JSON-LD Product?
Załóżmy, że content type Drupal zawiera te pola:
| Źródło Drupal | Typ pola | Zastosowanie widoczne |
|---|---|---|
| Node title | Core title | nagłówek produktu |
field_summary | Plain text, long | wprowadzenie |
field_sku | Plain text | tabela specyfikacji |
field_brand | Entity reference | szczegóły produktu |
field_image | Referencja media lub obrazu | zdjęcie produktu |
field_price | Decimal | blok oferty |
field_currency | List | blok oferty |
field_availability | List | status magazynowy |
| Canonical URL | Wygenerowany URL | tożsamość strony |
Mapowanie Schema.org powinno czytać te same wartości:
| Właściwość Schema.org | Źródło Drupal | Typowy token lub ustawienie |
|---|---|---|
Product @type | stała konfiguracja | Product |
Product @id | URL kanoniczny plus fragment | [node:url:absolute]#product |
Product name | tytuł node | [node:title] |
Product description | pole summary | [node:field_summary] |
Product url | URL kanoniczny | [node:url:absolute] |
Product sku | pole SKU | [node:field_sku] |
Product brand.name | nazwa referencjonowanej marki | token dla etykiety field_brand |
Product image | pole obrazu lub media | token absolutnego URL obrazu |
Offer price | pole ceny decimal | token surowej wartości field_price |
Offer priceCurrency | wartość listy walut | token zapisanej wartości field_currency |
Offer availability | wartość listy dostępności | pełny URL statusu Schema.org |
Ścieżki tokenów dla referencjonowanych encji i mediów zależą od struktury pól i włączonych providerów tokenów. Użyj Browse available tokens w formularzu Metatag i sprawdź wynik na prawdziwej stronie. Nie kopiuj tokena media z innego projektu, zakładając identyczną relację.
Podstawowa zasada mapowania pozostaje niezmienna:
- nazwy pochodzą z pól nazw,
- identyfikatory z pól identyfikatorów,
- liczby z pól numerycznych,
- kontrolowane statusy ze zapisanych wartości maszynowych,
- adresy URL powinny prowadzić do publicznie dostępnych adresów absolutnych,
- zagnieżdżone obiekty takie jak Offer i Brand zachowują własne
@type.
JSON-LD oparty na polach wspiera też wzorce redakcyjne takie jak answer-first writing dla wyszukiwania AI, gdzie widoczna treść i metadane muszą opisywać te same fakty.
Skonfiguruj domyślne ustawienia Product
W /admin/config/search/metatag dodaj lub edytuj domyślne ustawienia dla content type Product. Otwórz sekcję Schema.org: Product i ustaw:
@typenaProduct,namena token tytułu node,descriptionna token summary,urlna absolutny URL node,skuna pole SKU,imagena publiczny URL obrazu,brandjako obiekt Brand,offersjako obiekt Offer wypełniony polami ceny.
Formularz modułu reprezentuje złożone właściwości jako zagnieżdżone pola. Używaj tych kontrolek zamiast składać ciąg JSON w polu tekstowym.
Zapisz domyślne ustawienia, wyczyść cache i otwórz opublikowaną stronę produktu. W head powinien być jeden skrypt JSON-LD z obiektem Product w @graph.
Wynik powinien mieć taki kształt:
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Product",
"@id": "https://www.example.com/products/aqua-4500#product",
"name": "Aqua 4500",
"description": "A submersible pump for continuous industrial use.",
"url": "https://www.example.com/products/aqua-4500",
"sku": "AQ-4500",
"brand": {
"@type": "Brand",
"name": "AquaWorks"
},
"offers": {
"@type": "Offer",
"price": "269.00",
"priceCurrency": "EUR",
"availability": "https://schema.org/InStock"
}
}
]
}To przykład, a nie blok do wklejenia w Drupal. Twoje mapowanie powinno go generować z encji produktu.
Jak wyeksportować mapowanie Schema.org Metatag jako config Drupal?
Gdy wynik wygenerowany na stronie jest poprawny, wyeksportuj konfigurację Drupala:
drush cex -y
git diff -- config/syncDomyślne ustawienia bundle są zapisane jako encje konfiguracji Metatag default. Mapowanie Product zwykle trafia do pliku:
metatag.metatag_defaults.node__product.yml
Prosta część wyeksportowanego pliku ma taki kształt:
id: node__product
label: 'Content: Product'
tags:
schema_product_type: Product
schema_product_name: '[node:title]'
schema_product_description: '[node:field_summary]'
schema_product_id: '[node:url:absolute]#product'
schema_product_url: '[node:url:absolute]'
schema_product_sku: '[node:field_sku]'Złożone wartości takie jak Offer moduł serializuje, więc w surowym YAML trudniej je ocenić. Skonfiguruj je w UI, wyeksportuj i commituj wynik. Nie edytuj ręcznie wartości serializowanej, jeśli nie testujesz też wyrenderowanej strony.
Eksport konfiguracji ma znaczenie, bo mapowanie to zachowanie aplikacji. Powinno przejść code review i deployment razem z content type i polami, od których zależy.
Co się dzieje, gdy pola ceny w JSON-LD są puste?
Mapowanie cen bardzo szybko ujawnia problemy w modelu danych.
Cena powinna pochodzić z pola decimal, a nie ze sformatowanego zdania typu „Od 269 €”. Waluta powinna mieć własną kontrolowaną wartość. Dostępność przechowuje wartość maszynową mapowaną na poprawny status Schema.org.
Zdecyduj, co się dzieje, gdy nie ma publicznej ceny. Nie emituj:
{
"@type": "Offer",
"price": "",
"priceCurrency": "EUR"
}Niekompletna Offer może być niepoprawna lub wprowadzać w błąd. Albo wymagaj pól dla produktów publikujących Offer, albo pomiń Offer, gdy firma nie publikuje ceny.
Tu proste mapowanie tokenów może wymagać małego modułu custom. Implementacja hook_metatags_alter() może usunąć zagnieżdżony obiekt, gdy wymagane pola źródłowe są puste. Trzymaj regułę blisko modelu treści i pokryj ją testem.
Ta sama reguła dotyczy ocen, dat i identyfikatorów. Pusty token to nieużyteczne structured data. Fallback powinien mieć sens biznesowy, a nie tylko uciszać walidator.
Jak utrzymać wielojęzyczny JSON-LD zgodny z każdą przetłumaczoną stroną?
Tokeny rozwiązują się w kontekście renderowanej encji. Na przetłumaczonym URL przetłumaczony tytuł i opis powinny zasilać markup dla tego języka.
Sprawdź to na stronach zbliżonych do produkcji. Referencjonowane encje, metadane mediów i tokeny custom nie zawsze podążają za tłumaczeniem tak jak główne pola node.
Przed rozpoczęciem konfiguracji podziel właściwości na następujące grupy:
- Tłumaczalne: nazwa, opis i etykiety skierowane do odbiorcy.
- Zwykle wspólne: SKU, GTIN i identyfikatory techniczne.
- Specyficzne dla rynku: cena, waluta, dostępność i obsługiwany region.
- Całego serwisu: tożsamość wydawcy i oficjalne profile.
Francuska strona produktu nie powinna emitować angielskiego opisu, bo francuskie tłumaczenie jest puste. Zdecyduj, czy publikacja ma być zablokowana, właściwość pominięta, czy udokumentowany język zapasowy też pojawia się widocznie na stronie.
Testuj każdy URL językowy osobno. Przejście walidacji po angielsku nic nie mówi o niemieckiej cenie ani francuskich metadanych obrazu.
Jak walidować JSON-LD na wyrenderowanych stronach Drupal?
Zapis tokena w Drupalu nie dowodzi, że wynikowy JSON-LD jest poprawny. Walidatory pomagają tylko wtedy, gdy markup na live stronie odpowiada polom, które utrzymują redaktorzy.
Warto stosować walidację na trzech poziomach.
1. Parsuj wyjście
Otwórz źródło strony i znajdź:
<script type="application/ld+json">Potwierdź, że blok to poprawny JSON, że oczekiwany typ istnieje i że tylko jeden moduł posiada każdą encję. Zduplikowane obiekty Product z Schema.org Metatag i szablonu motywu mogą się różnić bez błędu składni.
2. Sprawdź słownik
Użyj walidatora Schema.org, aby sprawdzić typy i właściwości Schema.org.
To łapie błędne zagnieżdżanie, literówki we właściwościach i niepoprawne wartości. Nie dowodzi, że Google używa typu jako rich result. Dla kontroli SEO na poziomie CMS poza markupiem zobacz 10 funkcji SEO, które powinien mieć nowoczesny system CMS oraz najważniejsze poprawki po audycie SEO Drupal.
3. Sprawdź docelową funkcję Google
Użyj Rich Results Test Google dla typów obsługiwanych przez Google Search. Następnie sprawdź dokumentację danej funkcji pod kątem wymaganych właściwości.
Poprawny markup Schema.org i kwalifikacja do rich results to różne testy. Poprawny obiekt Service może dobrze opisywać stronę, nawet gdy Google nie udostępnia rich result dla Service.
Po kontrolach technicznych porównaj wynik z widoczną treścią. Walidatory nie ocenią, czy EUR 269 w markupie koliduje z EUR 249 w bloku oferty. Czy AI naprawdę może odczytać Twoją stronę internetową? pokazuje, dlaczego pobieralny HTML i zgodne fakty mają znaczenie poza klasycznymi rich results.
Jak testować pokrycie Schema.org w CI?
Zespół może poprawnie skonfigurować każdy istniejący content type i i tak stracić pokrycie pół roku później. Ktoś doda wariant Product lub bundle Resource bez domyślnych ustawień Metatag.
Najprostszy test CI sprawdza, czy wybrane publiczne bundle mają oczekiwaną grupę schema w wyeksportowanej konfiguracji.
<?php
declare(strict_types=1);
namespace Drupal\Tests\site_schema\Unit;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Yaml\Yaml;
final class SchemaDefaultsConfigTest extends TestCase {
public function testPublicBundlesHaveSchemaDefaults(): void {
$required = [
'article' => ['schema_article_type', 'Article'],
'product' => ['schema_product_type', 'Product'],
'service' => ['schema_service_type', 'Service'],
];
$configDirectory = dirname(DRUPAL_ROOT) . '/config/sync';
foreach ($required as $bundle => [$tag, $expectedType]) {
$path = sprintf(
'%s/metatag.metatag_defaults.node__%s.yml',
$configDirectory,
$bundle,
);
self::assertFileExists(
$path,
sprintf('The %s bundle has no Metatag defaults.', $bundle),
);
$config = Yaml::parseFile($path);
self::assertSame(
$expectedType,
$config['tags'][$tag] ?? null,
sprintf('The %s bundle has no %s mapping.', $bundle, $tag),
);
}
}
}Dostosuj katalog konfiguracji i listę bundle do projektu. Uruchom test w tym samym jobie PHPUnit, który sprawdza custom kod Drupal.
Taki test wykryje brak mapowania, ale nie wychwyci nieprawidłowo skonfigurowanego tokena ceny.
Dodaj jeden test funkcjonalny na wartościowy szablon. Utwórz lub załaduj reprezentatywny produkt, pobierz publiczny URL, zdekoduj skrypt application/ld+json i sprawdź krytyczne wartości biznesowe:
@typerównyProduct,namerówny tytułowi node,skurównyfield_sku,offers.pricerówny surowemu polu ceny,offers.priceCurrencyrówny zapisanej walucie,- widoczna cena równa wygenerowanej cenie.
Moduł Schema.org Metatag stosuje ten sam sposób we własnych testach funkcjonalnych: załaduj wyrenderowaną stronę, znajdź skrypt JSON-LD, zdekoduj i porównaj wyjście. Dlaczego Drupal sprawdza się w strukturalnych operacjach contentowych na dużą skalę pokazuje, jak konfiguracja, pola i governance utrzymują te kontrole użyteczne, gdy serwis rośnie.
Jak zbudować kolejkę redakcyjną do przeglądu structured data?
Domyślne ustawienia bundle powinny obejmować wszystkie typowe strony. Przegląd przez człowieka powinien skupiać się na brakujących lub wyjątkowych danych źródłowych.
Utwórz administracyjny View dla treści Product z kolumnami:
- tytuł,
- status publikacji,
- SKU,
- cena,
- waluta,
- dostępność,
- obraz,
- status tłumaczenia,
- data ostatniej zmiany,
- flaga „Schema review required”.
Dodaj exposed filtry dla pustych pól wymaganych i flagi przeglądu. Nadaj View jasną nazwę, np. Structured data review queue.
Flaga boolean jest przydatna, gdy rekord nie może podążać za mapowaniem bundle, np. produkt z kilkoma niezależnymi ofertami albo strona reprezentująca rodzinę produktów zamiast jednej SKU. Taki rekord wymaga decyzji dotyczącej modelu danych, a nie ręcznego wpisywania JSON-LD w polu tekstowym.
Jeśli redaktorzy mogą ustawiać nadpisania Metatag na poziomie encji, uwzględnij te rekordy w osobnym audycie. Nadpisania to wyjątki i powinny pozostać rzadkie. Gdy specyfikacje muszą wspierać też badania zakupowe wspomagane przez AI, rekomendacja AI dla dostawców: fakty do shortlisty wyjaśnia, dlaczego opublikowane wartości pól mają znaczenie poza snippetami wyszukiwania.
Jak włączyć mapowanie JSON-LD do workflow content type?
Dodanie nowego publicznego content type wpływa na znacznie więcej elementów niż sam formularz edycji. Użyj krótkiej checklisty definition of done:
- Wybierz główny typ Schema.org strony.
- Wskaż pola, które dostarczają użytecznych właściwości.
- Skonfiguruj domyślne ustawienia bundle z tokenami.
- Wyeksportuj i przejrzyj konfigurację.
- Przetestuj jeden kompletny rekord i jeden z brakującymi polami opcjonalnymi.
- Przetestuj każdy opublikowany język.
- Dodaj bundle do testu pokrycia konfiguracji.
- Dodaj wymagane pola źródłowe do View przeglądu redakcyjnego.
- Potwierdź, że motyw lub inny moduł nie generuje zduplikowanej encji.
Przeprowadź ponowny przegląd za każdym razem, gdy pole zmieni nazwę, typ lub właściciela biznesowego. Mapowanie może nadal istnieć, wskazując token, który już nic nie zwraca.
Potrzebujesz mapowań JSON-LD zgodnych z treścią w Drupalu?
Wdrażamy konfigurację Schema.org Metatag, mapowania pole-do-tokena i automatyczne kontrole na platformach Drupal, gdzie strony produktowe, artykuły i treść wielojęzyczna muszą pozostać zgodne między widoczną treścią a markupiem structured data. Ten sam wzorzec wspiera serwisy B2B publikujące ustrukturyzowane specyfikacje pod research kupujących i shortlisty wspomagane AI.
Jeśli Twój serwis Drupal potrzebuje utrzymywanego JSON-LD z pól treści zamiast ręcznie pisanych bloków, nasz zespół może skonfigurować domyślne ustawienia bundle, wyeksportować je jako kod i połączyć walidację z workflow redakcyjnym. Odwiedź stronę usługi Drupal, aby zobaczyć, jak budujemy i utrzymujemy platformy Drupal dla organizacji z dużą objętością treści.