Problem/Motivation

PathautoGenerator::createEntityAlias() contains the entire alias generation algorithm in a single monolithic method. Modules that need to customize specific steps — such as how existing aliases are loaded, how aliases are uniquified, or how the path array is built — have no choice but to duplicate the entire ~120-line method body in a decorator or subclass.

This is fragile: any upstream bugfix or improvement to the algorithm must be manually replicated in the downstream copy.

Proposed resolution

Apply the Template Method pattern: extract the algorithm body into a protected doCreateEntityAlias() method that calls three overridable extension points.

createEntityAlias() becomes a thin wrapper:

public function createEntityAlias(EntityInterface $entity, $op) {
  return $this->doCreateEntityAlias($entity, $op);
}

The new protected method accepts an optional $context_additions array that is merged into the hook context, allowing subclasses to inject extra data (e.g. a domain ID) without duplicating the algorithm.

Three protected extension points replace the previously inlined operations:

  • loadExistingAlias($source, $langcode, $context) — loads an existing alias for update/bulkupdate checks. Default: $this->aliasStorageHelper->loadBySource($source, $langcode).
  • uniquifyAlias(&$alias, $source, $langcode, $context) — ensures the alias is unique. Default: $this->aliasUniquifier->uniquify($alias, $source, $langcode).
  • buildPathArray($source, $alias, $langcode, $context) — builds the path array before saving. Default: ['source' => $source, 'alias' => $alias, 'language' => $langcode].

All three receive the full $context array so subclasses can read any additions they injected.

Remaining tasks

  • Review and commit.

API changes

New protected methods on PathautoGenerator:

  • doCreateEntityAlias(EntityInterface $entity, string $op, array $context_additions = [])
  • loadExistingAlias(string $source, string $langcode, array $context): array|false
  • uniquifyAlias(string &$alias, string $source, string $langcode, array $context): void
  • buildPathArray(string $source, string $alias, string $langcode, array $context): array

No breaking changes — createEntityAlias() behavior is identical. Existing decorators and callers are unaffected.

Issue fork pathauto-3577272

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review

Would be useful for the domain_path pathauto submodule.

Currently duplicated code: https://git.drupalcode.org/project/domain_path/-/blob/3.0.0-beta3/module...

usmanjutt84’s picture

Status: Needs review » Reviewed & tested by the community

I have just tested the MR#166 and works perfectly for me.