This post is mostly so I don't forget, as it took several hours to figure out.
Recently, I needed to create some links in a twig templates to various ECK ( Entity Construction Kit ) entity types, mostly to Add, View, and Edit. Now, it's not really a good idea to try building the paths manually, since the paths may change ( if I update the pathauto patterns or something ). Routes are much more stable.
In Twig, there are two main functions for generating links, link() and path(). Link creates an absolute URL, while path ( wait for it ) creates a path or relative URL.
ECK is sort of a special case, because routes are dynamic, since they can't exist until entities and bundles are created. And as far as I can tell, they aren't well documented. I figured most of this out by digging through the repo.
Let's say I have an entity type, Cool Entity ( machine name: cool_entity ) and a bundle, Awesome Stuff ( machine name: awesome_stuff ).
Since in this case, I want relative URLs to View existing Awesome Stuff, edit an existing Awesome Stuff entry, and add new Awesome Stuff ( because I love Awesome Stuff ), I want to use the path() function.
Path accepts a route_name and route_parameters as arguments. I can build my links as such:
<a href="{{ path( 'route_name', {'param_key': 'param_value'}) }}">View Awesome Stuff</a>
All we need to do now if populate the route_name and parameters, right? Well, I found it a bit confusing to determine the correct routes, so that's what we're going to do here.
In ECK, the routes are dynamic, but the View ( canonical ) and Edit ( edit_form ) follow the typical format: "entity.{$entity_type}.canonical" for viewing an existing entity, and "entity.{$entity_type).edit_form" for editing. The only real thing is to populate the route_parameter, which is "{$entity_type}": "{$entity_id}". Our path function becomes:
<a href="{{ path('entity.cool_entity.canonical', {'cool_entity': awesome_stuff.id.value}) }}">View Awesome Stuff</a>
You may have noticed I populated the "{$entity_id}" with "awesome_stuff.id.value". This is just a Twig variable that has my entity id, probably populated from a controller or entity reference field ( because who doesn't want to reference Awesome Stuff? ). However you can get the ID of the Awesome Stuff entity you want to view will work.
For editing our Awesome Stuff:
<a href="{{ path('entity.cool_entity.edit_form', {'cool_entity': awesome_stuff.id.value}) }}">Edit Awesome Stuff</a>
That was actually pretty straight forward. Now for the fun stuff, linking to the entity form to create new Awesome Stuff.
Because of the way ECK works, all entity forms use the same route, 'eck.entity.add', and it's the route parameters that determine which form is displayed ( and subsequently, what entities are created ).
The route 'eck.entity.add' takes two parameters, 'eck_entity_type' and 'eck_entity_bundle'. Obviously, the bundle needs to be a bundle of the entity type. Now our Add link becomes:
<a href="{{ path('eck.entity.add', {'eck_entity_type': 'cool_entity', 'eck_entity_bundle': 'awesome_stuff'}) }}">Add Awesome Stuff</a>
Sweet, now we have links to Add, View, and Edit Awesome Stuff.
By the way, if you want to include a Delete link, it follows a similar pattern as Edit:
<a href="{{ path('entity.cool_entity.delete_form', {'cool_entity': awesome_stuff.id.value}) }}">Delete Awesome Stuff</a>
We could stop there, but I just can't get enough Awesome Stuff. What I want now is to help my dear users to find their way back to what ever page introduced them to such Awesome Stuff. For those familiar, that would be done by appending the 'destination' parameter to my links.
Since, I just want the user to go back to the original page, I want to pass that path into the destination. For that, I can use:
{{ path('<current>') }}
Now my links are:
<!-- View -->
<a href="{{ path('entity.cool_entity.canonical', {'cool_entity': awesome_stuff.id.value, 'destination': path('<current>')}) }}">View Awesome Stuff</a>
<!-- Edit -->
<a href="{{ path('entity.cool_entity.edit_form', {'cool_entity': awesome_stuff.id.value, 'destination': path('<current>')}) }}">Edit Awesome Stuff</a>
<!-- Delete -->
<a href="{{ path('entity.cool_entity.delete_form', {'cool_entity': awesome_stuff.id.value, 'destination': path('<current>')}) }}">Delete Awesome Stuff</a>
<!-- Add -->
<a href="{{ path('eck.entity.add', {'eck_entity_type': 'cool_entity', 'eck_entity_bundle': 'awesome_stuff', 'destination': path('<current>')}) }}">Add Awesome Stuff</a>
And it looks so simple now. Hopefully this will save somebody some time ( including myself when I completely forget it ).