Question

I've setup my controller like this:

my_controller:
  path: '/controller/{id}'
  defaults:
    _controller: '\Drupal\Mymodule\Controller\MyController::Render'
    _title_callback: '\Drupal\Mymodule\Controller\MyController::getTitle'
  requirements:
    permission: 'access content'

Now, in my MyController.php I need to load an entity object (for which {id} is the id). Unfortunately, it seems I need to load my object twice. First, in my getTitle function because this is called first. Then again in my Render() function, which is called afterwards.

When I try to save the entity to my class as $this->entity It gets lost when the Render() function gets called. I tried to load via a constructor or create function, but these do not have access to the {id} slug in a proper manner.

What's the good practice way to make sure I need to load my entity object once for both functions?

Was it helpful?

Solution

When I try to save the entity to my class as $this->entity It gets lost when the Render() function gets called.

Use a service. Services are singletons and when the class resolver finds an existing service it loads the instance from the container and doesn't create a new class instance:

defaults:
  _controller: 'my_service:render'
  _title_callback: 'my_service:getTitle'

For good practice this is not really necessary in this case because entities are cached in memory automatically and loading an entity twice doesn't have a performance impact.

Good practice, though, would be to load the entity via route parameter upcasting:

foobar.view:
  path: '/foobar/{foobar_placeholder}'
  defaults:
    _controller: '\Drupal\foobar\Controller\Foobar::content'
    _title: 'Oh yeah foobar'
  options:
    parameters:
      foobar_placeholder:
        type: entity:foobar

Example from https://www.drupal.org/docs/8/api/routing-system/parameters-in-routes/parameter-upcasting-in-routes

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top