技術アーカイブス
EC-CUBE4のHTML最適化:プラグインで実現するSymfonyのEventListener活用
EC-CUBE4になってから、Symfonyで用意している機構へ簡単にアクセスできるようになりました。今回は Symfony の EventListener を使用した例をご紹介します。
出力するHTMLをminify(圧縮)するには、いくつか方法がありますが、ここではTwigがレンダリングした後のHTMLを変換する方法を説明します。本体のソースコードを直接編集することなく、プラグインで実装することが可能です。
1. プラグインを作成します。
プラグインコードは**[HtmlMinify]**とします。
1-1. プラグインフォルダを作成します。
[EC-CUBEインストールディレクトリ]/app/Plugin/HtmlMinify
1-2. プラグインの設定ファイルを設置します。
[EC-CUBEインストールディレクトリ]/app/Plugin/HtmlMinify/composer.json
ファイル内容
{
"name" : "ec-cube/HtmlMinify",
"version" : "1.0.0",
"description" : "HTML Minify プラグイン",
"type" : "eccube-plugin",
"require" : {
"ec-cube/plugin-installer" : "~0.0.3"
},
"extra" : {
"code" : "HtmlMinify"
}
}
1-3. プラグインをインストールします。
EC-CUBEインストールディレクトリに移動後、以下のコマンドを実行し、プラグインのインストールと有効化を行います。
php bin/console eccube:plugin:install --code=HtmlMinify
php bin/console eccube:plugin:enable --code=HtmlMinify
- EventListener を作成します。
2-1. EventListener を登録する設定ファイルを編集します。
[EC-CUBEインストールディレクトリ]/app/Plugin/HtmlMinify/Resource/config/services.yaml
ファイル内容
services:
htmlminify_listener: # 1
class: Plugin\HtmlMinify\EventListener\HtmlMinifyListener # 2
arguments: ['@service_container'] # 3
tags: # 4
- {
name: kernel.event_listener,
event: kernel.response,
method: onKernelResponse,
priority: -10000
}
# 1
システム上で一意となる名前を設定します。
# 2
実行するEventListenerクラスを指定します。
# 3
実行するクラスのコンストラクタに渡す、オブジェクトを指定します。
指定できるオブジェクトは以下のコマンドで確認することが出来ます。
php bin/console debug:container
# 4
実行時のオプションを指定します。
name: kernel.event_listener・・・実行する時のイベントリスナーの種類を指定します。
event: kernel.response・・・イベントの種類を指定します。他にkernel.requestなどのイベントがあります。
https://symfony.com/doc/3.4/components/http_kernel.html
method: onKernelResponse・・・実行するメソッド名を指定します。
priority: -10000・・・実行する順番を指定します。数字が低い方が後に実行されます。
2-2. HTMLを変換するクラスを作成します。
[EC-CUBEインストールディレクトリ]/app/Plugin/HtmlMinify/EventListener/HtmlMinifyListener.php
ファイル内容
<?php
namespace Plugin\HtmlMinify\EventListener;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
class HtmlMinifyListener
{
/**
* @var ContainerInterface
*/
private $container;
/**
* コンストラクタ。
*
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* HTMLタグを圧縮します。
*
* @param FilterResponseEvent $event
* @param string $eventName
*/
public function onKernelResponse(FilterResponseEvent $event,$eventName)
{
if (
($response = $event->getResponse())
&& ($response instanceof \Symfony\Component\HttpFoundation\Response)
&& ($content = $response->getContent())
) {
$content = preg_replace('#(?ix)(?>[^\S ]\s*|\s{2,})(?=(?:(?:[^<]++|<(?!/?(?:script|textarea|pre)))*+)(?:<(
?>script|textarea|pre)|\z))#','',$content);
$response->setContent($content);
}
}
}