Skip to content

Architecture

This page describes how Domain Path works under the hood. It is aimed at developers who want to understand the module's internals, debug alias resolution, or contribute code.

Request flow

The following diagram shows how an outbound URL is resolved when Domain Source and Domain Path are both enabled:

    Drupal renders a link to /node/42
                   |
                   v
  +--------------------------------------+
  | DomainSourcePathProcessor (pri 310)  |
  | Sets $options['domain'] = shop.com   |
  +--------------------------------------+
                   |
                   v
  +--------------------------------------+
  | DomainPathAliasProcessor (pri 305)   |
  | Looks up alias for /node/42 on       |
  | shop.com -> /widget                  |
  | Sets $options['alias'] = TRUE        |
  +--------------------------------------+
                   |
                   v
  +--------------------------------------+
  | Core AliasPathProcessor (pri 300)    |
  | SKIPPED ($options['alias'] is set)   |
  +--------------------------------------+
                   |
                   v
       Final URL: https://shop.com/widget

Without Domain Source, the active (negotiated) domain is used instead.

Key services

All services are defined in domain_path.services.yml.

domain_path.path_alias_manager

Class: DomainPathAliasManager

Decorates core's path_alias.manager. Implements both AliasManagerInterface and DomainAliasManagerInterface.

Key methods:

  • getAliasByPath($path, $langcode) -- resolves the alias for the active domain (from domain.negotiator).
  • getAliasByPathAndDomain($path, $langcode, $domain_id) -- resolves the alias for a specific domain. Falls back to the core alias if no domain-specific alias exists.
  • getPathByAlias($alias, $langcode) / getPathByAliasAndDomain(...) -- reverse lookups (alias to system path).

The manager maintains its own cache layer (cache.data) with 24-hour TTL, keyed by language and domain.

domain_path.repository

Class: DomainAliasRepository

Decorates core's path_alias.repository. Adds domain_id conditions to the SQL queries that look up aliases in the path_alias table.

domain_path.path_processor

Class: DomainPathAliasProcessor

Outbound path processor registered at priority 305 (between Domain Source at 310 and core at 300).

  • Checks for $options['domain'] (a DomainInterface entity).
  • Calls getAliasByPathAndDomain() to resolve the domain-specific alias.
  • Sets $options['alias'] = TRUE so core's processor does not override the result.

domain_path.helper

Class: DomainPathHelper

The central helper service used by form hooks and field logic:

  • alterEntityForm() -- adds domain path fields to entity forms.
  • submitEntityForm() -- handles bulk deletion of domain path aliases.
  • getConfiguredEntityTypes() -- returns the list of enabled entity types.
  • userCanAccessDomain($domain, $user) -- checks domain_access permissions.
  • getUserAccessibleDomains($user) -- returns domains the user can edit.
  • getDomainAccess($entity) -- reads domain_access field values from an entity.

Entity model

Path alias extension

Domain Path adds a domain_id base field to the path_alias entity type via hook_entity_base_field_info(). This field stores the machine name of the domain a given alias belongs to. An empty domain_id means the alias is the default (domain-agnostic) alias.

DomainPathItem (field type)

Class: Drupal\domain_path\Plugin\Field\FieldType\DomainPathItem

Extends core's PathItem with an additional domain_id property. The postSave() method creates, updates, or deletes path_alias entities based on the submitted form values.

Before saving, checkAccess() verifies that the entity is actually assigned to the target domain (via domain_access), preventing orphan aliases.

DomainPathFieldItemList (computed field)

Class: Drupal\domain_path\Plugin\Field\FieldType\DomainPathFieldItemList

Extends PathFieldItemList. The computeValue() method generates one field item per accessible domain, loading existing aliases from storage for saved entities.

Access control:

  • View: allowed for all users.
  • Edit/Create: requires create url aliases or administer url aliases permission.

Validation constraints

All constraints are applied at the field type level via the #[FieldType] attribute on DomainPathItem.

DomainPathSlash

Validates that the alias starts with a forward slash (/). Leading and trailing whitespace is trimmed before validation.

DomainPathUnique

Ensures that no two entities have the same alias on the same domain. An entity may update its own alias without triggering a violation.

DomainPathUserAccess

Prevents users from setting aliases on domains they do not have access to. Uses DomainPathHelper::userCanAccessDomain() for the check.

Event subscribers

DomainPathConfigSubscriber

Listens to ConfigEvents::SAVE. When domain_path.settings changes its entity_types list, the subscriber clears the entity field definitions cache so that new field definitions take effect immediately.