Drupal9のプレビューページを任意のレイアウトで表示する
2022-12-06
azblob://2022/12/06/eyecatch/2022-12-06-drupal9-layout-preview-page-000.jpg

FIXER Rookies Advent Calendar 2022の6日目です。

Drupalのカスタムテーマを使って、プレビュー画面を任意のレイアウトで表示する方法を備忘録として残しておきます。

事前準備

Drupalプロジェクトに以下のようなファイルをあらかじめ用意しておきます。

web/
 └ theme/
    └ custom/
       └ my_theme/
          ├ css/
          │  └ style.css
          ├ template/
          │  └ page--node--preview.html.twig
          ├ my_theme.info.yml
          ├ my_theme.libraries.yml
          └ my_theme.theme

実装

1. カスタムテーマの作成

my_theme.info.ymlとmy_theme.libraries.ymlに以下の記述を追加します。

my_theme.info.yml

name: My Theme
type: theme
description: "カスタムテーマ"
core_version_requirement: ^8 || ^9
base theme: claro
libraries:
  - my_theme/global-styling

my_theme.libraries.yml

preview-styling:
  version: 1.x
  css:
    theme:
      css/style.css: {}

追加後、drupalの/admin/appearance/にアクセスすると作成したカスタムテーマが表示されていると思うので、インストールを行います。

カスタムテーマのインストール画面

2. Twigテンプレートの作成

2-1. プレビューに必要なデータを取得

プレビューに必要なデータ(タイトル、本文、作成日など)はtempstoreという一時ストレージに保存されています。

tempstoreから必要な情報を抜き出し、twigの変数に代入するという処理をmy_theme.themeで実装します。

my_theme.theme

php<?php

function my_theme_preprocess_page(&$variables)
{
  if (\Drupal::routeMatch()->getRouteName() == "entity.node.preview") {
    $variables['#attached']['library'][] = 'my_theme/preview-styling';

    # ページのURLからuuidを取得
    $current_path = \Drupal::service('path.current')->getPath();
    $uuid = explode("/", $current_path)[3];

    # tempstoreから記事のエンティティを取得
    $tempstore = \Drupal::service('tempstore.private')->get('node_preview');
    $entity = $tempstore->get($uuid)->getFormObject()->getEntity();

    # タイトルを取得
    $title = $entity->title->value;

    # twig変数に代入
    $variables['title'] = $title;
  }
}

実装の流れとしては

プレビューページのURLからuuidを取得

取得したuuidをもとにtempstoreからデータを取得

データをtwig変数に代入

となっています。

2-2. twigにHTMLを追加

プレビューページ用のHTMLは、page--node--preview.html.twigに、CSSはstyle.cssにそれぞれ記述します。

2-1で表示するデータを変数として渡しているので、それらの変数をHTMLに組み込めばOKです。

HTML<div class="layout-container">
	<main role="main">
		<h1>{{ title }}</h1>
	</main>
</div>

3. 確認

ここまで実装した後に、Drupalからコンテンツを作成しプレビューボタンを押すと2-2で追加した通りのレイアウトでプレビューページが表示されます。

参考リンク