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 "group" for route "view.group_nodes.page_1" must match "[^/]++" ("" given) to generate a corresponding URL. in <em class="placeholder">Drupal\Core\Routing\UrlGenerator->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->getInternalPathFromRoute('view.group_nodes.page_1', Object, Array, Array) (Line: 293)
Drupal\Core\Routing\UrlGenerator->generateFromRoute('view.group_nodes.page_1', Array, Array, 1) (Line: 105)
Drupal\Core\Render\MetadataBubblingUrlGenerator->generateFromRoute('view.group_nodes.page_1', Array, Array, ) (Line: 753)
Drupal\Core\Url->toString() (Line: 116)
Drupal\views\Form\ViewsExposedForm->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 518)
Drupal\Core\Form\FormBuilder->retrieveForm('views_exposed_form', Object) (Line: 275)
Drupal\Core\Form\FormBuilder->buildForm('views_exposed_form', Object) (Line: 135)
Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase->renderExposedForm() (Line: 1238)
Drupal\views\ViewExecutable->build(NULL) (Line: 1391)
Drupal\views\ViewExecutable->execute(NULL) (Line: 1454)
Drupal\views\ViewExecutable->render() (Line: 130)
Drupal\views\Plugin\views\display\Block->execute() (Line: 1630)
Drupal\views\ViewExecutable->executeDisplay('block_1', Array) (Line: 77)
Drupal\views\Element\View::preRenderViewElement(Array) (Line: 59)
Drupal\views\Plugin\Block\ViewsBlock->build() (Line: 203)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func('Drupal\block\BlockViewBuilder::preRender', Array) (Line: 378)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 450)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 490)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 381)
__TwigTemplate_28fe6842aea943d14e05f87352680cceec7631b2c18fb7b37ccfc36cf3662b95->block_main_content(Array, Array) (Line: 215)
Twig_Template->displayBlock('main_content', Array, Array) (Line: 343)
__TwigTemplate_28fe6842aea943d14e05f87352680cceec7631b2c18fb7b37ccfc36cf3662b95->block_main(Array, Array) (Line: 215)
Twig_Template->displayBlock('main', Array, Array) (Line: 63)
__TwigTemplate_28fe6842aea943d14e05f87352680cceec7631b2c18fb7b37ccfc36cf3662b95->doDisplay(Array, Array) (Line: 428)
Twig_Template->displayWithErrorHandling(Array, Array) (Line: 399)
Twig_Template->display(Array, Array) (Line: 53)
__TwigTemplate_351c2bfaf5956f1b479a5459a3c4492cd8da44c749c920da42e38c16c8105ce4->doDisplay(Array, Array) (Line: 428)
Twig_Template->displayWithErrorHandling(Array, Array) (Line: 399)
Twig_Template->display(Array) (Line: 407)
Twig_Template->render(Array) (Line: 64)
twig_render_template('themes/contrib/enzian/src/templates/system/page--group.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('page', Array) (Line: 437)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 490)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 90)
__TwigTemplate_3036dce8e2fed09048841cd9f0ea8d7388ee0b06b90e81e2cb8f2997503037cf->doDisplay(Array, Array) (Line: 428)
Twig_Template->displayWithErrorHandling(Array, Array) (Line: 399)
Twig_Template->display(Array) (Line: 407)
Twig_Template->render(Array) (Line: 64)
twig_render_template('themes/contrib/enzian/src/templates/system/html.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('html', Array) (Line: 437)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 147)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 148)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->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
| Comment | File | Size | Author |
|---|---|---|---|
| #8 | 3046311-8.patch | 2.61 KB | shreyakaushik11 |
| #6 | interdiff-2-3.txt | 822 bytes | thalles |
| #3 | ctools-3046311-3-WSOD-rendering-block.patch | 2.2 KB | andrey.troeglazov |
| #2 | ctools-3046311-2-WSOD-rendering-block.patch | 2.74 KB | geek-merlin |
Issue fork ctools-3046311
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
Comment #2
geek-merlinPatch flying in that implements the proposed resolution.
The patch fixes the WSOD for me and i could not see drawbacks.
Let's ask testbot.
Comment #3
andrey.troeglazov commentedI have removed some useless comments
Comment #4
geek-merlin> useless comments
I disagree. But that's up to the maintainer.
Comment #5
andrey.troeglazov commentedWhy?
// Nothing to do here.
If method is empty its obvious that nothing to do here, no? :)
Comment #6
thallesFollow a interdiff #2 - #3
Comment #7
chris matthews commentedThe 2 year old patch in #2 needs a reroll.
Comment #8
shreyakaushik11 commentedI've rerolled the patch mentioned in #2.
Please review.
Comment #9
anruetherI can't reproduce this on ctools 4.0.4 anymore
Comment #11
drupgirl commentedWSOD is preventing the upgrade to ctools 4.1.0. The patch needs a reroll for 3.15 and/or 4.1.0.