0

I'm trying to alter a contrib module controller's output via KernelEvents::VIEW. I want to display the output from the controller and append the markup returned from the event handler. This is the code I am using, but it doesn't work as expected.

class BuildAlter implements EventSubscriberInterface {

  public function alterBuild(ViewEvent $event) {
    $build = $event->getControllerResult();
    $build['content'] = [
      '#type' => 'markup',
      '#markup' => '<p>Added by ControllerAlterSubscriber.</p>'
    ];

    $event->setControllerResult($build);
  }

  public static function getSubscribedEvents() {
    return [
      // The VIEW event occurs when the return value of a controller
      // is not a Response instance.
      KernelEvents::VIEW => ['alterBuild', 50],
    ];
  }

}
7
  • 1
    You need to register the service in *.services.yml. See drupal.stackexchange.com/questions/281093/…
    – 4uk4
    Aug 9, 2021 at 8:04
  • The problem, the $build['content'] is not referenced in the main twig I wan to alter, see below how content is output in twig. {{ last_checked }} {% for project_type in project_types %} <h3>{{ project_type.label }}</h3> {{ project_type.table }} {% else %} <p>{{ no_updates_message }}</p> {% endfor %} ` Should I open an issue to output $build['content'] for that twig file, so other event listeners can alter/add the output via the 'content' key? I'm lost.
    – Nicholas
    Aug 9, 2021 at 8:23
  • 1
    Should I open an issue I don't think that would be appropriate, there's nothing in convention or best practice to say a 'content' variable has to be used for a Twig template. Perhaps you could think about altering the route instead and building your own view based on the original plus your changes?
    – Clive
    Aug 9, 2021 at 8:42
  • 1
    The ViewEvent class is only available on Drupal 9. On Drupal 8, the class to use is GetResponseForControllerResultEvent. Drupal core code doesn't help much in understanding how to implement that event handler. None of the event handlers implemented by Drupal core uses setControllerResult().
    – apaderno
    Aug 9, 2021 at 14:30
  • 1
    Looking at the Drupal core code used for that type of event handler, I can only understand the event handler should not assume the value returned from $event->getControllerResult() is an array. RenderArrayNonHtmlSubscriber::onRespond() and MainContentViewSubscriber::onViewRenderArray() check the value returned is an array, and assume it's a render array. PsrResponseSubscriber::onKernelView() checks the value returned implements ResponseInterface.
    – apaderno
    Aug 9, 2021 at 14:44

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.