I'm actually using D9 to build a system with entities using sub-entities.
The main entity system use the following path : /item/{item}
Each sub entity is related to a main entity and use this path : /item/{item}/sub_item/{sub_item}
So to access the edit or delete form, the following pathes are required :
/item/{item}/sub_item/{sub_item}/edit
/item/{item}/sub_item/{sub_item}/delete
For example : /item/1/sub_item/4/edit
I declared the following route :
entity.sub_item.edit_form:
path: '/item/{item}/sub_item/{sub_item}/edit'
defaults:
_entity_form: 'sub_item.edit'
_title: 'Edit sub item'
options:
_admin_route: TRUE
parameters:
item:
type: entity:item
with_config_overrides: TRUE
sub_item:
type: entity:sub_item
with_config_overrides: TRUE
requirements:
_permission: 'administer site configuration'
Edit and Delete links are generated by list builder from getOperations. The list builder is on the following route : /item/1/sub_items (this is the "collection" to show the sub-items attached to main item).
I was hoping that the fact the current URL contained item/{item} can be directly re-used by the link generator, but it's not the fact...
Symfony\Component\Routing\Exception\MissingMandatoryParametersException : Some mandatory parameters are missing ("item") to generate a URL for route "entity.sub_item.edit_form". in Drupal\Core\Routing\UrlGenerator->doGenerate() (line 181 of /core/lib/Drupal/Core/Routing/UrlGenerator.php).
I tried to build a specific htmlRouteProvider class for my sub-item entity class but in this case too, the routes are built when cache are cleared, and I don't have access to the item in the URL to set it...
So... My question is : I'm missing something to do it easily, or must I re-implement the "toUrl()" method of my sub-item entity class to include the new "item" parameter "on the fly" ?
Thanks in advance for any suggestion.
PS : it's the solution I have actually in my sub-item entity class :
public function toUrl($rel = 'canonical', array $options = []) {
$uri = parent::toUrl($rel, $options);
$uri->setRouteParameter('item', \Drupal::routeMatch()->getRawParameter('item'));
return $uri;
}
But maybe a better solution can be found ?