9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

EC-CUBEAdvent Calendar 2018

Day 12

EC-CUBE4でタグを埋めたい!

Last updated at Posted at 2018-12-11

EC-CUBE4でタグを埋めたいときの方法をいくつか紹介します。
方法ごとにメリット、デメリットがあるので要件に合う方法を選択しましょう。

目次

  • default_frame.twig に追加する
    • default_frame.twig に直接追加する
    • app/template/ ディレクトリを利用して default_frame.twig をカスタマイズする
  • ブロック管理でタグを追加する
    • 画面からブロックを追加
    • プラグインでブロックを追加
  • TemplateEventでタグを追加する

default_frame.twig に追加する

default_frame.twig はEC-CUBEで全体のレイアウトを定義しているテンプレートファイルです。
このファイルに <head> タグや <body> タグ等が定義されています。

  • メリット
    • 早い
    • 手軽に全ページにタグが追加できる
  • デメリット
    • 管理画面から確認変更不可
    • 変更履歴管理が必要

default_frame.twig に直接追加する

フロント画面の default_frame.twig ファイルは以下に配置されています。
src/Eccube/Resource/template/{ECCUBE_TEMPLATE_CODE}/default_frame.twig 1
上記ファイルを編集してタグを追加すればフロントの全画面2に追加されます。

vi src/Eccube/Resource/template/{ECCUBE_TEMPLATE_CODE}/default_frame.twig

反映されない場合は管理画面からキャッシュを消してみましょう。

app/template/ ディレクトリを利用して default_frame.twig をカスタマイズする

app/template/ 配下に同名のテンプレートファイルを配置すると src/Eccube/Resource/template/ より優先的に読み込まれます。

cp src/Eccube/Resource/template/{ECCUBE_TEMPLATE_CODE}/default_frame.twig app/template/{ECCUBE_TEMPLATE_CODE}/

コピーしたファイルを編集してタグを追加すればフロントの全画面2に追加されます。

vi app/template/{ECCUBE_TEMPLATE_CODE}/default_frame.twig

反映されない場合は管理画面からキャッシュを消してみましょう。

ブロック管理でタグを追加する

EC-CUBEにはブロック管理の機能があります。

  • メリット
    • 管理画面からも追加可能
  • デメリット
    • レイアウト単位でのタグ追加となる(ページを指定してタグ追加が難しい)
    • レイアウトを追加変更する際はタグのブロックのレイアウトも気にする必要がある
    • テーマを変更する際も同様に気にする必要がある

画面からブロックを追加

  1. 管理画面 -> コンテンツ管理 -> ブロック管理 からタグのブロックを作成
  2. 管理画面 -> コンテンツ管理 -> レイアウト管理 から任意のレイアウトにブロックを追加

プラグインでブロックを追加

プラグインでもブロックの作成とレイアウトへの追加ができます。
おすすめ商品管理プラグインで同様の処理をしているので内容を確認してみましょう。

プラグインのインストール/有効化/無効化/削除時の処理は PluginManager.php というファイルに記述します。
プラグインを有効化した際には PluginManager.phpenable() 関数が実行されます。
画面からブロックを作成とレイアウトに追加する際には以下のような処理が行われておりますのでそれぞれ実装してやります。

  1. app/template配下へブロックのtwigファイルを配置
  2. ブロックの情報をDBに登録
  3. ブロックのレイアウトへの配置情報をDBに登録

冗長なほどコメントを入れましたので頑張って理解してください。

PluginManager.php
// プラグインのインストール時に実行されます
public function enable(array $meta = null, ContainerInterface $container)
{
    // 1. app/template配下へブロックのtwigファイルを配置
    $this->copyBlock($container);
    // ブロックのデータがすでに作成されている場合は新しいブロックを作りません。
    $Block = $container->get(BlockRepository::class)->findOneBy(['file_name' => $this->blockFileName]);
    if (is_null($Block)) {
        // 2. ブロックの情報をDBに登録、3. ブロックのレイアウトへの配置情報をDBに登録
        $this->createDataBlock($container);
    }
}

