Cuando trabajamos con SEO Offpage y estructuración avanzada de datos JSON-LD en Drupal, a veces necesitamos añadir propiedades Schema.org que no existen por defecto en los módulos Metatag y Schema Metatag. (Es necesario tener instalados estos 2 módulos para hacer lo que voy a comentar a continuación).
Como alternativa podemos extender ambos módulos desde un módulo custom creando nuestros propios plugins. Este proceso permite que Drupal reconozca nuevas propiedades Schema.org, las muestre en la UI de Metatag y las genere correctamente dentro del JSON-LD.
1. Crear el Tag del Metatag
Dentro de cualquier módulo custom de tu Drupal (que no interfiera con la funcionalidad del propio módulo), añade un archivo en:
src/Plugin/Metatag/Tag/NombredelCampo.phpEste plugin define el campo a nivel del módulo Metatag y utiliza una clase base para definir el comportamiento del mismo (por ejemplo SchemaNameBase para propiedades simples como string, número, URL, boolean). La clase base también tiene la funcionalidad de integrarse con Schema Metatag.
Ejemplo:
<?php
namespace Drupal\mi_modulo\Plugin\Metatag\Tag;
use Drupal\schema_metatag\Plugin\Metatag\Tag\SchemaNameBase;
/**
* Schema.org Action property: recipient.
*
* @MetatagTag(
* id = "schema_action_recipient",
* label = @Translation("Recipient"),
* description = @Translation("The participant who receives the action."),
* name = "recipient",
* group = "schema_organization",
* type = "string",
* multiple = FALSE,
* property_type = "recipient",
* weight = 20
* )
*/
class SchemaActionRecipient extends SchemaNameBase {
}
2. Detallando la funcionalidad del archivo
1. Namespace
namespace Drupal\mi_modulo\Plugin\Metatag\Tag;
Indica que este plugin pertenece al módulo mi_modulo y forma parte del sistema de plugins de Metatag, en el grupo Tag. Esto es obligatorio porque Metatag escanea este namespace para descubrir nuevos tags personalizados.
2. Clase base
use Drupal\schema_metatag\Plugin\Metatag\Tag\SchemaNameBase;
Importa la clase SchemaNameBase, utilizada para propiedades Schema.org simples. Esto le dice a Drupal: "Este campo es una propiedad Schema.org simple basada en un valor".
3. DocBlock introductorio
/** Schema.org Action property: recipient. */4. Anotación @MetatagTag
La anotación registra este plugin dentro del sistema de Metatag. Define cómo se va a comportar el campo, cómo se verá y cómo se conectará con Schema Metatag.
Voy campo por campo:
- id: Identificador único del plugin.
- label: Nombre visible en la interfaz de Metatag.
- description: Texto informativo en la UI.
- name: Nombre real de la propiedad Schema.org (clave del JSON-LD).
- group: Grupo donde aparecerá en la UI (ejemplo: schema_organization, schema_person, schema_action...).
- type: Tipo de campo en el formulario de Metatag (string, uri, integer…).
- multiple: Si permite varios valores (TRUE/FALSE).
- property_type: Conexión con Schema Metatag (Puedes crear uno nuevo o utilizar uno ya existente, lo veremos en el sigueinte punto).
- weight: Posición en la UI.
5. Clase del plugin
La clase no necesita añadir nada más porque toda la configuración está en la anotación.
¿Qué logras con este archivo?
- Metatag detecta este nuevo "Tag".
- Aparece un campo “Recipient” en la UI de Metatag.
- Puedes asignarle un valor por nodo, vista, taxonomía, etc.
- Schema Metatag lo procesa gracias al atributo property_type.
- El valor se incluye automáticamente en el JSON-LD final.
Ejemplo JSON-LD:
"recipient": "John Doe"
3. Crear el PropertyType de Schema Metatag
Este apartado es opcional si no necesitas crear un nuevo PropertyType, ya hay algunos existentes que te pueden servir.
Este archivo es la “otra mitad” necesaria para que la propiedad se genere correctamente en el JSON-LD. Mientras el Tag controla cómo aparece en la UI, el PropertyType indica a Schema Metatag qué tipo de propiedad Schema.org es y cómo debe ser tratada.
Ruta del archivo:
src/Plugin/schema_metatag/PropertyType/Recipient.phpEjemplo de PropertyType:
<?php
namespace Drupal\mi_modulo\Plugin\SchemaMetatag\PropertyType;
use Drupal\schema_metatag\Plugin\schema_metatag\PropertyTypeBase;
/**
* Schema.org property type: recipient.
*
* @SchemaPropertyType(
* id = "recipient",
* label = @Translation("Recipient"),
* tree_parent = {
* "Audience",
* "ContactPoint",
* "Organization",
* "Person",
* },
* tree_depth = 2,
* property_type = "thing",
* sub_properties = {
* "@type" = {
* "id" = "type",
* "label" = @Translation("@type"),
* "description" = @Translation("Defines the Schema.org type for the recipient."),
* },
* "name" = {
* "id" = "text",
* "label" = @Translation("Name"),
* "description" = @Translation("The name of the recipient entity."),
* },
* }
* )
*/
class Recipient extends PropertyTypeBase {
}¿Por qué es necesario un PropertyType?
- Define el tipo de propiedad Schema.org.
- Permite a Schema Metatag saber a qué entidades pertenece.
- Controla la estructura final del JSON-LD.
- Permite herencia de propiedades.
- Permite validación del tipo.
Si este archivo NO existe, el Tag aparecerá en la UI, pero NO se generará en el JSON-LD.
4. ¿Dónde editar este campo en la UI de Metatag?
Una vez creado y limpia la caché, podrás editarlo directamente en:
- /admin/config/search/metatag → Configuración global
- /admin/config/search/metatag/node__TU-CONTENIDO?destination=/admin/config/search/metatag → Configuración por tipo de contenido (En la pestaña Metatags dentro de cada nodo, pulsando en la pestaña Editar)
Una vez que hayas rellenado el nuevo campo en la UI del metatag (Punto 4) ya podrás verlo en tu esquema JSON-LD, pongo un ejemplo:
<script type="application/ld+json">{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"sameAs": [
"https://www.linkedin.com/company/web/",
"https://www.facebook.com/web",
"https://www.instagram.com/web/",
"https://bsky.app/profile/web.org",
"https://www.youtube.com/web"
],
"url": "https://www.web.org/en",
"name": "web",
"contactPoint": {
"@type": "ContactPoint",
"email": "info@web.org",
"contactType": "General"
},
"logo": {
"@type": "ImageObject",
"url": "https://www.web.org/en/themes/custom/web/brand.svg"
},
},
{
"@type": "WebSite",
"name": "web",
"url": "https://www.web.org/en",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://www.web.org/en/search?s={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
]
}</script>
Clases base alternativas a
SchemaNameBaseDependiendo del tipo de propiedad Schema.org que quieras crear, puedes usar:
- SchemaNameBase: valores simples (string, número, email).
- SchemaUriBase: URLs obligatorias.
- SchemaBooleanBase: valores TRUE/FALSE reales en JSON.
- SchemaIntegerBase: valores numéricos enteros.
- SchemaFloatBase: valores decimales.
- SchemaImageBase: propiedades tipo imagen.
- SchemaTypeBase: objetos Schema.org completos con subpropiedades.
Elegir la clase base correcta garantiza que el JSON-LD generado sea válido según Schema.org y Google Rich Results (Muy importante siempre comprobar los resultados generados con estas herramientas).