Wie kann ich die Blocksichtbarkeit mit Code steuern?

11

In Drupal 6 konnte ich die Blocksichtbarkeit mithilfe von PHP-Code in der Block-UI-Konfiguration wie folgt steuern:

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

Diese Funktionen haben den aktuellen Knoten, die Taxonomie usw. nachgeschlagen, um zu entscheiden, ob der Block angezeigt werden soll. Diese PHP-Option ist in Drupal 8 weg, aber es gibt ein $visibilityFeld in BlockBase. Kann ich damit die Sichtbarkeit zur Laufzeit programmgesteuert einstellen?

Nic
quelle
1
Sie sollten stattdessen ein benutzerdefiniertes Bedingungs-Plugin deklarieren. Durchsuchen Sie den Kern nach @Condition, um Arbeitsbeispiele zu finden.
Eyal
Im Allgemeinen ist das Schreiben von PHP-Code in die Datenbank eine schlechte Praxis und es sollte so weit wie möglich vermieden werden.
Eyal
Das PHP-Filtermodul wurde aus D8 entfernt. Im Allgemeinen ist es eine schlechte Idee, PHP zu verwenden, das in die Benutzeroberfläche eingegeben und auf diese Weise ausgeführt wird. Es ist eine schlechte Idee, weil ein fehlt; könnte eine ganze Site lähmen und dann werde ich beauftragt, die Datenbank zu durchsuchen, um die vermissten zu finden; Dies ist passiert,
Frank Robert Anderson
Einverstanden! Wird so viel Code wie möglich in das Modul verschoben und ich bin froh, dass ich dies mit reinem Code in D8 tun kann!
Nic

Antworten:

16

Ein Arbeitscode-Snippet zur Verwendung hook_block_access(). Hier rufe ich die Bedingung aus einem Feld des aktuellen Knotens ab:

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();
}

Vielen Dank an @Insasse, dass Sie das folgende Juwel in den Kommentaren geteilt haben. Bei programmgesteuert erstellten benutzerdefinierten Blöcken können Sie die Sichtbarkeit direkt innerhalb der Blockklasse steuern über 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');
  }

}

Quelle: So erstellen Sie programmgesteuert einen Block in Drupal 8

Leymannx
quelle
1
Sie können sogar die Zugriffsprüfung in Ihre Blockklasse schreiben -> webwash.net/programmatisch-create-block-drupal-8
Insasse
6

Ohne den PHP-Filter in Drupal 8 ist dies über die Benutzeroberfläche nicht mehr möglich.

Die einzige Möglichkeit ist die Verwendung der Block-API.

hook_block_access ist dein bester Kandidat. Von dort aus können Sie das überprüfen $operationund ein AccessResult basierend auf Ihren Bedingungen zurückgeben.

Genau wie in der Benutzeroberfläche nur diesmal das PHP in ein Modul setzen.

Frank Robert Anderson
quelle
4

Hier ist die Drupal 8-Lösung: Block Exclude Pages .

Dieses Modul fügt einen Ausschlussseitenfilter für Blöcke hinzu.

Um bestimmte Seiten nach dem Platzhalter oder zwischen Platzhaltern auszuschließen, stellen Sie dem Pfadmuster einfach das Präfix '!' Vor. in der Konfiguration der Sichtbarkeit der Blockseite.

Dies funktioniert für die Sichtbarkeit, die auf "Für die aufgelisteten Seiten anzeigen" eingestellt ist. In diesem Fall wird durch die Ausschlusspfade der Block auf Seiten ausgeblendet, die trotz des angezeigten Platzhalters mit dem übereinstimmen.

Oder umgekehrt: Wenn die Seitenliste auf "Für die aufgelisteten Seiten ausblenden" eingestellt ist, zeigen die ausgeschlossenen Pfade den Block auf Seiten an, auf denen das Muster übereinstimmt, obwohl der Platzhalter ausgeblendet ist.

Block Exclude Pages screenshot

Juyal Jee
quelle
1

Um die Möglichkeiten der Blocksichtbarkeit zu erweitern, können Sie diesen Patch ausprobieren:

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

Es wird der AND / OR- Konjunktionsoperator für die Sichtbarkeitsbedingungen eingeführt, sodass Sie sagen können, dass dieser Block sichtbar sein soll, wenn er vom Typ my_content_type ist ODER der Benutzer eine Administratorrolle hat ODER die URL mit meinem / path / to / * etc beginnt. Auch die Bedingungen könnte negiert werden, so dass Sie viele Bedingungen festlegen können, unter denen Ihr Block nicht sichtbar sein soll

Wenn Sie das Drupal Commerce-Modul verwenden, können Sie dies auch versuchen, indem Sie das Modul https://www.drupal.org/project/commerce_quick_purchase installieren. Beachten Sie, dass bei der Installation des Moduls diese Funktionalität für alle Blöcke auf dem System verfügbar ist, auch wenn Sie dies nicht tun. t Verwenden Sie den vom Modul bereitgestellten Block. Weitere Informationen finden Sie hier

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

Zusätzlich können Sie Ihr eigenes Zustands-Plugin erstellen, siehe Beispiel aus dem Modul

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

Drugan
quelle