0

I was trying to get the path alias using for nodes using the following code.

\Drupal::service('path.alias_manager')->getAliasByPath('/node/' . $nid);

It works for nodes that are already created, but it breaks when a new node is being added. I get the following error.

Uncaught PHP Exception Symfony\Component\Routing\Exception\InvalidParameterException: "Parameter "node" for route "entity.node.canonical" must match "\d+" ("" given) to generate a corresponding URL.

Is there an alternative way to get the path alias for nodes that have not been saved yet?

3
  • 1
    Aliases are alternative paths to the node. They require the canonical path, so that there is a path to be an alternative of. The canonical path requires the Node ID (Entity ID) as node paths are /node/[NODE ID], which doesn't exist, until the node has been saved. So the answer is that no, it's impossible to create an alias before a node has been saved, as the canonical path does not and cannot exist until the node has been saved.
    – Jaypan
    Commented Jun 4, 2020 at 15:12
  • @Jaypan Even if that says it's not possible, that is still an answer, since it explains why it's not possible.
    – avpaderno
    Commented Jun 5, 2020 at 8:19
  • Ok, I figured I wasn't really helping which is why I posted it as a comment. Added as an answer. Thanks Kimamlaluno.
    – Jaypan
    Commented Jun 5, 2020 at 14:50

2 Answers 2

1

Aliases are alternative paths to the node. They require the canonical path, so that there is a path to be an alternative of. The canonical path requires the Node ID (Entity ID) as node paths are /node/[NODE ID]. The Node ID doesn't exist until the node has been saved, as it comes from the database upon save. So the path does not exist until the node has been saved, meaning there is nothing to alias.

So the answer is that no, it's impossible to create an alias before a node has been saved, as the canonical path does not and cannot exist until the node has been saved.

0

Well, there "is" a "way"... But it would be very convoluted, error-prone and limited to specific use-case. So only try it if you really cannot wait until you got past the save...

It amounts to, basically, calling/injecting the pathauto.generator service (on 8.7, it may have changed name since 8.8) and the token service then...

a) Requesting the appropriate pathauto configuration for your current entity with $pathautoGenerator->getPatternByEntity (unless I'm mistaken, you have an $entity in pre_save, and this method does not care that you have an id or not, it just needs to query entitytype and bundle).

b) Recreating the string that corresponds to alias by reading that config then using the appropriate fields values to reconstruct (or if easier for you using $tokenService->replace with $string being the pattern, $data being ['node' => $yourNode]).

If obviously won't work if you're actually using in your pattern any metadata that is yet to be filled on pre-save (which means on a brand new entity, at least nid, vid and uuid).

Honestly I feel that this would be a "glorified hack" (with "raw hack" being writing everything without even trying to rely on pattern configuration XD).

So I'd use it only until I found better way to go or managed to get rid of that "need to get alias before entity is saved" (like put a big @todo / @fixme "refactor or remove ASAP").

If this is a common need for you in your whole site, you may question whether best for later maintenance/evolution is... - keeping using Pathauto or... - "building up custom alias generator/manager".

Hope that helps. :)

3
  • This won't work, path_alias entities have two fields that are required - path and alias. Paths don't exist until the entity has been saved, so without a path, thepath_alias entity cannot be created. See the base field definitions: api.drupal.org/api/drupal/…
    – Jaypan
    Commented Jun 5, 2020 at 16:09
  • Well, in my comprehension, OP wanted the "string representing the alias", not "the actual alias". In other words, if I'm not mistaken, he wanted to get the information "alias part" of the path_alias entity, not to create the entity himself. So as long as the string didn't need any component of the path, it would fit its need.
    – Laurent L.
    Commented Jun 9, 2020 at 14:27
  • It's a race condition (en.wikipedia.org/wiki/Race_condition). Another node with the same alias may exist, or may be created while this alias is being calculated. This would only be a calculation of what the alias may be, not what it will be. It's an unreliable method that requires hoping users will not try to create nodes at the same time that would have the same alias.
    – Jaypan
    Commented Jun 9, 2020 at 14:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.