在Drupal 6中,我可以在块UI配置中使用PHP代码来控制块可见性,例如:
<?php return MYMODULE_abc() || MYMODULE_def() ; ?>
这些功能查询当前节点,分类法等,以决定是否显示该块。这个PHP选项在Drupal 8中消失了,但是中有一个$visibility
字段BlockBase
。我可以使用它来以编程方式在运行时设置可见性吗?
在Drupal 6中,我可以在块UI配置中使用PHP代码来控制块可见性,例如:
<?php return MYMODULE_abc() || MYMODULE_def() ; ?>
这些功能查询当前节点,分类法等,以决定是否显示该块。这个PHP选项在Drupal 8中消失了,但是中有一个$visibility
字段BlockBase
。我可以使用它来以编程方式在运行时设置可见性吗?
Answers:
一个有效的代码片段如何使用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中的php过滤器,将不再可能从UI中进行。
唯一的选择是使用块api。
hook_block_access是您最好的候选人。从那里,您可以检查$operation
并根据您的条件返回AccessResult。
就像在UI中一样,这次只是将php放入模块中。
对于8.2.x,您需要创建一个条件插件并实现ContextProviderInterface。
请参阅DO中的示例,但是它有点过时了(因为删除了BlockEvent和BlockSubscriberBase以便使用上下文存储库服务)。
也可以使用Drupal控制台生成插件:
drupal generate:plugin:condition
要扩展块可见性的可能性,您可以尝试以下补丁:
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/条件