private function createDataBlock(ContainerInterface $container)
{
    // DBの操作をするときはentityManagerを利用します
    $em = $container->get('doctrine.orm.entity_manager');
    // DeviceTypeはPCにしておきます。(EC-CUBEのデフォルトでBlockのDeviceTypeは利用されていない)
    $DeviceType = $container->get(DeviceTypeRepository::class)->find(DeviceType::DEVICE_TYPE_PC);
    try {
        // 2. ブロックの情報をDBに登録
        // BlockのEntityを作成します。
        $Block = $container->get(BlockRepository::class)->newBlock($DeviceType);
        // Blockの各パラメータを設定してからDBに登録します。
        $Block->setName($this->blockName) // ブロック名
            ->setFileName($this->blockFileName) // templateファイルのファイル名
            ->setUseController(false) // ブロックにControllerを設定するか。trueにするとこのブロックが呼び出されたときに実行されるControllerを定義できる。
            ->setDeletable(false); // 管理画面から削除できるか。管理画面から削除する必要はないのでfalseを指定。
        $em->persist($Block); // Entityを永続化する。新しく作成したEntityはpersist()しないとDBに保存できない。
        $em->flush($Block); // EntityをDBに保存する。

        // 3. ブロックのレイアウトへの配置情報をDBに登録
        // BlockがどのLayoutのどの位置に配置されているかの情報はBlockPositionで定義されている
        // すでにブロックがレイアウトに配置されている場合は処理を終了
        $blockPos = $container->get(BlockPositionRepository::class)->findOneBy(['Block' => $Block]);
        if ($blockPos) {
            return;
        }
        // ブロックの順序はblock_rowで定義されている
        // ブロックを配置したいところにすでにブロックが登録されている場合には、それを考慮してblock_rowを設定する必要がある
        // ブロックを配置したいレイアウトの位置のブロックの一番下のブロックを取得する
        $blockPos = $container->get(BlockPositionRepository::class)->findOneBy(
            ['section' => Layout::TARGET_ID_MAIN_BOTTOM, 'layout_id' => Layout::DEFAULT_LAYOUT_UNDERLAYER_PAGE],
            ['block_row' => 'DESC']
        );
        // BlockPositionの作成
        $BlockPosition = new BlockPosition();
        // すでに配置されているブロックをもとにblock_rowを設定する
        $BlockPosition->setBlockRow(1);
        if ($blockPos) {
            // ブロックがすでに存在する場合はその一番下のブロックのさらに下にブロックを配置する
            $blockRow = $blockPos->getBlockRow() + 1;
            $BlockPosition->setBlockRow($blockRow);
        }
        // ブロックを配置するレイアウトを取得。ここでは「下層ページ用レイアウト」を指定している。
        $LayoutDefault = $container->get(LayoutRepository::class)->find(Layout::DEFAULT_LAYOUT_UNDERLAYER_PAGE);
        // $BlockPositionのパラメータを設定する
        $BlockPosition->setLayout($LayoutDefault) // レイアウト
            ->setLayoutId($LayoutDefault->getId()) // レイアウトのID
            ->setSection(Layout::TARGET_ID_MAIN_BOTTOM) // 配置位置。ここでは#main_bottomを指定
            ->setBlock($Block) // ブロック
            ->setBlockId($Block->getId()); // ブロックのID
        $em->persist($BlockPosition); // Entityを永続化する。新しく作成したEntityはpersist()しないとDBに保存できない。
        $em->flush($BlockPosition); // EntityをDBに保存する。
    } catch (\Exception $e) {
        throw $e;
    }
}

private function copyBlock(ContainerInterface $container)
{
    // 現在のテーマのテンプレートにファイルを配置するため現在のテーマのディレクトリを取得します。
    $templateDir = $container->getParameter('eccube_theme_front_dir');
    // コピー先にファイルがない場合のみファイルをコピーします
    $file = new Filesystem();
    if (!$file->exists($templateDir.'/Block/'.$this->blockFileName.'.twig')) {
        // app/template配下へブロックのtwigファイルを配置
        $file->copy($this->originBlock, $templateDir.'/Block/'.$this->blockFileName.'.twig');
    }
}

ソースはこちら

タグのテンプレートファイルを用意しておく必要がありますので Resource/template/Block/ 配下にtwigファイルを作成しておきましょう。
おすすめ商品管理プラグインの場合はこちら

説明は割愛しますが、プラグインでブロックを作成される場合には無効化/アンインストール時にブロックを削除する処理も実装しましょう。

TemplateEventでタグを追加する

プラグインやカスタマイズディレクトリでTemplateEventを追加してタグを埋められます。

  • メリット
    • ページを指定してのタグ追加がシンプルに行える
  • デメリット
    • 複数ページへタグ追加する際はその数だけイベントを設定する必要がある
    • 他のプラグイン等で新規追加したページにタグを埋めたいときはイベントの追加が必要

手順

EventSubscriberInterface を実装したクラスを作成します。
メーカー管理プラグインに実装例があるので確認してみましょう。

// EventSubscriberInterfaceを実装したクラスを作成
class MakerEvent implements EventSubscriberInterface
{
    // getSubscribedEvents関数でフックするテンプレートを指定する
    // 戻り値に配列を指定することで複数のページを指定可能
    // この例では商品詳細画面のtwigを指定している
    public static function getSubscribedEvents()
    {
        // 形式は '{フックしたいテンプレートファイル}' => ['{イベント発火時に実行する関数}', {イベントの優先順位(省略可)}]
        return [
            'Product/detail.twig' => ['onTemplateProductDetail', 10],
        ];
    }

    // TemplateEventを引数にとった関数を作成する
    public function onTemplateProductDetail(TemplateEvent $templateEvent)
    {
        // addSnippet()関数で追加したいテンプレートファイルを指定する。
        $templateEvent->addSnippet('@Maker4/default/maker.twig');
    }
}

ソースはこちら

addSnippet() 関数の他に addAsset() 関数も利用可能。

addSnippet() : <body>タグ内の下の方にテンプレートを追加できる
addAsset() : <head>タグ内にテンプレートを追加できる

追加するタグのテンプレートファイルを作成しておく必要があります。
メーカー管理プラグインの場合はここに定義しています。

テンプレートへパラメータを渡す方法はこちらの記事に記載しているのでよかったらどうぞ。

まとめ

タグの追加方法がいくつかあり、それぞれメリットデメリットがあります。
タグの要件に合わせて追加方法の選択が必要です。

例えばプラグインで実現したい場合は default_frame.twig へのタグの追加は難しいです。
また、特定のページだけにタグを配置したい場合はTemplateEventを利用するのが良いでしょう。

  1. デフォルトのテンプレートの場合は ECCUBE_TEMPLATE_CODE=default

  2. 追加した画面は実装による 2

9
11
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
9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?