Get media entity path or url in twig template for drupal 9, 10; canonical route to individual media content item
- media twig template url path
- media twig template url path drupal
- media twig template url drupal
- media entity path twig template drupal
- canonical, cannonical, cononical, cone of shame, whatever
This sort of thing makes Drupal just bad. Like i know (and Drupal knows) this is information i can get, but rather than follow the paths of convenience that have been developed for the things people have been using regularly for 20 years (nodes) we add a new front-end-facing entity and in the name of “consistency” we make it damn near impossible to figure
While , i thought content entities in general did have the concept of a canonical path.
Or anything broadly equivalent and easy to guess…
{{ media.getUrl()
}} or {{ media.getPath()
}} or url: {{media.url}}
or path: {{media.path.0.value }}
or anything, at least id: {{media.id}}
provided a value.
Looking it up, <a href="{{ path('media.entity.canonical', {'media': media.id}) }}">
should work the same as it can for node, entity.node.canonical
, but got this:
The website encountered an unexpected error. Please try again later.
Symfony\Component\Routing\Exception\RouteNotFoundException: Route “media.entity.canonical” does not exist. in Drupal\Core\Routing\RouteProvider->getRouteByName() (line 206 of core/lib/Drupal/Core/Routing/RouteProvider.php).
So we are not giving simple URL or path functions or variables in the name of consistency, but then our routes for entities, which is what we have to use instead to get the path, also lack any consistency. Got it.
EDIT: Route names are consistent, all the above investigation was unnecessary and only happened because i am dyslexic.
So the solution is as expected:
<a href="{{ path('entity.media.canonical', {'media': media.id}) }}">
OK, fine, let’s look in core/modules/media/media.routing.yml
. We see entity.media.revision
and nothing else even close. OK looking in core/lib/Drupal/Core/Entity/Routing/DefaultHtmlRouteProvider.php
we see there absolutely should be a route available at entity.media.canonical
, if there is a canonical route for media, so… there must not be?
if ($canonical_route = $this->getCanonicalRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.canonical", $canonical_route);
}
Like i know we had to turn it on in the interface but it seems there should be one under the hood always?
OK in core/modules/media/src/Routing/MediaRouteProvider.php
we have this:
/**
* {@inheritdoc}
*/
protected function getCanonicalRoute(EntityTypeInterface $entity_type) {
if ($this->config->get('standalone_url')) {
return parent::getCanonicalRoute($entity_type);
}
else {
return parent::getEditFormRoute($entity_type);
}
}
OK… so ignoring for the moment the fact that the “canonical” route changes based on that setting, what the hell is the canonical route called if not
template_preprocess_node
has this:
$variables['url'] = !$node
->isNew() ? $node
->toUrl('canonical')
->toString() : NULL;
The formatting there makes it unnecessarily hard to parse, so to rephrase, if the node is new, return null, else return the canonical route URL as a string:
$variables['url'] = $node->isNew() ? NULL : $node->toUrl('canonical')->toString();
Tried to help others out by sharing this solution back in a comment on the media template documentation:
Get path or URL for media entity in Twig template
mlncn commented less than a minute ago
While content entities in general have the concept of a canonical path, Drupal has failed to do themers a solid and just have it available in a consistent place. Whereas core’s template_preprocess_node provides node.html.twig
a convenient {{ url }}
variable:
- url: Direct URL of the current node.
That same helpful variable is not available in this media template. I think core should add it, and on any given project we could add it in template preprocess, but for a twig-only solution use:
{{ path('entity.media.canonical', {'media': media.id}) }}
(Or substitute url for the full URL instead of the relative path.)
Note that this will go to the edit page by default but the view page if the standalone URL option is enabled.
See also: https://chromatichq.com/insights/creating-links-within-twig-templates-using-path-and-url/