How do I create a HTML link from an internal path using the core Link class? I miss the deprecated l() a lot. I am trying to construct the Drupal 8 equivalent of:

l(t('mylink'), 'admin/structure/types');


This call generates this HTML:

'&lt;a href="/admin/structure/types"&gt;mylink&lt;/a&gt;'


I want to know how to produce the same HTML (i.e. a string) using the Link class.

Please understand that I am not looking asking how to render the link. I need the string for other purposes than rendering. I fully aware of that usually, one wants to render the link. If that is what you want to do, you should look at the accepted answer to this question: How do I create a link?.

I am trying to generate an HTML link to'admin/structure/types'. But will appreciate an answer that explains how to do this for any valid internal path.

I've looked at a lot of examples, a most of the them end up saying one should use Link::fromTextAndUrl in some construct like this - without explaining how to get $routename from the path.: 

Link::fromTextAndUrl(t('mylink'), Url::fromRoute($routeName));


However, by searching (as suggested by Jaypan) I was able to determine that the routename for this path was 'entity.node_type.collection'.  This works as one would expect:

  $url = Url::fromRoute('entity.node_type.collection');
  $url_string = $url-&gt;toString();


I.e.: $url_string is now 'admin/structure/types'.

So I proceed to build a link object

$link = Link::fromTextAndUrl(t('mylink'), Url::fromRoute('entity.node_type.collection'));


Now: How to get an HTML string?

No Sssweat suggests:

$url = Url::fromRoute('book.admin');
$link_thingy = Link::fromTextAndUrl(t('mylink'), $url)-&gt;toString();


This step just make $link_thingy into an object. Close, but no cigar.

In an updated version of his answer, Jaypan says that treating this object like a string - example:

 print Link::fromTextAndUrl(t('mylink'), Url::fromRoute('user.login'))-&gt;toString();


outputs the HTML string.  This works. This means you will have the HTML string when you use it in a context one would use a string.  Therefore, I've accepted Jaypan's answer.

I've also tried out the kiamlaluno's answer, i.e.:

 $link_thingy = $link-&gt;toRenderable();


This produces a (huge) render array, not a string.  A render array, however, is a very useful thing (see comments for why this is so), but it is not accepted as answer to this question because the question was: How to get an HTML string?

Environment: Clean install of Drupal 8.8.6 (core + devel). Ubuntu 20.04 LTS.
Getting the route can be tricky. Sometimes I'll just do a code search for the path.

Routes are defined in [MODULE].routing.yml files. You can often look for a route you need if you can guess the module that supplies it. For example, the user login page is provided by the user module, so I look in user.routing.yml, in which I find this for the user login route:

user.login:
  path: '/user/login'
  defaults:
    _form: '\Drupal\user\Form\UserLoginForm'
    _title: 'Log in'
  requirements:
    _user_is_logged_in: 'FALSE'
  options:
    _maintenance_access: TRUE


The route name here is user.login. Now, that route name can be used to do the following:

$url = Url::fromRoute('user.login');
// Get the URL string:
$url_string = $url-&gt;toString();
// Build a link:
$link = Link::fromTextAndUrl(t('Log In'), $url);
// Get the link string:
$link_string = $link-&gt;toString();


Note that $link-&gt;toString() returns an object of type Drupal\Core\GeneratedLink. This class has the magic method GeneratedLink::__toString(). This magic method is invoked when the object is treated like a string. That means you can treat the result of $link-&gt;toString() as if it were a string, even though it's an object. So in context where you can print values, this will work:

print Link::fromTextAndUrl(t('mylink'), Url::fromRoute('user.login'))-&gt;toString();