Como posso controlar a visibilidade do bloco com o código?

11

No Drupal 6, eu podia controlar a visibilidade do bloco usando o código PHP na configuração da interface do usuário do bloco, como:

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

Essas funções procuraram o nó atual, taxonomia etc. para decidir se o bloco seria exibido. Esta opção do PHP desapareceu no Drupal 8, mas há um $visibilitycampo no BlockBase. Posso usar isso para definir programaticamente a visibilidade em tempo de execução?

Nic
fonte
11
Você deve declarar um plug-in de condição personalizado. Pesquise o @Condition no núcleo para encontrar exemplos de trabalho.
Eyal
Geralmente, escrever código PHP no banco de dados é uma prática ruim e evitar o máximo possível.
Eyal
O módulo de filtro php foi removido do D8. Em geral, é uma má idéia usar o php digitado na interface do usuário e executado dessa maneira. É uma péssima ideia porque falta um; poderia aleijar um site inteiro e depois serei contratado para pesquisar no banco de dados para encontrar os desaparecidos; Isso aconteceu,
Frank Robert Anderson
Acordado! É movido o máximo de código possível para o módulo e feliz por poder fazer isso com código puro no D8!
Nic

Respostas:

15

Um trecho de código de trabalho como usar hook_block_access(). Aqui, recupero a condição de um campo do nó atual:

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

Obrigado @Insasse por compartilhar a seguinte jóia nos comentários. Para blocos personalizados criados por programação, você pode controlar a visibilidade diretamente de dentro da classe de blocos através de 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');
  }

}

Fonte: Como criar programaticamente um bloco no Drupal 8

leymannx
fonte
11
Você pode até escrever a verificação de acesso em sua classe bloco -> webwash.net/programmatically-create-block-drupal-8
Insasse
7

Na falta do filtro php no Drupal 8, isso não será mais possível na interface do usuário.

A única opção é usar a API do bloco.

hook_block_access é o seu melhor candidato. A partir daí, você pode verificar $operatione devolver um AccessResult com base em suas condições.

Assim como na interface do usuário, apenas desta vez colocando o php em um módulo.

Frank Robert Anderson
fonte
4

Aqui está a solução Drupal 8: Bloquear páginas de exclusão .

Este módulo adiciona um filtro de páginas de exclusão para blocos.

Para excluir páginas específicas após o curinga ou entre curingas, basta prefixar o padrão do caminho com um '!' na configuração de visibilidade da página de bloqueio.

Isso funciona para a visibilidade definida como "mostrar para as páginas listadas"; nesse caso, os caminhos de exclusão ocultam o bloco nas páginas correspondentes, apesar do curinga definido para exibição.

Ou o contrário, se a lista de páginas estiver definida como "ocultar para as páginas listadas", os caminhos excluídos mostrarão o bloco nas páginas em que o padrão corresponde, apesar do curinga definido para ocultar.

Block Exclude Pages screenshot

Juyal Jee
fonte
1

Para ampliar as possibilidades de visibilidade do bloco, você pode tentar este patch:

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

ele introduz o operador de conjunção AND / OR para as condições de visibilidade, para que você possa dizer oh, eu quero esse bloco visível se for do my_content_type OU o usuário tem função administrativa OU o URL começa com meu / path / to / * etc. também as condições pode ser negado para que você possa definir muitas condições nas quais não deseja que seu bloco fique visível

Além disso, se você usar o módulo Drupal Commerce, poderá tentar o acima, instalando o módulo https://www.drupal.org/project/commerce_quick_purchase. Observe que a instalação do módulo expõe essa funcionalidade para todos os blocos do sistema, mesmo que você não t use o bloco fornecido pelo módulo veja mais

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

Além disso, você pode criar seu próprio plug-in de condição, veja o exemplo no módulo

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

drugan
fonte