Block Pluginを使用して非管理ファイルをサイトに表示する方法を解説します。前回作成したファイルハンドラーサービスをブロックとして実装し、サイトビルダーがUI経由で自由に配置できるようにします。
パート2では、非管理ファイルを検索してランダムに1つを返すサービスを構築しました。このパートでは、その機能をBlock Pluginとして公開します。ブロックを使用することで、カスタムロジックを再利用可能な形で実装できます。サイトビルダーは、Drupalのブロックレイアウトインターフェイスを通じて、コードを変更することなく、任意の場所に配置できます。
Block Pluginクラスの基本構造と実装
クラスはBlockBaseを継承し、ContainerFactoryPluginInterfaceを実装します。これにより、DrupalのサービスコンテナからファイルハンドラーとURL生成サービスを注入できます。
<?php
namespace Drupal\unmanaged_files\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\unmanaged_files\Service\FileHandler;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
/**
* ランダムな非管理ファイルを表示するブロックを提供します。
*
* @Block(
* id = "unmanaged_files_block",
* admin_label = @Translation("Unmanaged Files Block"),
* )
*/
final class UnmanagedFilesBlock extends BlockBase implements ContainerFactoryPluginInterface {依存性注入を活用したコンストラクターの実装
コンストラクターは、通常のプラグインパラメーターに加えて、2つの注入されたサービスを受け取ります。カスタムFileHandlerとDrupalのFileUrlGeneratorInterfaceです。これらは、後で使用するためにプライベートプロパティとして保存されます。
/**
* 新しいUnmanagedFilesBlockインスタンスを構築します。
*
* @param array $configuration
* プラグインインスタンスに関する情報を含む設定配列。
* @param string $plugin_id
* ブロックのプラグインID。
* @param mixed $plugin_definition
* プラグイン実装の定義。
* @param \Drupal\unmanaged_files\Service\FileHandler $handler
* 非管理ファイル用のファイルハンドラーサービス。
* @param \Drupal\Core\File\FileUrlGeneratorInterface $urlGen
* ファイルURL生成サービス。
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
private FileHandler $handler,
private FileUrlGeneratorInterface $urlGen,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}コンテナファクトリパターンによるサービス注入
コンストラクターがサービスを必要とするため、ContainerFactoryPluginInterfaceからcreate()も実装します。これは、コンテナからサービスを取得し、コンストラクターに渡します。@varアノテーションは、IDEが型を理解し、誤った警告を回避するのに役立ちます。
/**
* UnmanagedFilesBlockのインスタンスを作成します。
*
* このファクトリーメソッドは、コンテナから必要なサービスを注入します。
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $c
* サービスコンテナ。
* @param array $configuration
* プラグインインスタンスに関する情報を含む設定配列。
* @param string $plugin_id
* ブロックのプラグインID。
* @param mixed $plugin_definition
* プラグイン実装の定義。
*
* @return static
* 新しいUnmanagedFilesBlockインスタンスを返します。
*/
public static function create(ContainerInterface $c, array $configuration, $plugin_id, $plugin_definition): self {
/** @var \Drupal\unmanaged_files\Service\FileHandler $handler */
$handler = $c->get('unmanaged_files.handler');
/** @var \Drupal\Core\File\FileUrlGeneratorInterface $urlGen */
$urlGen = $c->get('file_url_generator');
return new self(
$configuration,
$plugin_id,
$plugin_definition,
$handler,
$urlGen,
);
}レンダー配列を生成するbuildメソッドの実装
build()メソッドは、Drupalがブロックをレンダリングするために呼び出すものです。ファイルハンドラーにランダムな非管理ファイルを要求します。ファイルが見つかった場合は、imageテーマを使用してレンダー配列を返します。ファイルが見つからない場合は、シンプルなメッセージを返します。max-ageキャッシュメタデータは1秒に設定されているため、ページをリフレッシュすると画像が素早くローテーションします。
/**
* ブロックのレンダー配列を構築します。
*
* ファイルハンドラーを使用してランダムな非管理ファイルを取得し、
* それを画像レンダー配列として返します。非管理ファイルが見つからない場合は、
* 代わりにシンプルなメッセージを返します。
*
* @return array
* ブロックコンテンツのレンダー配列。
*/
public function build(): array {
$uri = $this->handler->getRandomFile();
if (!$uri) {
return [
'#markup' => '<p>非管理ファイルが見つかりません。</p>',
];
}
return [
'#theme' => 'image',
'#uri' => $uri,
'#alt' => $this->t('ランダムな非管理ファイル'),
'#cache' => [
'max-age' => 1,
],
];
}管理画面でのブロック配置手順
キャッシュをクリアしてから、「構造」→「ブロックレイアウト」に移動します。「カスタム」カテゴリに「Unmanaged Files Block」がリストされているのがわかるはずです。サイドバーまたはフッター領域に配置し、保存してページをリフレッシュしてください。リロードするたびに、異なる非管理ファイル画像が表示されるはずです。
管理画面での操作手順:
- 管理メニューから「構造」→「ブロックレイアウト」にアクセス
- 配置したい領域(サイドバー、フッターなど)の「ブロックを配置」をクリック
- 「カスタム」カテゴリから「Unmanaged Files Block」を選択
- 設定を確認して「ブロックを配置」ボタンをクリック
- レイアウトを保存
次のステップ
パート4では、Twigテンプレート内で非管理ファイルを直接レンダリングする方法を探ります。これにより、開発者はテーマレイヤー内でハンドラーを使用するより柔軟な方法が得られます。
この記事は 「Unmanaged Files in Drupal (Part 3): Rendering an Unmanaged File in a Block」の翻訳記事です。
カテゴリ