I am using Drupal 9. I want to give the ability to the admin to place a block and select from the block a taxonomy term in which will filter a content type.
I did the above by creating a custom block with the taxonomy "Sponsor Type" as you can see the screenshot bellow.
Also I use views_embed_view
to pass the taxonomy as an argument and filter the data using Contextual filters
Custom block code:
<?php
namespace Drupal\aek\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Provides a 'SponsorsBlock' block.
*
* @Block(
* id = "sponsors_block",
* admin_label = @Translation("Sponsors"),
* )
*/
class SponsorsBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
"max_items" => 5,
] + parent::defaultConfiguration();
}
public function blockForm($form, FormStateInterface $form_state) {
$sponsors = \Drupal::entityTypeManager()
->getStorage('taxonomy_term')
->loadTree("horigoi");
$sponsorsOptions = [];
foreach ($sponsors as $sponsor) {
$sponsorsOptions[$sponsor->tid] = $sponsor->name;
}
$form['sponsor_types'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Sponsor Type'),
'#description' => $this->t('Select from which sponsor type you want to get'),
'#options' => $sponsorsOptions,
'#default_value' => $this->configuration['sponsor_types'],
'#weight' => '0',
];
$form['max_items'] = [
'#type' => 'number',
'#title' => $this->t('Max items to display'),
'#description' => $this->t('Max Items'),
'#default_value' => $this->configuration['max_items'],
'#weight' => '0',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
$this->configuration['sponsor_types'] = $form_state->getValue('sponsor_types');
$this->configuration['max_items'] = $form_state->getValue('max_items');
}
/**
* {@inheritdoc}
*/
public function build() {
$selectedSponsorTypes = $this->configuration['sponsor_types'];
$cnxFilter = '';
foreach ($selectedSponsorTypes as $type) {
if ($type !== 0) {
$cnxFilter .= $type . ",";
}
}
return views_embed_view('embed_sponsors', 'default', $cnxFilter);
}
}
My issue now is how to limit the results. If you look above I have added an option "Max items to display" but using the Contextual filters I can't find any way to pass that argument to handle this.
If you use views_embed_view()
, you will not be able to access the view object.
Load your view manually then you can set any properties before executing it:
use Drupal\views\Views;
public function build() {
$selectedSponsorTypes = $this->configuration['sponsor_types'];
$cnxFilter = '';
foreach ($selectedSponsorTypes as $type) {
if ($type !== 0) {
$cnxFilter .= $type . ",";
}
}
$view = Views::getView('embed_sponsors');
$display_id = 'default';
$view->setDisplay($display_id);
$view->setArguments([$cnxFilter]);
$view->setItemsPerPage($this->configuration['max_items']);
$view->execute();
return $view->buildRenderable($display_id);
}