Creating a link from node ID in Drupal 8

44,493

Solution 1

You need to use the \Drupal\Core\Url class, specifically its fromRoute static method. Drupal 8 uses routes which have name different from their actual URL path. In your case, the route to use is the canonical route for a node entity: entity.node.canonical. \Drupal\Core\Url::fromRoute() will not return a string, but an object. To get the URL as a string, you need to call its toString() method.

$options = ['absolute' => TRUE];
$url = \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => 1], $options);
$url = $url->toString();

The static method is not easily testable, $url->toString() require an initialized container. Your can replace the static method with a call to UrlGeneratorInterface::generateFromRoute() on the url_generator service.

$options = ['absolute' => TRUE];
$url = $this->url_generator->generateFromRoute('entity.node.canonical', ['node' => 1], $options);
$url = $url->toString();

Unfortunately, this method is marked as @internal so you are not supposed to use it in user code (ie. outside Drupal core).

Solution 2

Create absolute URL:

$options = ['absolute' => TRUE];
$url_object = Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => $nid], $options);
// will output http://example.com/path-to-my-node

Create absolute link object:

$options = ['absolute' => TRUE, 'attributes' => ['class' => 'this-class']];
$node_title = Drupal\Core\Render\Markup::create('<span>' . $node_title . '</span>');
$link_object = Drupal\Core\Link::createFromRoute($node_title, 'entity.node.canonical', ['node' => $nid], $options);
// will output <a href="http://example.com/path-to-my-node" class="this-class"><span>My Node's Title</span></a>

Solution 3

In case you have fully loaded node object you can simply call $node->toUrl() to get required URL. By default it returns canonical URL for a node (node/NID) but it is possible to build other URLs listed in Node entity definition (see Drupal\node\Entity\Node.php). Same is true for other entity types.

$options = ['absolute' => TRUE];
$view_link = Link::fromTextAndUrl(t('View'), $node->toUrl('canonical', $options));
$edit_link = Link::fromTextAndUrl(t('Edit'), $node->toUrl('edit-form', $options));
$delete_link = Link::fromTextAndUrl(t('Delete'), $node->toUrl('delete-form', $options));

Solution 4

Full absolute path with correct language prefix:

$url_options = [
  'absolute' => TRUE,
  'language' => \Drupal::languageManager()->getCurrentLanguage(),
];
$Path = Url::fromRoute('entity.node.canonical', ['node' => 81], $url_options)->toString();
// prints https://example.com/fr/mon-page

Solution 5

Here is my answer for node edit link.

$nodeInfo = $entity->get('nid')->getValue();
$nodeId = $nodeInfo[0]['value'];
$options = ['absolute' => TRUE];
$url = \Drupal\Core\Url::fromRoute('entity.node.edit_form', ['node' => $nodeId], $options);
$url = $url->toString();
Share:
44,493

Related videos on Youtube

Nicensin
Author by

Nicensin

Updated on March 03, 2022

Comments

  • Nicensin
    Nicensin about 2 years

    I am checking out Drupal 8 and try to generate a link based on the node ID of an article. In Drupal 7 it is something like:

    $options = array('absolute' => TRUE);
    $nid = 1; // Node ID
    $url = url('node/' . $nid, $options);
    

    This results into an absolute link with the correct url-alias.

    So the url()-function seems to be deprecated; what is the Drupal-8 way? Looks like a really basic function for me but I could not find any useful references.

  • Nicensin
    Nicensin about 8 years
    this did it for me. thanks for the snippet! if an alias is defined i get the alias, if not I get the link with .../node/id.
  • Nadeem Ahmed
    Nadeem Ahmed about 8 years
    The OP ask specifically for a node URL from ids ID, this answer is incomplete0 Also, the OP is asking for a absolute URL (per original code), this answer does not produce absolute URL. Finally, \Drupal::l() is deprecated, use Link::fromTextAndUrl() instead.
  • Paul Leclerc
    Paul Leclerc over 7 years
    Could you explain how to use it ? Where did I change / add code ? In theme > preprocess ? Url.php or the Core ? It is difficult to find global answer when we start Drupal..
  • Nicensin
    Nicensin over 6 years
    @PaulLeclerc You should never change something in the core just as a general note. You can use the code examples above wherever you need it. It works in every file where you can use php. We obviously can not answer this for you because we do not know what you want to do.