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

11

Dans Drupal 6, je pouvais contrôler la visibilité des blocs en utilisant du code PHP 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 $visibilitychamp dans BlockBase. Puis-je l'utiliser pour définir par programme la visibilité lors de l'exécution?

Nic
la source
1
Vous devez plutôt déclarer un plugin de condition personnalisée. Recherchez dans le noyau @Condition pour trouver des exemples de travail.
Eyal
Généralement, écrire du code PHP dans la base de données est une mauvaise pratique et il faut éviter autant que possible.
Eyal
Le module de filtrage php a été supprimé de D8. En général, c'est une mauvaise idée d'utiliser php entré dans l'interface utilisateur et exécuté de cette manière. C'est une mauvaise idée car il manque un; pourrait paralyser un site entier, puis je serai embauché pour rechercher le db pour trouver les disparus; C'est arrivé,
Frank Robert Anderson
D'accord! Est déplacé autant de code que possible dans le module, et heureux de pouvoir le faire avec du code pur en D8!
Nic

Réponses:

15

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

leymannx
la source
1
Vous pouvez même écrire le contrôle d'accès dans votre classe de bloc -> webwash.net/programmatically-create-block-drupal-8
Insasse
7

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

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

hook_block_access est votre meilleur candidat. De là, vous pouvez vérifier $operationet renvoyer un AccessResult en fonction de vos conditions.

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

Frank Robert Anderson
la source
4

Voici la solution Drupal 8: Bloquer les pages d'exclusion .

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

Juyal Jee
la source
1

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

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

il introduit l' opérateur de conjonction ET / OU pour les conditions de visibilité afin que vous puissiez dire oh je veux que ce bloc soit visible s'il est de mon_contenu_type OU l' utilisateur a le rôle d'administrateur OU l'url commence par mon / chemin / vers / * etc .. aussi les conditions pourrait être annulé 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 notez qu'être installé le module expose cette fonctionnalité pour tous les blocs du système même si vous ne le faites pas '' t utiliser 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

drugan
la source