When creating various pages developers often have to generate links, URLs and occasionally redirect users to where they came from, or any other arbitrary page. In Drupal 7 we used l()
, drupal_get_destination()
and drupal_goto()
. As you may suspect, things have changed drastically with Drupal 8. Although drupal_get_destination()
is still there, it is marked deprecated, so we should not be using it any longer.
URL generation
When adding a URL into a string, for instance in a text description, core recommends we use the \Drupal\Core\Url
class. This has a few handy methods:
- Internal URL based on a route -
Url::fromRoute()
, Example:Url::fromRoute('acquia_connector.settings')
- Internal URL based on a path -
Url::fromInternalUri()
, Example:Url::fromInternalUri('node/add')
- External URL -
Url::fromUri
, Example:Url::fromUri('https://www.acquia.com')
The last two methods are very similar, the main difference is, that fromInternalUri()
already assumes an 'internal:' prefix, which tells Drupal to build an internal path. It's worth reading up on what prefixes are supported, for instance the ':entity' prefix can help in building dynamic URIs.
When you need to constrict and display the link as text you can use the toString()
method: Url::fromRoute('acquia_connector.settings')->toString()
.
Redirection - drupal_goto in Drupal 8
Back in the days, things were simple. The bread was cheaper, Drupal was procedural and developers were using drupal_goto()
, like there is no tomorrow. But times are changing. Drupal is now object-oriented, and response generation became more regulated than before.
To redirect the visitor, one typically placed drupal_goto()
s into his, or her page callback. Page callbacks are a thing of the past now, being replaced by Controllers. A typical route will respond with a Controller class which extends ControllerBase, and is responsible for delivering the right response to the browser. To issue a redirection, we simply need to return the right response. Under the hood this is handled via the RedirectResponse class, courtesy of Symfony:
use Drupal\Core\Url; ... return new RedirectResponse(Url::fromUri('/node/add'));
The ControllerBase
class in Drupal 8 (via the UrlGeneratorTrait
trait) exposes the redirect()
method, which gives us a handy shortcut, so in case you are redirecting to an internal route, you can implement the same redirection by simply calling: return $this->redirect('acquia_connector.settings');
.
Summary - tl;dr
l()
is gone. Use \Drupal\Core\Link for full link objects, and \Drupal\Core\Url for URL generation.drupal_goto()
is gone. Use a RedirectResponse, or the redirect() method in your controller.