6

I'm making the leap from Drupal 7 to Drupal 8 and am still fuzzy on some core concepts, particularly relating to dependency injection (DI). I've read plenty of tutorials and have a grasp on DI with services, but am unclear on using DI with something like \Drupal::Url().

For instance, I am using the following code in a class: use Drupal\Core\Url; ... $url = Url::fromRoute('<current>', [], ['absolute' => 'true'])->toString();

From what I can tell, there is no Url service. So, what I am wondering is: Is it possible to access Url via DI? And if so, how?

Bonus points: I intend for the class I am writing to be used as a service. Does this have any impact on the answer?

Edit: Fixed erroneous code.

Edit 2: I should also point out that the purpose of this call is to retrieve the current absolute URL so that I can determine if it is HTTPS.

0

1 Answer 1

5

You can inject the UrlGenerator as service and use UrlGenerator::generateFromRoute, but in the linked doc you are discouraged to do so:

@internal Should not be used in user code. Use \Drupal\Core\Url instead.

So the code in your question to create an url object is OK for a service, but not the toString() method. Render the url only with this method when the page rendering process has started, for example in a theme.

In a service you usually don't know this and you should return an unrendered url object, so that it can be rendered later in the rendering pipeline.

$url = Url::fromRoute('<current>', [], ['absolute' => 'true']);

toString() in the wrong place generates ugly error messages about early rendering which are hard to debug when this happens somewhere in a service.

7
  • Awesome! This is great information, especially about avoiding toString(). So, am I to understand correctly that it is acceptable to use the static Url::fromRoute procedurally and without DI?
    – Beau
    Sep 29, 2017 at 15:31
  • "The Url class is basically a value object, so in that sense doesn't need to be injected. It's only when you render it to a string that the UrlGenerator dependency is pulled in. But you basically shouldn't be rendering it yourself - use a link render array." drupal.org/node/2491981#comment-11556477 - #36
    – 4uk4
    Sep 29, 2017 at 15:50
  • I really appreciate this information. I've edited my question to add clarification. Does the 2nd edit impact this answer?
    – Beau
    Sep 29, 2017 at 17:16
  • No, because this would be about how to inject the request stack, get the current request and then $request->getScheme()
    – 4uk4
    Sep 29, 2017 at 19:35
  • Do you think that is a good idea to inject the renderer service and then render the link render array inside the service? May 18, 2018 at 19:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.