Saltar a contenido

Domain Config

El módulo Domain Config proporciona sobrescrituras de configuración por dominio. Permite que cada dominio tenga su propio nombre de sitio, configuración de tema, página de inicio por defecto o cualquier otra configuración — todo desde una única instalación de Drupal.

Este módulo solo cubre las sobrescrituras por dominio. Las sobrescrituras por idioma que se añaden encima (indexadas por la pareja (domain, langcode)) las proporciona el submódulo opcional Domain Config Language, donde se describen.

Arquitectura: 2.x vs 3.x

Domain Config 3.x es un rediseño completo de cómo se almacenan y resuelven las sobrescrituras de configuración por dominio. La versión 2.x utilizaba una solución interna personalizada, mientras que 3.x aprovecha la Config Collections API nativa de Drupal.

El enfoque 2.x (legacy)

En Domain 2.x, las sobrescrituras por dominio se almacenaban como objetos de configuración separados en la colección por defecto, usando una convención de nombres:

domain.config.{domain_id}.{config_name}

Por ejemplo, sobrescribir el nombre del sitio en one_example_com:

domain.config.one_example_com.system.site

Estos objetos vivían junto a toda la demás configuración en el almacenamiento por defecto. En tiempo de ejecución, un resolver personalizado interceptaba las cargas de configuración, detectaba el dominio activo, construía el nombre de la sobrescritura, intentaba cargarla y fusionaba el resultado sobre la configuración base.

Limitaciones de este enfoque:

  • Los objetos de configuración contaminaban el espacio de nombres de la colección por defecto.
  • El esquema de nombres era frágil — la expresión regular para extraer el ID de dominio y el nombre de configuración de una cadena plana era propensa a errores.
  • Sin integración con ConfigFactoryOverrideInterface de Drupal — el mecanismo de sobrescritura era completamente personalizado.
  • La exportación/importación de configuración no entendía estos elementos como sobrescrituras — aparecían como objetos de configuración regulares.
  • Los eventos de configuración (save, delete, rename) requerían propagación manual.

El enfoque 3.x (config collections)

Domain Config 3.x almacena las sobrescrituras en colecciones de configuración de Drupal — una funcionalidad nativa de Drupal diseñada exactamente para este propósito. Las colecciones son particiones virtuales del almacenamiento de configuración que comparten el mismo backend (sistema de archivos, base de datos, etc.) pero están lógicamente separadas.

Nomenclatura de colecciones:

Tipo Formato Ejemplo
Solo dominio domain.{domain_id} domain.one_example_com

Dentro de una colección, el objeto de configuración conserva su nombre original. Por ejemplo, la sobrescritura del nombre del sitio para one_example_com se almacena como system.site dentro de la colección domain.one_example_com — no como un nombre aplanado modificado.

Beneficios clave:

  • Separación limpia entre la configuración base y las sobrescrituras.
  • API estándar de Drupal (ConfigFactoryOverrideInterface).
  • Soporte adecuado de exportación/importación de configuración — las colecciones se exportan como subdirectorios.
  • Los eventos de configuración (save, delete, rename) se gestionan automáticamente.

El submódulo opcional Domain Config Language añade una segunda colección (domain.{domain_id}.language.{lang_code}) encima de la de por dominio, para los sitios que necesitan sobrescrituras indexadas tanto por dominio como por idioma.

Cómo funciona en tiempo de ejecución

Resolución de sobrescrituras

Cuando Drupal carga un objeto de configuración (por ejemplo, system.site), la config factory solicita a todos los servicios de sobrescritura registrados que proporcionen sus sobrescrituras. Domain Config registra un servicio de sobrescritura:

  • domain.config_factory_override (prioridad -253) — carga la sobrescritura por dominio desde la colección domain.{domain_id}.

El resultado final fusionado sigue esta cascada:

Configuración base (colección por defecto)
  ↓ fusionada con
Sobrescritura por dominio (colección domain.{domain_id})
  = Configuración final en tiempo de ejecución

Ejemplo con system.site en el dominio two_example_com:

# Configuración base (colección por defecto):
system.site:
  name: "My Site"

# Sobrescritura por dominio (colección domain.two_example_com):
system.site:
  name: "Two"        # sobrescribe "My Site" → "Two"

# Resultado final en tiempo de ejecución: name = "Two"

Cuando domain_config_language también está instalado, una capa adicional (domain, langcode) se añade a esta cascada — véase la documentación de Domain Config Language.

Contexto de dominio

El dominio activo se determina mediante DomainNegotiationContext, que se inyecta en el servicio de sobrescritura. El contexto se establece durante el evento kernel request por DomainSubscriber y también puede cambiarse programáticamente (por ejemplo, por Domain Config al comparar configuraciones entre dominios).

Cuando no hay un dominio activo (por ejemplo, durante comandos Drush sin contexto de dominio), no se aplican sobrescrituras y se utiliza la configuración base.

Negociación temprana para middlewares

Si los middlewares de terceros necesitan sobrescrituras de domain_config antes de que se dispare el evento kernel request, instale el módulo Domain Early Negotiation (domain_early_negotiation) del proyecto Domain Extras. Consulte la documentación de Domain para más detalles.

Cache

El servicio de sobrescritura proporciona un sufijo de cache basado en el ID del dominio actual. Esto garantiza que los objetos de configuración almacenados en cache para un dominio no se sirvan a otro.

Los metadatos de cache incluyen el cache context domain, por lo que el contenido renderizado que depende de configuración específica de dominio varía correctamente.

