2

When on a node, the following annotation will obtain the node from the context:

/**
 * @Condition(
 *   id = "node_type",
 *   label = @Translation("Node Bundle"),
 *   context = {
 *     "node" = @ContextDefinition("entity:node", label = @Translation("Node"))
 *   }
 * )
 */

As shown here: https://www.drupal.org/docs/8/api/plugin-api/plugin-contexts

Is there an equivalent way to do this with taxonomy terms when on /taxonomy/term/%?

The code below certainly works but I'm wondering if there is a cleaner method like for nodes. Note that I'm also aware of the Term::load($tid) method but that still requires parsing the URL to obtain the tid and isn't portable (the code can be used only when run on a page).

  /**
   * Return current term.
   */
  public function getCurrentTerm() {
    $term = null;

    // Below we are using the general method to obtain the objects.
    // \Drupal\taxonomy\Entity\Term::load($tid) is the other

    // Get the unaliased path in the form /taxonomy/term/tid.
    $current_path = \Drupal::service('path.current')->getPath();

    preg_match('/\/taxonomy\/term\/\d+/', $current_path, $matches);

    // Return null if not in proper form.
    if (count($matches)) {
      // Find the parameters for this route.
      $params = \Drupal\Core\Url::fromUri("internal:" . $current_path)
        ->getRouteParameters();

      // Fetch the taxonomy object.
      $entity_type = key($params);
      $term = \Drupal::entityTypeManager()
        ->getStorage($entity_type)
        ->load($params[$entity_type]);
    }

    return $term;
  }
}
  • 2
    You can replace the code example with $term = \Drupal::routeMatch()->getParameter('taxonomy_term') – 4k4 May 5 '17 at 19:35
  • 1
    The question is a little confusing. The first annotation you are showing is for a condition, which isn't used when viewing a node, but rather when defining a condition used for a block. What exactly are you trying to achieve? – kiamlaluno May 5 '17 at 20:42
  • I was just using that as an example. Your answer was perfect, thank you. – André May 5 '17 at 23:53
  • Sorry didn't realize the question was from you, kiamlaluno. – André May 6 '17 at 0:14
1

Update 10.05.2019:

There is an unresolved issue about that on drupal.org: Term route context.

It uses the same solution as in my answer below.

Original answer:

You can create a custom context provider "Taxonomy term from URL".

service definition in MYMODULE.services.yml:

  MYMODULE.taxonomy_term_context:
    class: Drupal\MYMODULE\ContextProvider\TaxonomyTermContext
    arguments: ['@current_route_match']
    tags:
      - { name: 'context_provider' }

The /src/ContextProvider/TaxonomyTermContext.php

<?php

namespace Drupal\MYMODULE\ContextProvider;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextProviderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Sets the current taxonomy term as a context on taxonomy term routes.
 */
class TaxonomyTermContext implements ContextProviderInterface {

  use StringTranslationTrait;

  /**
   * The route match object.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * Constructs a new object.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match object.
   */
  public function __construct(RouteMatchInterface $route_match) {
    $this->routeMatch = $route_match;
  }

  /**
   * {@inheritdoc}
   */
  public function getRuntimeContexts(array $unqualified_context_ids) {
    $result = [];
    $context_definition = new ContextDefinition('entity:taxonomy_term', $this->t('Taxonomy term from URL'));
    $value = NULL;
    if (
      ($route_object = $this->routeMatch->getRouteObject())
      && ($route_contexts = $route_object->getOption('parameters'))
      && isset($route_contexts['taxonomy_term'])
    ) {
      if ($term = $this->routeMatch->getParameter('taxonomy_term')) {
        $value = $term;
      }
    }

    $cacheability = new CacheableMetadata();
    $cacheability->setCacheContexts(['route']);

    $context = new Context($context_definition, $value);
    $context->addCacheableDependency($cacheability);
    $result['taxonomy_term'] = $context;

    return $result;
  }

  /**
   * {@inheritdoc}
   */
  public function getAvailableContexts() {
    $context = new Context(new ContextDefinition('entity:taxonomy_term', $this->t('Taxonomy term from URL')));
    return ['taxonomy_term' => $context];
  }

}

The ctools module provides already the condition plugin for entity bundles:ctools/src/Plugin/Condition/EntityBundle.php. You can use it together with the new service.

See also config block visibility by vocabulary, but it not show block access fail(miss context).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.