Jak mogę kontrolować widoczność bloku za pomocą kodu?

11

W Drupal 6 mogłem kontrolować widoczność bloku za pomocą kodu PHP w konfiguracji interfejsu bloku, takiego jak:

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

Funkcje te sprawdzały bieżący węzeł, systematykę itp., Aby zdecydować, czy wyświetlić blok. Ta opcja PHP zniknęła w Drupal 8, ale jest $visibilitypole w BlockBase. Czy mogę tego użyć, aby programowo ustawić widoczność w czasie wykonywania?

Nic
źródło
1
Zamiast tego powinieneś zadeklarować niestandardową wtyczkę. Przeszukaj rdzeń dla @Condition, aby znaleźć działające przykłady.
Eyal
Zasadniczo pisanie kodu PHP w bazie danych jest złą praktyką i należy unikać w jak największym stopniu.
Eyal
Moduł filtra php został usunięty z D8. Ogólnie rzecz biorąc, złym pomysłem jest używanie php wprowadzonego do interfejsu użytkownika i wykonanego w ten sposób. Jest to zły pomysł, ponieważ brakuje; mogę sparaliżować całą witrynę, a następnie zostanę zatrudniony do przeszukania bazy danych w celu znalezienia brakującej; Tak się stało
Frank Robert Anderson,
Zgoda! Został przeniesiony jak najwięcej kodu do modułu i cieszę się, że mogę to zrobić za pomocą czystego kodu w D8!
Nic

Odpowiedzi:

15

Działający fragment kodu, jak go używać hook_block_access(). Tutaj pobieram warunek z pola bieżącego węzła:

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

Dzięki @Insasse za udostępnienie następującego klejnotu w komentarzach. W przypadku bloków niestandardowych utworzonych programowo można kontrolować widoczność bezpośrednio z klasy bloków poprzez 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');
  }

}

Źródło: Jak programowo utworzyć blok w Drupal 8

leymannx
źródło
1
Możesz nawet napisać kontrolę dostępu w swojej klasie bloków -> webwash.net/programmatically-create-block-drupal-8
Insasse
7

Brak filtru php w Drupal 8 nie będzie już możliwy z poziomu interfejsu użytkownika.

Jedyną opcją jest użycie interfejsu API bloku.

hook_block_access jest twoim najlepszym kandydatem. Stamtąd możesz sprawdzić $operationi zwrócić AccessResult na podstawie twoich warunków.

Tak jak w interfejsie użytkownika, tylko tym razem umieszczając php w module.

Frank Robert Anderson
źródło
4

Oto rozwiązanie Drupal 8: Blokuj wykluczanie stron .

Ten moduł dodaje filtr wykluczeń stron dla bloków.

Aby wykluczyć określone strony po znaku wieloznacznym lub między symbolami wieloznacznymi, po prostu poprzedź wzór ścieżki prefiksem „!” w konfiguracji widoczności strony bloku.

Działa to dla widoczności ustawionej na „pokaż dla wymienionych stron”, w tym przypadku ścieżki wykluczania ukryją blok na stronach, które pasują do tego, mimo że zestaw symboli zastępczych jest wyświetlany.

Lub na odwrót, jeśli lista stron jest ustawiona na „ukryj dla wymienionych stron”, wykluczone ścieżki pokażą blok na stronach, na których wzorzec pasuje, pomimo ustawienia wieloznacznej karty do ukrycia.

Block Exclude Pages screenshot

Juyal Jee
źródło
1

aby rozszerzyć możliwości widoczności bloku, możesz wypróbować tę łatkę:

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

wprowadza operator koniunkcji AND / OR dla warunków widoczności, więc możesz powiedzieć, och, chcę, aby ten blok był widoczny, jeśli jest typu mój_koncepcja LUB użytkownik ma rolę administratora LUB adres URL zaczyna się od mojej / ścieżki / do / * itd. również warunków można to zanegować, dzięki czemu możesz ustawić wiele warunków, w których nie chcesz, aby blok był widoczny

także jeśli korzystasz z modułu Drupal Commerce, możesz wypróbować powyższe, instalując https://www.drupal.org/project/commerce_quick_purchase moduł, że zainstalowanie modułu ujawnia tę funkcjonalność dla wszystkich bloków w systemie, nawet jeśli nie „ t użyć bloku dostarczonego przez moduł zobacz więcej

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

dodatkowo możesz stworzyć własną wtyczkę warunkową, patrz przykład z modułu

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

narkoman
źródło