1

For a custom entity I have created several dynamic blocks. But the blocks are not displayed. They are placed in admin/structure/block. Below is an example of block 1.

myentity.routing.yml:

myentity.blocks:
  path: '/collection/{myentity}'
  defaults:
    _title: 'Stuff collection'
  requirements:
    _permission: 'access content'
    myentity: \d+
  options:
    parameters:
      myentity:
        type: entity:myentity
        bundle:
            - a

Part of src/Plugin/Block:

namespace DrupalCorePluginBlock;

use DrupalCoreBlockBase;

/**
 * Provides a 'Collection' block.
 *
 * @Block(
 *   id = "collection_block 1",
 *   admin_label = @Translation("Collection: Stuff"),
 *   category = @Translation("My Collection"),
 *   context_definitions = {
 *     "myentity" = @ContextDefinition("entity:myentity", label = @Translation("Myentity ID"))
 *   }
 * )
 */
class MyentityBlock1 extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $myentity = $this->getContextValue('myentity');
    return [...];
}

If I replace myentity with node, it works, but for a custom entity I probably need to define something more. But what?

1
  • Maybe this: $myentity = \Drupal::service('current_route_match')->getParameter('myentity');
    – Jaypan
    May 31, 2022 at 15:18

1 Answer 1

3

You can follow Providing global context variables. You have to create a new service to provide a context variable for your custom entity. You can use some entity node, user, taxonomy_term... because them already define.

https://git.drupalcode.org/project/drupal/-/blob/9.3.x/core/modules/taxonomy/taxonomy.services.yml#L7

  taxonomy_term.taxonomy_term_route_context:
      class: Drupal\taxonomy\ContextProvider\TermRouteContext
      arguments: ['@current_route_match']
      tags:
        - { name: 'context_provider' }

https://git.drupalcode.org/project/drupal/-/blob/9.3.x/core/modules/taxonomy/src/ContextProvider/TermRouteContext.php#L48

 /**
   * {@inheritdoc}
   */
  public function getRuntimeContexts(array $unqualified_context_ids) {
    $result = [];
    $context_definition = EntityContextDefinition::create('taxonomy_term')->setRequired(FALSE);
    $value = NULL;
    if ($route_object = $this->routeMatch->getRouteObject()) {
      $route_parameters = $route_object->getOption('parameters');

      if (isset($route_parameters['taxonomy_term']) && $term = $this->routeMatch->getParameter('taxonomy_term')) {
        $value = $term;
      }
      elseif ($this->routeMatch->getRouteName() == 'entity.taxonomy_term.add_form') {
        $vocabulary = $this->routeMatch->getParameter('taxonomy_vocabulary');
        $value = Term::create(['vid' => $vocabulary->id()]);
      }
    }

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

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

    return $result;
  }
1
  • 1
    Thanks for your help. With the taxonomy example, I was able to quickly add the missing code.
    – PROMES
    Jun 5, 2022 at 12:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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