hook_pathauto_pattern_alter()
is only invoked when:
- The entity has a path field
- Pathauto processing is enabled
- For entities that support revisions, the entity is using the default revision
- A default pattern has been set for that entity
$entity->toUrl()->getInternalPath()
doesn't throw a EntityMalformedException
, UndefinedLinkTemplateException
, or UnexpectedValueException
exception
The shown hook is also only invoked when an entity is updated, not when an entity is created.
When the Pathauto module has been set not to change an existing path alias, even if hook_pathauto_pattern_alter()
were invoked, the path alias wouldn't be changed.
As side note, the hook could should first check the entity for which the hook is invoked is a node, which is what the example hook in pathauto.api.php does.
/**
* Alter the pattern to be used before an alias is generated by Pathauto.
*
* This hook will only be called if a default pattern is configured (on
* admin/config/search/path/patterns).
*
* @param \Drupal\pathauto\PathautoPatternInterface $pattern
* The Pathauto pattern to be used.
* @param array $context
* An associative array of additional options, with the following elements:
* - 'module': The module or entity type being aliased.
* - 'op': A string with the operation being performed on the object being
* aliased. Can be either 'insert', 'update', 'return', or 'bulkupdate'.
* - 'source': A string of the source path for the alias (e.g. 'node/1').
* - 'data': An array of keyed objects to pass to token_replace().
* - 'bundle': The sub-type or bundle of the object being aliased.
* - 'language': A string of the language code for the alias (e.g. 'en').
* This can be altered by reference.
*/
function hook_pathauto_pattern_alter(\Drupal\pathauto\PathautoPatternInterface $pattern, array $context) {
// Switch out any [node:created:*] tokens with [node:updated:*] on update.
if ($context['module'] == 'node' && ($context['op'] == 'update')) {
$pattern->setPattern(preg_replace('/\[node:created(\:[^]]*)?\]/', '[node:updated$1]', $pattern->getPattern()));
}
}
The code for the shown hook would be similar to the following one.
use Drupal\pathauto\PathautoPatternInterface;
function mymodule_pathauto_pattern_alter(PathautoPatternInterface $pattern, array $context) {
if ($context['module'] == 'node' && $context['op'] === "update" && $context['bundle'] === "news") {
$node = $context['data']['node'];
$archived = $node->get('field_archived')->getString() === "1";
if ($archived) {
$pattern->setPattern('/archive/[node::title]');
}
}
}
Objects are already passed by reference; it's not necessary to define the first parameter as &$pattern
.
I would also verify there aren't other modules implementing hook_pathauto_pattern_alter()
for which their implementation is invoked after the implementation shown in the question, and that is altering the pattern for the same entity and the same bundle.
References