Problem/Motivation

How to prepare
* create a view
* create a page display with a parametrized route like /group/%group/nodes
* create a block display
* place the block display to be shown on said page

How to reproduce
* request a said page (here eg group/17/nodes)

Get a WSOD like this. Uninstall ctools, the WSOD is NOT there.

The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Symfony\Component\Routing\Exception\InvalidParameterException</em>: 
Parameter &quot;group&quot; for route &quot;view.group_nodes.page_1&quot; must match &quot;[^/]++&quot; (&quot;&quot; given) to generate a corresponding URL. in <em class="placeholder">Drupal\Core\Routing\UrlGenerator-&gt;doGenerate()</em> (line <em class="placeholder">204</em> of <em class="placeholder">core/lib/Drupal/Core/Routing/UrlGenerator.php</em>). <pre class="backtrace">Drupal\Core\Routing\UrlGenerator-&gt;getInternalPathFromRoute(&#039;view.group_nodes.page_1&#039;, Object, Array, Array) (Line: 293)
Drupal\Core\Routing\UrlGenerator-&gt;generateFromRoute(&#039;view.group_nodes.page_1&#039;, Array, Array, 1) (Line: 105)
Drupal\Core\Render\MetadataBubblingUrlGenerator-&gt;generateFromRoute(&#039;view.group_nodes.page_1&#039;, Array, Array, ) (Line: 753)
Drupal\Core\Url-&gt;toString() (Line: 116)
Drupal\views\Form\ViewsExposedForm-&gt;buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 518)
Drupal\Core\Form\FormBuilder-&gt;retrieveForm(&#039;views_exposed_form&#039;, Object) (Line: 275)
Drupal\Core\Form\FormBuilder-&gt;buildForm(&#039;views_exposed_form&#039;, Object) (Line: 135)
Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase-&gt;renderExposedForm() (Line: 1238)
Drupal\views\ViewExecutable-&gt;build(NULL) (Line: 1391)
Drupal\views\ViewExecutable-&gt;execute(NULL) (Line: 1454)
Drupal\views\ViewExecutable-&gt;render() (Line: 130)
Drupal\views\Plugin\views\display\Block-&gt;execute() (Line: 1630)
Drupal\views\ViewExecutable-&gt;executeDisplay(&#039;block_1&#039;, Array) (Line: 77)
Drupal\views\Element\View::preRenderViewElement(Array) (Line: 59)
Drupal\views\Plugin\Block\ViewsBlock-&gt;build() (Line: 203)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func(&#039;Drupal\block\BlockViewBuilder::preRender&#039;, Array) (Line: 378)
Drupal\Core\Render\Renderer-&gt;doRender(Array) (Line: 450)
Drupal\Core\Render\Renderer-&gt;doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer-&gt;render(Array) (Line: 490)
Drupal\Core\Template\TwigExtension-&gt;escapeFilter(Object, Array, &#039;html&#039;, NULL, 1) (Line: 381)
__TwigTemplate_28fe6842aea943d14e05f87352680cceec7631b2c18fb7b37ccfc36cf3662b95-&gt;block_main_content(Array, Array) (Line: 215)
Twig_Template-&gt;displayBlock(&#039;main_content&#039;, Array, Array) (Line: 343)
__TwigTemplate_28fe6842aea943d14e05f87352680cceec7631b2c18fb7b37ccfc36cf3662b95-&gt;block_main(Array, Array) (Line: 215)
Twig_Template-&gt;displayBlock(&#039;main&#039;, Array, Array) (Line: 63)
__TwigTemplate_28fe6842aea943d14e05f87352680cceec7631b2c18fb7b37ccfc36cf3662b95-&gt;doDisplay(Array, Array) (Line: 428)
Twig_Template-&gt;displayWithErrorHandling(Array, Array) (Line: 399)
Twig_Template-&gt;display(Array, Array) (Line: 53)
__TwigTemplate_351c2bfaf5956f1b479a5459a3c4492cd8da44c749c920da42e38c16c8105ce4-&gt;doDisplay(Array, Array) (Line: 428)
Twig_Template-&gt;displayWithErrorHandling(Array, Array) (Line: 399)
Twig_Template-&gt;display(Array) (Line: 407)
Twig_Template-&gt;render(Array) (Line: 64)
twig_render_template(&#039;themes/contrib/enzian/src/templates/system/page--group.html.twig&#039;, Array) (Line: 384)
Drupal\Core\Theme\ThemeManager-&gt;render(&#039;page&#039;, Array) (Line: 437)
Drupal\Core\Render\Renderer-&gt;doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer-&gt;render(Array) (Line: 490)
Drupal\Core\Template\TwigExtension-&gt;escapeFilter(Object, Array, &#039;html&#039;, NULL, 1) (Line: 90)
__TwigTemplate_3036dce8e2fed09048841cd9f0ea8d7388ee0b06b90e81e2cb8f2997503037cf-&gt;doDisplay(Array, Array) (Line: 428)
Twig_Template-&gt;displayWithErrorHandling(Array, Array) (Line: 399)
Twig_Template-&gt;display(Array) (Line: 407)
Twig_Template-&gt;render(Array) (Line: 64)
twig_render_template(&#039;themes/contrib/enzian/src/templates/system/html.html.twig&#039;, Array) (Line: 384)
Drupal\Core\Theme\ThemeManager-&gt;render(&#039;html&#039;, Array) (Line: 437)
Drupal\Core\Render\Renderer-&gt;doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer-&gt;render(Array) (Line: 147)
Drupal\Core\Render\MainContent\HtmlRenderer-&gt;Drupal\Core\Render\MainContent\{closure}() (Line: 582)
Drupal\Core\Render\Renderer-&gt;executeInRenderContext(Object, Object) (Line: 148)
Drupal\Core\Render\MainContent\HtmlRenderer-&gt;renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber-&gt;onViewRenderArray(Object, &#039;kernel.view&#039;, Object)
call_user_func(Array, Object, &#039;kernel.view&#039;, Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher-&gt;dispatch(&#039;kernel.view&#039;, Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel-&gt;handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel-&gt;handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle-&gt;handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache-&gt;pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache-&gt;handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware-&gt;handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware-&gt;handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel-&gt;handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel-&gt;handle(Object) (Line: 19)
</pre>

Debugging

In our case, \Drupal\ctools_views\Plugin\Display\Block::usesExposed returns TRUE when core does not.

  /**
   * {@inheritdoc}
   */
  public function usesExposed() {
    $filters = $this->getHandlers('filter');
    foreach ($filters as $filter_name => $filter) {
      if ($filter->isExposed() && !empty($filter->exposedInfo())) {
        return TRUE;
      }
    }
    return FALSE;
  }

The comment in \Drupal\ctools_views\Plugin\Display\Block::elementPreRender gives some hint why.
Unfortunately, fixing here $view->exposed_widgets['#action'] is too late as above backtrace shows:
* \Drupal\views\Plugin\views\display\DisplayPluginBase::getLinkDisplay gives the first Display that has a route
* \Drupal\views\Form\ViewsExposedForm::buildForm does $view->getUrl()->toString() WSOD's on a missing parameter then.

  /**
   * Exposed widgets typically only work with ajax in Drupal core, however
   * #2605218 totally breaks the rest of the functionality in this display and
   * in Core's Block display as well, so we allow non-ajax block views to use
   * exposed filters and manually set the #action to the current request uri.
   */
  public function elementPreRender(array $element) {
    /** @var \Drupal\views\ViewExecutable $view */
    $view = $element['#view'];
    if (!empty($view->exposed_widgets['#action']) && !$view->ajaxEnabled()) {
      $view->exposed_widgets['#action'] = \Drupal::request()->getRequestUri();
    }
    return parent::elementPreRender($element);
  }

Proposed resolution

Implement \Drupal\views\Plugin\views\display\DisplayRouterInterface.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Issue fork ctools-3046311

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

axel.rutz created an issue. See original summary.

geek-merlin’s picture

Status: Active » Needs review
StatusFileSize
new2.74 KB

Patch flying in that implements the proposed resolution.
The patch fixes the WSOD for me and i could not see drawbacks.
Let's ask testbot.

andrey.troeglazov’s picture

I have removed some useless comments

geek-merlin’s picture

> useless comments

I disagree. But that's up to the maintainer.

andrey.troeglazov’s picture

Why?
// Nothing to do here.
If method is empty its obvious that nothing to do here, no? :)

thalles’s picture

StatusFileSize
new822 bytes

Follow a interdiff #2 - #3

chris matthews’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

The 2 year old patch in #2 needs a reroll.

shreyakaushik11’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new2.61 KB

I've rerolled the patch mentioned in #2.
Please review.

anruether’s picture

I can't reproduce this on ctools 4.0.4 anymore

suresh7787 made their first commit to this issue’s fork.

drupgirl’s picture

WSOD is preventing the upgrade to ctools 4.1.0. The patch needs a reroll for 3.15 and/or 4.1.0.