There are plenty of ways to create links when using Drupal 8 and I will share some of those ways in this post.
The easiest way to create internal links is using Link::createFromRoute
And it is used like this:
use Drupal\Core\Link; $link = Link::createFromRoute('This is a link', 'entity.node.canonical', ['node' => 1]);
Using the Url
object gives you more flexibility to create links, for instance, we can do the same as Link::createFromRoute
method using the Url object like this:
use Drupal\Core\Link; use Drupal\Core\Url; $link = Link::fromTextAndUrl('This is a link', Url::fromRoute('entity.node.canonical', ['node' => 1]));
And actually Link::fromTextAndUrl
is what Drupal recommends instead of using the deprecated l()
method. Passing the Url object to the link object gives you great flexibility to create links, here are some examples:
Internal links which have no routes:
$link = Link::fromTextAndUrl('This is a link', Url::fromUri('base:robots.txt'));
External links:
$link = Link::fromTextAndUrl('This is a link', Url::fromUri('http://www.google.com'));
links with only the fragment (without url) :
$link = Link::fromTextAndUrl('This is a link', Url::fromUri('internal:#fragment'));
Using the data provided by a user:
$link = Link::fromTextAndUrl('This is a link', Url::fromUserInput('/node/1');
The param passed to fromUserInput must start with /,#,? or it will throw an exception.
Linking entities.
$link = Link::fromTextAndUrl('This is a link', Url::fromUri('entity:node/1'));
Entities are a special case, and there are more ways to link them:
$node = Node::load(1); $link = $node->toLink(); $link->setText('This is a link');
And even using the route:
$link = Link::fromTextAndUrl('This is a link', Url::fromRoute('entity.node.canonical', ['node' => 1]));
Drupal usually expects a render array if you are going to print the link, so the Link object has a method for that:
$link->toRenderable();
which will return an array.
Final tips:
Searching a route using Drupal Console
The easiest way to find the route of a specific path is using Drupal Console, with the following command.
$ drupal router:debug | grep -i "\/node"
That will return something like:
entity.node.canonical /node/{node} entity.node.delete_form /node/{node}/delete entity.node.edit_form /node/{node}/edit entity.node.preview /node/preview/{node_preview}/{view_mode_id} entity.node.revision /node/{node}/revisions/{node_revision}/view entity.node.version_history /node/{node}/revisions node.add /node/add/{node_type} node.add_page /node/add node.multiple_delete_confirm /admin/content/node/delete node.revision_delete_confirm /node/{node}/revisions/{node_revision}/delete node.revision_revert_confirm /node/{node}/revisions/{node_revision}/revert node.revision_revert_translation_confirm /node/{node}/revisions/{node_revision}/revert/{langcode} search.help_node_search /search/node/help search.view_node_search /search/node view.frontpage.page_1 /node
Listing all the possible routes with that word, we can choose one and do:
drupal router:debug entity.node.canonical
And that will display more information about a specific route:
Route entity.node.canonical
Path /node/{node}
Defaults
_controller \Drupal\node\Controller\NodeViewController::view
_title_callback \Drupal\node\Controller\NodeViewController::title
Requirements
node \d+
_entity_access node.view
_method GET|POST
Options
compiler_class \Drupal\Core\Routing\RouteCompiler
parameters node:
type: 'entity:node'
converter: paramconverter.entity
_route_filters method_filter
content_type_header_matcher
_route_enhancers route_enhancer.param_conversion
_access_checks access_check.entity
So in this way we can search the route without the needing to search in all the *.routing.yml files and in this example the route is entity.node.canonical
and the param expected is node.
Print links directly within a twig template
It is also possible to print links directly on the twig template with the following syntax:
<a href="{{url('entity.node.canonical', {'node': node.id( ) }}"> {{ 'This is a link'|t }} </a>
Add links inside a t() method.
If you want to add a link inside the t() you can do what Drupal suggests on Dynamic or static links and HTML in translatable strings:
use Drupal\Core\Url; $url = Url::fromRoute('entity.node.canonical', ['node' => 1]); $this->t('You can click this <a href=="@link">Link</a>', ['@link' => $url->toString()]);