條件插件在塊實體配置中被用到(在默認安裝下,系統也只有該處用到),用來指定塊在什麼條件下才顯示,見管理後臺:管理》結構》區塊佈局》點擊某個塊的配置,每一種類型的條件由一個插件負責,這些插件由條件插件管理器來管理:
服務id:plugin.manager.condition
類:Drupal\Core\Condition\ConditionManager
獲取方式:\Drupal::service('plugin.manager.condition');
插件定義的修改鉤子:condition_info
插件存放目錄:src/Plugin/Condition
釋文類:\Drupal\Core\Condition\Annotation\Condition
系統默認提供了5個條件插件:
語言條件:
控制在某種語言界面下,是否滿足需求,類如下:
Drupal\language\Plugin\Condition\Language
內容類型條件:
控制是在哪些內容類型下條件是否滿足,類如下:
\Drupal\node\Plugin\Condition\NodeType
頁面條件:
依據路徑判斷是否滿足條件,類如下:
\Drupal\system\Plugin\Condition\RequestPath
角色條件:
依據角色判斷是否滿足條件,類如下:
\Drupal\user\Plugin\Condition\UserRole
當前主題條件:
只在當前主題下才滿足條件,類如下:
\Drupal\system\Plugin\Condition\CurrentThemeCondition
自定義條件插件:
在模塊的src/Plugin/Condition目錄下定義一個類,實現以下接口:
\Drupal\Core\Condition\ConditionInterface
系統很貼心的提供了條件插件的默認基類:
\Drupal\Core\Condition\ConditionPluginBase
只需要繼承她即可,清除緩存啓用
可參見系統定義的插件示例,以下提供了一個自定義的示例。
自定義示例:
這裏提供一個示例,用於在指定的星期才顯示塊,沒有指定的那一天不顯示,如果沒有配置,將視爲顯示,這裏假設模塊名爲“yunke”,在目錄yunke/src/Plugin/Condition建立一個類,文件名:Week.php,內容如下:
<?php
namespace Drupal\yunke\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Form\FormStateInterface;
/**
* 提供一個星期條件
*
* @Condition(
* id = "week",
* label = @Translation("week"),
* )
*/
class Week extends ConditionPluginBase
{
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state)
{
$options = [
1 => 'Monday',
2 => 'Tuesday',
3 => 'Wednesday',
4 => 'Thursday',
5 => 'Friday',
6 => 'Saturday',
0 => 'Sunday',
];
$form['week'] = [
'#type' => 'checkboxes',
'#title' => '在以下時間顯示',
'#default_value' => $this->configuration['week'],
'#options' => $options,
'#description' => '如果沒有選擇,相當於全部選中',
];
return parent::buildConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration()
{
return [
'week' => [],
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state)
{
$this->configuration['week'] = array_filter($form_state->getValue('week'));
parent::submitConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function summary()
{
$days = $this->configuration['week'];
if (count($days) > 1) {
$days = implode(', ', $days);
} else {
$days = reset($days);
}
if (!empty($this->configuration['negate'])) {
return $this->t('在星期 @week 將不顯示', ['@week' => $days]);
} else {
return $this->t('在星期 @week 顯示', ['@week' => $days]);
}
}
/**
* {@inheritdoc}
*/
public function evaluate()
{
$week=date("w");
if (empty($this->configuration['week']) && !$this->isNegated()) {
return TRUE;
}
return in_array($week, $this->configuration['week']);
}
/**
* {@inheritdoc}
*/
public function getCacheContexts()
{
$contexts = parent::getCacheContexts();
$contexts[]='week';
//此處應定義一個關於星期的上下文,以便讓緩存正常工作
return $contexts;
}
}
該類需要一個自定義的上下文,在目錄yunke\src\CacheContext建立類:
文件名:WeekCacheContext.php 內容如下:
<?php
namespace Drupal\yunke\CacheContext;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\Context\CacheContextInterface;
/**
* 定義一個星期緩存上下文
*
* 上下文 ID: 'week'.
*/
class WeekCacheContext implements CacheContextInterface {
/**
* {@inheritdoc}
*/
public static function getLabel() {
return t('Week');
}
/**
* {@inheritdoc}
*/
public function getContext() {
return date("w");
}
/**
* {@inheritdoc}
*/
public function getCacheableMetadata() {
return new CacheableMetadata();
}
}
然後在服務定義文件:yunke/yunke.services.yml中添加以下內容:
cache_context.week:
class: \Drupal\yunke\CacheContext\WeekCacheContext
tags:
- { name: cache.context }
清除緩存,然後到塊配置頁面就能看到我們自定義的條件了
條件解析特徵:
系統提供了一個條件解析特徵:
\Drupal\Core\Condition\ConditionAccessResolverTrait
這被用來判斷有多個條件時,最終條件是否能夠滿足,只有一個方法:
resolveConditions($conditions, $condition_logic)
參數$conditions是由條件插件對象構成的數組,$condition_logic代表級聯條件的關鍵詞,and或or之一,
該方法返回一個布爾值,代表條件是否得到滿足,true爲所有條件滿足。
補充:
條件插件的上下文映射數組來自:
\Drupal\Core\Condition\ConditionPluginBase::buildConfigurationForm
在表單內部以值類型被保存
我是雲客,【雲遊天下,做客四方】,聯繫方式見主頁,歡迎轉載,但須註明出處