Guardado de las sobrescrituras

Al guardar una sobrescritura, DomainConfigOverrideEditable::save() solo conserva las claves cuyo valor realmente cambia con respecto a la base. El resto se ignora: la sobrescritura solo contiene las diferencias.

Funciona igual para las dos formas de escribir en la config:

  • ConfigFormBase, que llama a set() clave por clave,
  • ConfigEntityStorage::doSave(), que llama a setData() con toda la config de una vez.

El resultado almacenado es el mismo: una sobrescritura mínima.

Dos consecuencias útiles a tener en cuenta:

  • devolver una clave a su valor de base la retira de la sobrescritura;
  • cambiar otra clave en una config ya sobrescrita (por ejemplo cambiar la región de un bloque cuyo label es lo único sobrescrito) no toca la sobrescritura existente: la nueva diferencia simplemente se añade.

A la inversa, la lectura sin sobrescritura (ConfigEntityStorage::loadMultipleOverrideFree()) es un problema distinto y no se trata aquí. Ver #3587744 y el submódulo domain_config_entity_ui previsto en domain_extras.

Limitación conocida: acortar una lista

Una sobrescritura por dominio no puede acortar una sequence: los elementos presentes en la base más allá de la longitud de la sobrescritura siguen visibles. Esta limitación viene del core de Drupal, no de domain_config.

Ejemplo. La base tiene allowed_tags: ['a', 'em', 'strong', 'p']. La sobrescritura la reemplaza por ['a', 'em', 'strong'] — se quiere quitar 'p'. En la lectura, el core fusiona mediante NestedArray::mergeDeepArray([$base, $override], TRUE). La fusión recorre los arreglos clave por clave, por lo que 'p' (en el índice 3) permanece, y el visitante sigue viendo los cuatro elementos.

El formato de las sobrescrituras no sabe expresar «ignora el índice N de la base». Por eso domain_config no puede corregir este comportamiento sin alejarse de cómo funcionan las demás sobrescrituras de Drupal (settings.php, sobrescrituras de módulos, etc.).

Según el caso, hay varias soluciones:

  • si controlas el esquema, sustituir la sequence por un mapping asociativo: las sobrescrituras funcionan correctamente sobre maps asociativos;
  • sobrescribir más bien la clave padre y escribir ahí la lista completa deseada mediante código;
  • modificar directamente la configuración de base.

Eventos del ciclo de vida de configuración

Domain Config 3.x gestiona adecuadamente los eventos del ciclo de vida de la configuración para mantener las sobrescrituras de dominio sincronizadas con la configuración base:

Evento Comportamiento
Config save Para cada dominio, si existe una sobrescritura de dominio para la configuración guardada, se filtra para eliminar los valores idénticos a la nueva configuración base (conservando solo las sobrescrituras reales).
Config delete Si se elimina la configuración base, la sobrescritura de dominio correspondiente se elimina de todas las colecciones de dominio.
Config rename Si se renombra la configuración base, la sobrescritura se renombra en todas las colecciones de dominio para coincidir.

Exportación e importación de configuración

Como las sobrescrituras viven en colecciones de Drupal, se integran con el sistema de exportación/importación de configuración:

Estructura del directorio de exportación:

El FileStorage de Drupal convierte los puntos en los nombres de colección en separadores de directorio. La colección domain.one_example_com se convierte en el directorio domain/one_example_com/:

config/sync/
  system.site.yml                              # Configuración base
  domain/
    one_example_com/
      system.site.yml                          # Sobrescritura por dominio
    two_example_com/
      system.site.yml

Los módulos también pueden incluir sobrescrituras de dominio por defecto usando la misma convención en su directorio config/install/:

mymodule/config/install/
  domain/
    one_example_com/
      system.site.yml
    two_example_com/
      system.site.yml

Cuando se crea una nueva entidad de dominio, installDomainOverrides() llama a ConfigInstallerInterface::installCollectionDefaultConfig() de Drupal para instalar los valores por defecto proporcionados por los módulos para la colección de ese dominio.

Cuando domain_config_language está instalado, este mismo esquema se extiende con un subdirectorio language/{langcode}/ bajo cada carpeta de dominio — véase la documentación de Domain Config Language.

Domain Config UI

El módulo opcional Domain Config UI proporciona una interfaz de usuario para gestionar las sobrescrituras por dominio directamente desde los formularios de configuración existentes.

Consulte la documentación de Domain Config UI para más detalles sobre:

  • Activar/desactivar sobrescrituras por configuración y por dominio.
  • El enlace de acción en línea en los formularios de administración.
  • Configuraciones no permitidas.
  • Control programático mediante alter hooks.

Migración de 2.x a 3.x

La migración 2.x → 3.x la lleva domain_config_language porque todo sitio 2.x con sobrescrituras por dominio tenía también el módulo language activado, y el formato de almacenamiento heredado era el mismo independientemente de si había sobrescrituras por idioma o no. domain_config_update_10002() instala automáticamente domain_config_language durante drush updatedb cuando language está activado, y la migración se ejecuta desde domain_config_language_install().

Véase la documentación de Domain Config Language para los pasos completos de la migración y las notas de retroceso.

Servicios

Servicio Clase Función
domain.config_factory_override DomainConfigFactoryOverride Sobrescrituras de configuración por dominio (prioridad -253)
domain_config.library.discovery.collector DomainConfigLibraryDiscoveryCollector Decora el descubrimiento de librerías para variar por dominio

Issues relacionados