如何使用代码控制块的可见性?


11

在Drupal 6中,我可以在块UI配置中使用PHP代码来控制块可见性,例如:

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

这些功能查询当前节点,分类法等,以决定是否显示该块。这个PHP选项在Drupal 8中消失了,但是中有一个$visibility字段BlockBase。我可以使用它来以编程方式在运行时设置可见性吗?


1
您应该改为声明一个自定义条件插件。在核心中搜索@Condition以找到可用的示例。
2016年

通常,将PHP代码写入数据库是一种不好的做法,应尽可能避免使用。
2016年

php过滤器模块已从D8中删除。通常,使用在用户界面中输入并以这种方式执行的php是个坏主意。这是个好主意,因为缺少一个; 可能使整个网站瘫痪,然后我将被雇用搜索数据库以寻找失踪的地方; 这已经发生了,
Frank Robert Anderson

同意!我将尽可能多的代码移入模块,并且很高兴我可以在D8中使用纯代码来做到这一点!
尼克

Answers:


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/programmatically-create-block-drupal-8
Insasse,

7

缺少Drupal 8中的php过滤器,将不再可能从UI中进行。

唯一的选择是使用块api。

hook_block_access是您最好的候选人。从那里,您可以检查$operation并根据您的条件返回AccessResult。

就像在UI中一样,这次只是将php放入模块中。


4

这是Drupal 8解决方案:块排除页面

该模块为块添加排除页面过滤器。

要排除通配符之后或通配符之间的特定页面,只需在路径模式前加上前缀“!”即可 在阻止页面可见性配置中。

这适用于将可见性设置为“显示列出的页面”,在这种情况下,尽管通配符设置为显示,但排除路径将隐藏与匹配的页面上的块。

否则,如果页面列表设置为“隐藏列出的页面”,则尽管通配符设置为隐藏,但排除的路径将在模式匹配的页面上显示块。

Block Exclude Pages screenshot



1

要扩展块可见性的可能性,您可以尝试以下补丁:

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

它为可见性条件引入了AND / OR联合运算符,因此您可以说哦,我希望此块可见(如果它属于my_content_type 用户具有管理员角色,或者 url以my / 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/条件

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.