¿Cómo puedo controlar la visibilidad del bloque con el código?

11

En Drupal 6, pude controlar la visibilidad del bloque usando el código PHP en la configuración de la interfaz de usuario del bloque como:

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

Estas funciones buscaron el nodo actual, la taxonomía, etc. para decidir si mostrar el bloque. Esta opción PHP desapareció en Drupal 8, pero hay un $visibilitycampo en BlockBase. ¿Puedo usar esto para establecer programáticamente la visibilidad en tiempo de ejecución?

Nic
fuente
1
En su lugar, debe declarar un complemento de condición personalizada. Busque el núcleo de @Condition para encontrar ejemplos de trabajo.
Eyal
En general, escribir código PHP en la base de datos es una mala práctica y se debe evitar tanto como sea posible.
Eyal
El módulo de filtro php se ha eliminado de D8. En general, es una mala idea usar php ingresado en la interfaz de usuario y ejecutado de esta manera. Es una mala idea porque falta un; podría paralizar un sitio entero y luego seré contratado para buscar en el DB para encontrar los desaparecidos; Esto ha sucedido,
Frank Robert Anderson
¡Convenido! Se movió tanto código como pude al módulo, ¡y me alegra poder hacerlo con código puro en D8!
Nic

Respuestas:

15

Un fragmento de código de trabajo sobre cómo usarlo hook_block_access(). Aquí recupero la condición de un campo del nodo actual:

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

Gracias @Insasse por compartir la siguiente joya en los comentarios. Para bloques personalizados creados mediante programación, puede controlar la visibilidad directamente desde dentro de la clase de bloque a travé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');
  }

}

Fuente: Cómo crear un bloque mediante programación en Drupal 8

leymannx
fuente
1
Incluso podría escribir la verificación de acceso en su clase de bloque -> webwash.net/programmatic-create-block-drupal-8
Insasse
7

Al carecer del filtro php en Drupal 8, esto ya no será posible desde la interfaz de usuario.

La única opción es usar la api de bloque.

hook_block_access es tu mejor canidate. Desde allí puede verificar $operationy devolver un AccessResult según sus condiciones.

Al igual que en la interfaz de usuario solo esta vez colocando el php en un módulo.

Frank Robert Anderson
fuente
4

Aquí está la solución Drupal 8: Bloquear Excluir páginas .

Este módulo agrega un filtro de exclusión de páginas para bloques.

Para excluir páginas específicas después del comodín o entre comodines, simplemente prefije el patrón de ruta con el prefijo '!' en la configuración de visibilidad de la página de bloqueo.

Esto funciona para la visibilidad establecida en "mostrar para las páginas enumeradas", en este caso, las rutas de exclusión ocultarán el bloque en las páginas que coincidan a pesar del comodín configurado para mostrar.

O al revés, si la lista de páginas está configurada para "ocultar las páginas enumeradas", las rutas excluidas mostrarán el bloque en las páginas donde el patrón coincide a pesar del comodín configurado para ocultar.

Block Exclude Pages screenshot

Juyal Jee
fuente
1

Para ampliar las posibilidades de visibilidad del bloque, puede probar este parche:

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

introduce el operador de conjunción AND / OR para las condiciones de visibilidad para que pueda decir oh, quiero que este bloque sea visible si es de my_content_type O el usuario tiene un rol de administrador O la url comienza con mi / ruta / a / * etc. también las condiciones podría negarse para que pueda establecer muchas condiciones en las que no desea que su bloque sea visible

Además, si usa el módulo Drupal Commerce, puede probar lo anterior instalando el https://www.drupal.org/project/commerce_quick_purchase , tenga en cuenta que al instalar el módulo, se expone esta funcionalidad para todos los bloques del sistema, incluso si no lo hace ' t use el bloque provisto por el módulo ver más

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

adicionalmente puede crear su propio complemento de condición, ver ejemplo del módulo

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

drogo
fuente