Creating a link from node ID in Drupal 8
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();
Related videos on Youtube
Nicensin
Updated on March 03, 2022Comments
-
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 about 8 yearsthis 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 about 8 yearsThe 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, useLink::fromTextAndUrl()
instead. -
Paul Leclerc over 7 yearsCould 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 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.