I want to create a small, custom Drupal 8 module to open all external links in the menu in a new tab, how can I do that?
I think I should use hook_link_alter
to do it, but I don't know how to do it so I can select all the external links only?
I want to create a small, custom Drupal 8 module to open all external links in the menu in a new tab, how can I do that?
I think I should use hook_link_alter
to do it, but I don't know how to do it so I can select all the external links only?
Links can be generated in a number of ways, which makes it hard to change consistently. For a single implementation that you want to reach most parts, you should swap the link_generator
service with your own subclass. This should catch all menu items and links in general, but wont touch custom markup from wysiwyg. Here you would need to create a custom filter.
The ::generate($text, Url $url)
method is what is used to actually create the create the HTML. What you want to do, it to add the _blank
target attribute if the url is external.
The code for the link generator subclass, could look like this:
class MyLinkGenerator extends LinkGenerator {
public function generate($text, Url $url) {
if ($url->isExternal()) {
$attributes = $url->getOption('attributes');
$attributes['target'] = '_blank';
$url->setOption('attributes', $attributes);
}
return parent::generate($text, $url);
}
}
I wont go into how to change the class of a service, there is plenty of examples for this here and elsewhere.
If you want to use hook_link_alter you can also simply implement the following code in a module :
/**
* Implements hook_link_alter().
*/
function mymodule_link_alter(&$vars) {
if ($vars['options']['external'] == TRUE) {
$vars['options']['attributes']['target'] = '_blank';
}
}
extlink contrib module for Drupal 8 & 9 (also a D7 version) can do the job.
On the extlink contrib module project page it says:
Configure external links to open in a new window
And there is other functionality, too.
I've just started using this module and from tests so far, it does the job.
In my case it does actually open an external link in a new tab so even though it says new window, it actually opens in a new tab.