37

I have a node object, and I am trying to use it to get a given path in Drupal 8.

There was drupal_lookup_path() in Drupal 7 but I'm not seeing any equivalent or documentation for Drupal 8.

What's the new "Drupal" way to get a path from a node object?

Would it be something simple like $node->get('path')?

This seems like a simple question, but I'm just absolutely not finding any documentation on it.

Notice I do not want the path alias for the current path; I want the path alias for an arbitrary node, given a node object or a node ID.

5
  • 3
    Possible duplicate of Get the current path alias or path?
    – Kevin
    Mar 8 '17 at 17:06
  • I think this might be a duplicate, check the linked question there are lots of answers.
    – Kevin
    Mar 8 '17 at 17:07
  • The other question has answers saying how to get the path alias for the current path, not for a node for which the OP knows the node ID.
    – apaderno
    Mar 8 '17 at 17:59
  • It's not a duplicate - I don't want the current path. I want the path given an arbitrary node object or NID.
    – Jack Ryan
    Mar 8 '17 at 18:03
  • 1
    Yes, this is not a duplicate, see my answer.
    – 4k4
    Mar 8 '17 at 19:10
72

To get the path alias for a node given its node ID use the path.alias_manager service, like the following code.

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

In Drupal 8.8.0 and newer versions, the path.alias_manager service has been deprecated, removed in Drupal 9, and replaced by the path_alias.manager service. The code doesn't change, except it requires a different service.

See The Path Alias core subsystem has been moved to the "path_alias" module, which lists all the services that have been deprecated.

1
29

If you only have the nid, 4k4's solution of

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

Works great. But if you already have a node object you can skip a step or two. Nodes actually have built in methods for getting urls.

$node->toUrl()->toString();

Would return the aliased url of the node.

toUrl() returns a url object. See here https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/class/Url/8.2.x

and toString() is a method of the url object that returns the string representation of the url.

2
  • 16
    Note that $node->toUrl()->setAbsolute()->toString() will return the absolute URL, useful for sharing etc.
    – Tim
    Nov 18 '17 at 14:57
  • 1
    Both methods look equivalent at first sight, but there is a difference. Using $node->toUrl() will give you the full path to a node. This means you get the path alias, but other URL manipulations (e.g. adding a language prefix) will also be applied. The getAliasByPath() method, on the other hand, will give you just the path alias. Sep 27 at 9:46
23

What about using Url:

use Drupal\Core\Url;    

...

$url = Url::fromRoute('entity.node.canonical', ['node' => $nid])->toString();
3
  • 12
    IIRC, the primary difference between this and using the AliasManager, is that this will also ensure that outbound path processors run, while AliasManager just does the alias lookup. You can also get the Url object directly as $node->toUrl().
    – mpdonadio
    Mar 9 '17 at 0:57
  • 2
    Much better solution.
    – Patrick
    Oct 21 '17 at 23:35
  • 1
    Broiken if installed in a subdir. Jul 16 '20 at 5:33
8

Best way to get node URL from node object-

  • Absolute Path : $node->toUrl()->setAbsolute()->toString();
  • Relative Path : $node->toUrl()->toString();

It will also handle node language.

1
  • The question was about the node alias, this is broiken if installed in a subdir. Jul 16 '20 at 5:33
4

You can also use the load method from path.alias_storage to return an array of the alias details or boolean false if there wasn't a path found for that node.

$aliasArray = \Drupal::service('path.alias_storage')->load(['source' => '/node/' . $nid]);

1
  • Will this load all existing aliases? I would say yes. In my case, I need all aliases. Jun 3 at 16:42
3

If you want to get the node alias url by languages dont forget to use the language like this.

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

If you are using it in a class do not forget to use the dependencies injection correctly.

1

As per the new change record in Drupal 8.8.0 path.alias_manager is deprecated and path_alias.manager is introduced.

New syntax is as follows :

$url_alias = \Drupal::service('path_alias.manager')->getAliasByPath('/node/'. $nid, $langcode);
0

Surprisingly, as of Drupal 9.2, none of the current answers work in a multilingual site that uses path prefixes for language detection.

This is what I ended up using:

// Note: using dependency injection to get the language code.
$lang_code = $this->languageManager
  ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
  ->getId();

// Note: using dependency injection to load the node.
$test_nid = 1
$test_node = $this->entityTypeManager->getStorage('node')->load($test_nid);

// If the node has a translation, load it.
if ($test_node->hasTranslation($lang_code)) {
  $test_node = $test_node->getTranslation($lang_code);
}

// Get the localized URL for that node.
$localized_url = $test_node->toUrl('canonical', [
  'language' => $test_node->language(),
])->toString();
-6

I was hoping for a more "Drupalesque" solution, but here's what I made myself to do the job:

  function getPathFromNID($nid) {
    $db = \Drupal::database();

    $data = $db
        ->select('url_alias', 'u')
        ->fields('u', ['alias'])
        ->condition('source', '/node/' . $nid)
        ->execute()
        ->fetchField();
    return $data;
  }
2
  • 4
    No, you should never be directly querying core tables like this in Drupal 8. Use the API like all the above answers.
    – anonymous
    Jul 8 '20 at 17:32
  • One of the issues with this is if there's a core update that changes how these aliases are stored this code will break.
    – Matt
    Jun 17 at 19:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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