Being that Taxonomy Terms by default have a viewable page, it really surprised me to find that there's no condition to show blocks depending on which bundle (vocabulary) you're viewing, absolutely ludacris.
So naturally, I built one. Just here to thieve my code? Jump to the TL;DR at the bottom you dirty, dirty pirate ;p
First we create a Condition plugin, obviously we need a module for this, so if you're not familiar then kick rocks bro.
Let's start with my_module/src/Plugin/Condition/Vocabulary.php
php
<?php
namespace Drupal\my_module\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
/**
* Provides a Vocabulary condition.
*
* @Condition(
* id = "vocabulary",
* label = @Translation("Vocabulary"),
* )
*/
class Vocabulary extends ConditionPluginBase {
public function evaluate() {
// TODO: Implement evaluate() method.
}
public function summary() {
// TODO: Implement summary() method.
}
}
So as we can see from the initial method stubs, I need to provide a summary as well as Boolean of whether or not this condition is met, but wait.. don't I need to know what I'm evaluating? Fuck yea I do. We want the user to pick what vocabulary they want this condition to meet.
In comes the dependency injection, so we implement ContainerFactoryPluginInterface and get the entity type manager to load terms as well as the route matcher to get the current route's term.
php
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('current_route_match')
);
}Ok, great, but we still need someone to tell us what vocabularies we want to select. So lets add some configuration here. First add some default configuration, then a form and a submit handler to store the selections. You'll notice here I have an extra configuration for exclusiveness, this is so that if you are checking against non-term pages you have the option to allow or fail regardless.
php
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'bundles' => [],
'exclusive' => FALSE,
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$options = [];
/** @var \Drupal\taxonomy\VocabularyInterface[] $vocabularies */
$vocabularies = $this->entityTypeManager->getStorage('taxonomy_vocabulary')->loadMultiple();
foreach ($vocabularies as $vocabulary) {
$options[$vocabulary->id()] = $vocabulary->label();
}
$form['bundles'] = [
'#title' => $this->t('Vocabularies'),
'#type' => 'checkboxes',
'#options' => $options,
'#default_value' => $this->configuration['bundles'],
];
$form['exclusive'] = [
'#title' => $this->t('Exclusive'),
'#type' => 'checkbox',
'#description' => $this->t('If checked, this rule will negate non-taxonomy pages.'),
'#default_value' => $this->isExclusive(),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
$this->configuration['bundles'] = array_filter($form_state->getValue('bundles'));
$this->configuration['exclusive'] = $form_state->getValue('exclusive', FALSE);
}
/**
* Helper for exclusiveness.
*
* @return bool
* Whether or not this has been checked.
*/
protected function isExclusive() {
return isset($this->configuration['exclusive']) ? $this->configuration['exclusive'] : FALSE;
}No Let's evaluate the condition:
php
/**
* {@inheritdoc}
*/
public function evaluate() {
// Do nothing if nothing is checked.
if (empty($this->configuration['bundles']) && !$this->isNegated()) {
return TRUE;
}
/** @var \Drupal\taxonomy\TermInterface $term */
$term = \Drupal::routeMatch()->getParameter('taxonomy_term');
if (is_scalar($term)) {
$term = $this->entityTypeManager->getStorage('taxonomy_term')->load($term);
}
// No term.
if (!$term) {
// Ban hammer.
if ($this->isExclusive()) {
return FALSE;
}
// Negated or leave for other rules.
return !$this->isNegated();
}
// Normal check.
return !empty($this->configuration['bundles'][$term->bundle()]);
}TL;DR
Here's the full plugin:
Download