Problem/Motivation
I was working on a project customization that allowed users to manually select from a given list of taxonomy terms as arguments. This way, they could handpick a term instead of having to know the ID or depend on the context.
The problem is that any prepopulated value on the view arguments will be erased by the following code on Drupal\views\Plugin\Block\ViewsBlock::build():
public function build() {
$this->view->display_handler->preBlockBuild($this);
// AT THIS POINT; MY VIEW->ARGS MIGHT HAVE BEEN ALREADY SET MANUALLY BY THE USER
$args = []; <---- ARGS IS RESET
foreach ($this->view->display_handler->getHandlers('argument') as $argument_name => $argument) {
// TRIES TO POPULATE $ARGS FROM THE CONTEXT
}
// We ask ViewExecutable::buildRenderable() to avoid creating a render cache
// entry for the view output by passing FALSE, because we're going to cache
// the whole block instead.
if ($output = $this->view->buildRenderable($this->displayID, array_values($args), FALSE)) {
// USES $ARGS FOR RENDERING THE VIEW
(...)
return $output;
}
return [];
}
Since the output is generated using $this->view->buildRenderable($this->displayID, array_values($args), FALSE)
, any preexisting value for $this->view->args
won't be taken into consideration.
Proposed resolution
We could account for the rare, but possible scenario where the $args have been already programmatically setted, same as items_per_page or other exposed settings.
This could be done by defaulting $args
not to an empty array but as the current value from $this->view->args
(wich 99% of the time will be an empty array, nonetheless):
$args = $this->view->args;
This will also ensure that we don't break the arguments loaded from context, as they will override this default value if present.