Block API
概要
Drupal 8のブロックは、実際には2つの別々のAPI構造で構成されており、Drupalが以前のイテレーションでサポートしていたものと同様のユーザーインターフェースを作成します。この2つのAPIは、再利用可能なスタンドアロンAPIであるBlock Plugin APIと、ブロックの配置と可視性の制御のためのDrupal 8の特定のユースケースであるBlock Entity APIです。
Block Plugin APIでのブロックの作成
モジュールのコードで定義されたブロックを作成するには、プラグインAPI、特にアノテーションベースのプラグイン検出の学習と理解が必要です。これは、Drupal 8がブロックを定義するコードを見つけるために使用するメカニズムです。
モジュールで定義されたカスタムブロックの作成には、次の手順が含まれます:
- アノテーションを使用してブロックプラグインを作成します
- Drupal\Core\Block\BlockBaseクラスを拡張します。
- ユースケースに必要なDrupal\Core\Block\BlockPluginInterfaceインターフェースのメソッドを実装します。
ブロックをDrupalとユーザーに表示可能にする
Drupalは検出にPSR-4標準を使用します。モジュール名がfaxであると仮定すると、カスタムブロックのコードはfax/src/Plugin/Block/に配置する必要があります。このディレクトリ内の各ファイルは、含まれるクラスに従って名前を付ける必要があります。FaxBlockクラスを定義する場合、それはfax/src/Plugin/Block/FaxBlock.phpというファイルに配置し、次の例に従った内容にする必要があります:
namespace Drupal\fax\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a 'Fax' block.
*
* @Block(
* id = "fax_block",
* admin_label = @Translation("Fax block"),
* )
*/
class FaxBlock extends BlockBase {
// Override BlockPluginInterface methods here.
}
アノテーションのidプロパティは、ブロックの一意の機械可読識別子と、他のコードから見えるブロック名を定義します。'admin_label'アノテーションは、管理インターフェースにブロックを表示するときに使用される人間が読めるブロック名を定義します。利用可能なアノテーションプロパティは、\Drupal\Core\Block\Annotation\Block(パブリックプロパティ)にあります。
オーバーライドする最も一般的な2つのメソッド:
- BlockPluginInterface::build() - ブロックに表示させたいコンテンツを定義するレンダー配列を返す必要があります。
- BlockBase::access() - ブロックの可視性を制御します。AccessResultオブジェクトを返すことが期待されています。
ブロックにカスタム設定オプションを追加する
BlockPluginInterface::blockForm()メソッドとBlockPluginInterface::blockSubmit()メソッドをオーバーライドし、BlockBase::setConfigurationValue()とBlockBase::getConfiguration()を使用して、ブロック設定フォームにカスタム設定オプションを追加することもできます。
次の例では、blockForm()メソッドに新しいテキストフィールドを追加し、blockSubmit()メソッドでユーザーが提供したデータを保存します。このコードは、フォームの構築時に値がどのように取得され、検証され、適切なメソッドで更新されるかを示しています。
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
/**
* Provides a 'Fax' block.
*
* @Block(
* id = "fax_block",
* admin_label = @Translation("Fax block"),
* )
*/
class FaxBlock extends BlockBase implements BlockPluginInterface {
// Access method here ...
/**
* {@inheritdoc}
*/
public function build() {
$config = $this->getConfiguration();
$fax_number = isset($config['fax_number']) ? $config['fax_number'] : '';
return array(
'#markup' => $this->t('The fax number is @number!', array('@number' => $fax_number)),
);
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$form = parent::blockForm($form, $form_state);
// Retrieve existing configuration for this block.
$config = $this->getConfiguration();
// Add a form field to the existing block configuration form.
$form['fax_number'] = array(
'#type' => 'textfield',
'#title' => t('Fax number'),
'#default_value' => isset($config['fax_number']) ? $config['fax_number'] : '',
);
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
// Save our custom settings when the form is submitted.
$this->setConfigurationValue('fax_number', $form_state->getValue('fax_number'));
}
/**
* {@inheritdoc}
*/
public function blockValidate($form, FormStateInterface $form_state) {
$fax_number = $form_state->getValue('fax_number');
if (!is_numeric($fax_number)) {
$form_state->setErrorByName('fax_number', t('Needs to be an integer'));
}
}
}
また、build()メソッドでBlockBase::getConfiguration()メソッドを使用して、設定データを取得し、ユーザーに表示することもできます。ブロックのaccess()メソッドには、ブロックを表示するかどうかを決定するためのより複雑なロジックを含めることもできます。
アクセス条件メソッドの例。
/**
* {@inheritdoc}
*/
public function access(AccountInterface $account, $return_as_object = FALSE) {
return \Drupal\Core\Access\AccessResult::allowedIf($account->isAuthenticated());
}
独自のキャッシュ条件を作成することもできます
キャッシュタグを使用したメソッドの例。キャッシュタグの詳細をご覧ください。
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return \Drupal\Core\Cache\Cache::mergeTags(parent::getCacheTags(), ['node_list']);
}
ブロックの最大キャッシュ時間を0に変更したい場合。キャッシュmax-ageの詳細をご覧ください。
public function getCacheMaxAge() {
// If you want to disable caching for this block.
return 0;
}