I have a View which returns 5 entities of the same type. AJAX - enabled, filters and exposed filters, all working fine.

I need to add a new result, a user - defined entity, at the top of the View results. This programmatically added row should not be affected when the exposed filters are used and should remain at the top of the View, on top of the other 5 returned results, no matter what.

I managed to add this with hook_views_post_execute() but when I use the exposed filters the View returns to its original results and my addition is lost, because AJAX is enabled on this View. hook_views_post_execute() doesn't seem to have any effect after the initial page load.

What is a good alternative for this scenario ie alter the View in a way that's not affected by the AJAX refresh?

  • In the UI you can embed a different view into the header area of your view. Wouldn't that work?
    – dxc
    Mar 25, 2020 at 22:45
  • Attachments and headers also disappear on AJAX refresh.
    – webmaniac
    Mar 25, 2020 at 22:51
  • Make views exposed form as block, make user result views as block. Place these blocks above of View with 5 entities. That's all...
    – Nikit
    Mar 25, 2020 at 23:25
  • @nikit the View structure needs to stay as is, not break it down into blocks as this will also create a huge need for theming changes. The required solution is to inject the one “independent of filters” entity between the filters and the dynamic results and make it unaffected by any change coming from the exposed filters.
    – webmaniac
    Mar 26, 2020 at 8:14
  • @webmaniac I don't think that's big problem for theming changes - exposed block and view will have one common classes. Also you can assign class in view settings. The same for users view.
    – Nikit
    Mar 26, 2020 at 11:46

1 Answer 1


When checking the current route match in a Views Ajax request you get the route of the Views Ajax endpoint views/ajax and not the route of the page where the View is placed on.

However, Ajax requests contain the original path of the View and ViewAjaxController::ajaxView() puts this path in the global current path stack (for the pager to work correctly).

So if the path is no longer in the request

$path = \Drupal::request()->request->get('view_path');

it should be transfered to:

$path = \Drupal::service('path.current')->getPath();

Which should then point to the node route you are looking for.

  • Unfortunatelly this returns /views/ajax. I think I'm getting somewhere with \Drupal::request()->server->get('HTTP_REFERER') and \Drupal::request()->getSchemeAndHttpHost().
    – webmaniac
    Mar 26, 2020 at 20:38
  • You can't rely on the refererer, not all clients provide one. If view_path is not transferred already to the current path it should still be present in the request.
    – 4uk4
    Mar 26, 2020 at 20:44
  • 4k4 can you elaborate please, I don't seem to get anythign in view_path.
    – webmaniac
    Mar 26, 2020 at 20:56
  • See the edited answer.
    – 4uk4
    Mar 26, 2020 at 21:20
  • \Drupal::service('path.current')->getPath(); still returns /views/ajax.
    – webmaniac
    Mar 26, 2020 at 21:26

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.