web-dev-qa-db-fra.com

Comment contrôler la visibilité des blocs avec du code?

Dans Drupal 6, je pouvais contrôler la visibilité des blocs en utilisant PHP code dans la configuration de l'interface utilisateur du bloc comme:

<?php return MYMODULE_abc() || MYMODULE_def() ; ?>

Ces fonctions ont recherché le nœud actuel, la taxonomie, etc. pour décider d'afficher ou non le bloc. Cette option PHP a disparu dans Drupal 8, mais il y a un $visibility champ dans BlockBase. Puis-je l'utiliser pour définir par programme la visibilité lors de l'exécution?

11
Nic

Un extrait de code de travail comment utiliser hook_block_access() . Ici, je récupère la condition à partir d'un champ du nœud actuel:

use Drupal\block\Entity\Block;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Drupal\Core\Access\AccessResult;

/**
 * Implements hook_block_access().
 */
function MYMODULE_block_access(Block $block, $operation, AccountInterface $account) {

  $node = \Drupal::routeMatch()->getParameter('node');

  $hero_image_exists = FALSE;

  if ($node instanceof NodeInterface) {
    if ($node->hasField('field_hero_image')) {
      if (!$node->get('field_hero_image')->isEmpty()) {
        $hero_image_exists = TRUE;
      }
    }
  }

  if ($operation == 'view' && $block->getPluginId() == 'MYBLOCK') {
    return AccessResult::forbiddenIf($hero_image_exists == FALSE)->addCacheableDependency($block);
  }

  return AccessResult::neutral();
}

Merci @Insasse d'avoir partagé le joyau suivant dans les commentaires. Pour les blocs personnalisés créés par programme, vous pouvez contrôler la visibilité directement depuis l'intérieur de la classe de bloc via blockAccess():

class MyBlock extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() {
    return [
      '#markup' => $this->t('This is a simple block!'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  protected function blockAccess(AccountInterface $account) {
    return AccessResult::allowedIfHasPermission($account, 'access content');
  }

}

Source: Comment créer par programme un bloc dans Drupal 8

16
leymannx

En l'absence de filtre php dans Drupal 8, cela ne sera plus possible depuis l'interface utilisateur.

La seule option est d'utiliser l'api de bloc.

hook_block_access est votre meilleur candidat. De là, vous pouvez vérifier le $operation et renvoyez un AccessResult en fonction de vos conditions.

Tout comme dans l'interface utilisateur, cette fois-ci, mettre le php dans un module.

6

Voici la solution Drupal 8: Block Exclude Pages .

Ce module ajoute un filtre d'exclusion de pages pour les blocs.

Pour exclure des pages spécifiques après le caractère générique ou entre les caractères génériques, il suffit de préfixer le modèle de chemin avec un "!" Préfixé dans la configuration de visibilité de la page de blocage.

Cela fonctionne pour la visibilité définie sur "afficher pour les pages répertoriées", dans ce cas, les chemins d'exclusion masqueront le bloc sur les pages qui correspondent malgré le caractère générique défini pour s'afficher.

Ou l'inverse, si la liste de pages est définie sur "masquer pour les pages répertoriées", les chemins exclus afficheront le bloc sur les pages où le modèle correspond malgré le caractère générique défini pour masquer.

Block Exclude Pages screenshot

4
Juyal Jee

Pour 8.2.x, vous devez créer un Condition Plugin et implémenter le - ContextProviderInterface.

Voir un exemple de D.O. mais il est en quelque sorte dépassé (car BlockEvent et BlockSubscriberBase supprimés en faveur d'un service de référentiel de contexte).

Il serait également agréable d'utiliser la console Drupal pour générer le plugin:

drupal generate:plugin:condition
3
TheodorosPloumis

pour étendre les possibilités de visibilité des blocs, vous pouvez essayer ce patch:

https://www.drupal.org/project/drupal/issues/923934#comment-1240136

il présente les [~ # ~] et [~ # ~] / [~ # ~] ou [~ # ~] opérateur de conjonction pour les conditions de visibilité afin que vous puissiez dire oh je veux que ce bloc soit visible s'il est de my_content_type [~ # ~] ou [~ # ~] l'utilisateur a un rôle d'administrateur [~ # ~] ou [~ # ~] l'url commence par mon/path/to/* etc .. également les conditions pourraient être annulées afin que vous puissiez définir un grand nombre de conditions auxquelles vous ne voulez pas que votre bloc soit visible

également si vous utilisez le module Drupal Commerce, vous pouvez essayer ce qui précède en installant le module https://www.drupal.org/project/commerce_quick_purchase qui est installé le module expose cette fonctionnalité pour tous les blocs du système même si vous n'utilisez pas le bloc fourni par le module voir plus

https://github.com/drugan/commerce_quick_purchase#block-visibility

en outre, vous pouvez créer votre propre plugin de condition voir l'exemple du module

https://cgit.drupalcode.org/commerce_quick_purchase/tree/src/Plugin/Condition

1
drugan