Як я можу контролювати видимість блоку за допомогою коду?


11

У Drupal 6 я міг контролювати видимість блоку за допомогою PHP-коду в конфігурації блоку інтерфейсу, наприклад:

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

Ці функції шукали поточний вузол, систематику тощо, щоб вирішити, чи відображати блок. Цей параметр PHP відсутній у Drupal 8, але в ньому є $visibilityполе BlockBase. Чи можу я використовувати це для програмного налаштування видимості під час виконання?


1
Ви повинні замість цього оголосити плагін для спеціальних умов. Пошук ядра для @Condition, щоб знайти робочі приклади.
Еял

Як правило, введення PHP-коду в базу даних є поганою практикою, і слід уникати максимально можливого використання.
Ейал

Модуль фільтра php видалено з D8. Загалом, погана ідея використовувати php, введений в інтерфейс користувача та виконаний таким чином. Це погана ідея, оскільки пропущено а; могла покалічити цілий сайт, і тоді я наймусь, щоб шукати db, щоб знайти зниклих; Це сталося,
Френк Роберт Андерсон

Домовились! Переміщується в модуль стільки коду, скільки я міг, і радий, що я можу це зробити з чистим кодом у D8!
Нік

Відповіді:


15

Фрагмент робочого коду, як користуватися hook_block_access(). Тут я отримую умову з поля поточного вузла:

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

Дякуємо @Insasse за те, що поділився наступним дорогоцінним каменем у коментарях. Для програмно створених спеціальних блоків ви можете керувати видимістю безпосередньо з класу блоків за допомогою 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');
  }

}

Джерело: Як програмно створити блок в Drupal 8


1
Ви навіть можете написати перевірку доступу у своєму блоковому класі -> webwash.net/programmatic-create-block-drupal-8
Insasse

7

Відсутній php-фільтр в Drupal 8, це більше не буде можливим у користувальницькому інтерфейсі.

Єдиний варіант - використовувати блок api.

ho_block_access - ваш найкращий канідат. Звідти ви можете перевірити $operationта повернути AccessResult залежно від ваших умов.

Як і в користувальницькому інтерфейсі лише цього разу, вводячи php в модуль.


4

Ось рішення Drupal 8: Блокувати виключення сторінок .

Цей модуль додає фільтр сторінок виключення для блоків.

Щоб виключити конкретні сторінки після підстановки або між підстановкою, просто вставте шаблон контуру за допомогою префікса "!" у конфігурації видимості блокової сторінки.

Це працює для видимості, встановленої на "Показати для перелічених сторінок", в цьому випадку шляхи виключення приховатимуть блок на сторінках, які відповідають незважаючи на встановлений підстановочний знак.

Або навпаки, якщо в списку сторінок встановлено значення "приховати для перелічених сторінок", виключені шляхи покажуть блок на сторінках, де візерунок збігається, незважаючи на підстановку, яка ховається.

Block Exclude Pages screenshot


3

Для 8.2.x потрібно створити плагін Condition і реалізувати ContextProviderInterface .

Дивіться приклад DO, але він якось застарів (тому що BlockEvent і BlockSubscriberBase видалено на користь служби контекстного сховища).

Було б непогано також використовувати консоль Drupal для створення плагіна:

drupal generate:plugin:condition

1

щоб розширити можливості видимості блоку, ви можете спробувати цей патч:

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

він вводить оператор сполучення І / АБО для умов видимості, тому ви можете сказати, о, я хочу, щоб цей блок був видимим, якщо він має my_content_type АБО користувач має роль адміністратора АБО URL починається з мого / path / to / * тощо. Також умови можна заперечувати, щоб ви могли встановити багато умов, за яких ви не хочете, щоб ваш блок був видимим

також якщо ви використовуєте модуль Drupal Commerce, ви можете спробувати вище, встановивши https://www.drupal.org/project/commerce_quick_purchase зауваження, що встановлення модуля відкриває цю функціональність для всіх блоків у системі, навіть якщо ви цього не робите ' t використовувати блок, наданий модулем, див. докладніше

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

додатково ви можете створити свій власний плагін, див. приклад з модуля

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.