4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DrupalAdvent Calendar 2023

Day 6

Drupal 10.2の開発者向けアップデート

Last updated at Posted at 2023-12-09

Drupal Advent Calendar 2023 の6日目です。

前日の投稿ではウミ菊池さんから非エンジニア視点での Drupal 10.2 変更点ピックアップが紹介されていましたので、本記事ではDrupal 10.2に含まれる開発者向けのアップデート(の中から私が理解できたもの)をいくつか紹介しようと思います。執筆時点の最新バージョンであるDrupal 10.2.0-rc1を参照しています。

新機能

プラグインタイプで、Annotationsの代わりにAttributesが利用できるように

Drupalでは、ブロックやViewsで利用されているプラグインシステムでDoctrine Annotationsが活用されています。PHP 8から言語ネイティブでAttributesがサポートされたことで、Drupal 10.2からAttributesを使用したプラグイン開発ができるようになりました。

Doctrine AnnotationsはDrupal 10中に非推奨となり、Drupal 11で削除される計画です。

AnnotatedClassDiscoveryで独自プラグインタイプを作成している方は、Attributesを使用した実装方法に移行する必要があります。

AnnotatedClassDiscoveryが利用されたプラグインタイプを用いてプラグインを作成している方は、まずプラグインタイプ側でAttributesがサポートされていることを確認し、Attributesを使用した実装方法に移行する必要があります。

Drupal 10.2の時点では、コアではBlockとActionのみがAttributesに対応しています。

コード例

ブロックプラグインタイプを使用してプラグインを作成した例を示します。

Drupal 10.1以前
web/modules/custom/marucha/src/Plugin/Block/MaruchaBlock.php
<?php

namespace Drupal\marucha\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides marucha block.
 *
 * @Block(
 *   id = "marucha_block",
 *   admin_label = @Translation("Marucha Block"),
 * )
 */
class MaruchaBlock extends BlockBase {

  public function build() {
    return [
      '#markup' => 'This is marucha block.',
    ];
  }

}

Drupal 10.2以降
web/modules/custom/marucha/src/Plugin/Block/MaruchaBlock.php
<?php

namespace Drupal\marucha\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\Attribute\Block;
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
 * Provides marucha block.
 */
#[Block(
  id: 'marucha_block',
  admin_label: new TranslatableMarkup('Marucha Block')
)]
class MaruchaBlock extends BlockBase {

  public function build() {
    return [
      '#markup' => 'This is marucha block.',
    ];
  }

}

差分

参照

イベントサブスクライバでSymfonyのautoconfigurationが利用可能に

イベントをサブスクライブする場合、モジュールの *.service.yml ファイルにサブスクライバを登録します。Drupal 10.2からは、service.ymlの _defaults キー内に autoconfigure: true を指定することで個別にタグをつける必要がなくなりました。

コード例

Drupal 10.1以前
web/modules/custom/marucha/marucha.services.yml
services:
  marucha.config_subscriber:
    class: '\Drupal\marucha\EventSubscriber\ConfigSubscriber'
    tags:
      - { name: 'event_subscriber' }
Drupal 10.2以降
web/modules/custom/marucha/marucha.services.yml
services:
  _defaults:
    autoconfigure: true
  marucha.config_subscriber:
    class: '\Drupal\marucha\EventSubscriber\ConfigSubscriber'
差分

参照

ControllerBaseクラスでDIする際にcreate()メソッドが不要に

コントローラー、フォーム、ブロックなどのクラスでサービスを注入する場合、create()ファクトリメソッドをオーバーライドすることでサービスを読み込むことができます。

Drupal 10.2ではControllerBaseクラスにAutowireTraitが実装され、サービスを読み込むためであればcreate()メソッドの実装は不要になりました。1

コード例

Drupal 10.1以前
web/modules/custom/marucha/src/Controller/MaruchaController.php
<?php

namespace Drupal\marucha\Controller;

use Drupal\Component\Datetime\Time;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MaruchaController extends ControllerBase {

  protected $time;

  public function __construct(Time $time) {
    $this->time = $time;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('datetime.time')
    );
  }

# 省略
Drupal 10.2以降
web/modules/custom/marucha/src/Controller/MaruchaController.php
<?php

namespace Drupal\marucha\Controller;

use Drupal\Component\Datetime\Time;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

class MaruchaController extends ControllerBase {

  protected $time;

  public function __construct(
    #[Autowire(service: 'datetime.time')]
    Time $time
  ) {
    $this->time = $time;
  }

# 省略
差分

参照

#config_targetプロパティがConfigFormBaseクラスに追加

以下のように、スキーマファイルで constraints キーを使用することで各構成値に制約を設定できます。

web/modules/custom/marucha/config/schema/marucha.schema.yml
marucha.settings:
  type: config_object
  label: 'Marucha settings'
  mapping:
      name:
        type: label
        label: 'Name'
        constraints:
          NotBlank:
            message: "入力してください!(スキーマファイル側で制御)"

しかし、フォームではこの制約の定義を読み込むことは出来ず、validateForm()メソッドで同じようなロジックを記述する必要がありました。

Drupal 10.2から、ConfigFormBaseクラスに #config_target プロパティが実装され、これを使用することでスキーマファイルに定義された制約で検証を行うことができるようになりました。

コード例

Drupal 10.1以前
web/modules/custom/marucha/src/Form/MaruchaConfigForm.php
<?php

namespace Drupal\marucha\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

class MaruchaConfigForm extends ConfigFormBase {

  public function getFormId() {
    return 'marucha_config_form';
  }

  protected function getEditableConfigNames() {
    return ['marucha.settings'];
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('marucha.settings');
    $form['name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name'),
      '#default_value' => $config->get('name'),
    ];
    return parent::buildForm($form, $form_state);
  }

  public function validateForm(array &$form, FormStateInterface $form_state) {
    if (!$form_state->getValue('name')) {
      $form_state->setErrorByName('name', '入力してください!(validateFormメソッドで制御)');
    }
  }

# 省略

Screenshot 2023-12-09 at 17.57.13.png

Drupal 10.2以降
web/modules/custom/marucha/src/Form/MaruchaConfigForm.php
<?php

namespace Drupal\marucha\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

class MaruchaConfigForm extends ConfigFormBase {

  public function getFormId() {
    return 'marucha_config_form';
  }

  protected function getEditableConfigNames() {
    return ['marucha.settings'];
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('marucha.settings');
    $form['name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name'),
      '#default_value' => $config->get('name'),
      '#config_target' => 'marucha.settings:name',
    ];
    return parent::buildForm($form, $form_state);
  }

# 省略

Screenshot 2023-12-09 at 17.58.01.png

差分

参照

まとめ

私が触ったことがあるAPIを中心に新機能を紹介しました。コード例はリポジトリに公開しました。

  1. フォームやブロックは・・・?

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?