web-dev-qa-db-ja.com

コードでブロックの可視性を制御するにはどうすればよいですか?

Drupal 6では、PHPコードを使用してブロックの可視性を制御できます。

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

これらの関数は、現在のノードや分類法などを調べて、ブロックを表示するかどうかを決定しました。このPHPオプションはDrupal 8でなくなりましたが、BlockBase$visibilityフィールドがあります。これを使用してプログラムで実行時に可視性を設定しますか?

11
Nic

使用するコードスニペット 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

16
leymannx

Drupal 8にphpフィルターがないと、UIからこれを実行できなくなります。

唯一のオプションは、ブロックAPIを使用することです。

hook_block_access はあなたの最高の候補です。そこから$operationし、条件に基づいてAccessResultを返します。

UIと同じように、今回はphpをモジュールに配置します。

Drupal 8の解決策: Block Exclude Pages です。

このモジュールは、ブロックの除外ページフィルターを追加します。

ワイルドカードの後またはワイルドカードの間にある特定のページを除外するには、パスパターンの前に「!」を付けます。ブロックページの表示設定。

これは、「リストされたページに対して表示する」に設定された可視性で機能します。この場合、除外パスは、表示するように設定されたワイルドカードにもかかわらず、一致するページのブロックを非表示にします。

または逆に、ページリストが「リストされたページに対して非表示」に設定されている場合、除外されたパスは、ワイルドカードが非表示に設定されているにもかかわらず、パターンが一致するページにブロックを表示します。

Block Exclude Pages screenshot

4
Juyal Jee

8.2.xの場合、条件プラグインを作成し、-を実装する必要があります ContextProviderInterface

D.O。の例 を参照してください。ただし、 BlockEventおよびBlockSubscriberBaseが削除された がコンテキストリポジトリサービスを支持しているため)古くなっています。

Drupalコンソールを使用してプラグインを生成することもいいでしょう:

drupal generate:plugin:condition
3

ブロックの可視性の可能性を拡張するには、このパッチを試すことができます:

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

[〜#〜]と[〜#〜]/[〜#〜]または[〜 #〜]可視性条件の結合演算子。これにより、このブロックがmy_content_type[〜#〜]または[〜 #〜]ユーザーには管理者ロール[〜#〜]または[〜#〜]があり、URLはmyで始まります/ path/to/*など。条件を否定できるため、ブロックを表示したくない多くの条件を設定できます。

Drupal Commerceモジュールを使用している場合も、インストールされている https://www.drupal.org/project/commerce_quick_purchase モジュールノートをインストールすることで上記を試すことができますモジュールが提供するブロックを使用しない場合でも、モジュールはシステム上のすべてのブロックに対してこの機能を公開します

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

さらに、独自の条件プラグインを作成できます。モジュールの例を参照してください

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

1
drugan