concrete5の記事ブロック内で画像の遅延読み込みに対応する(カスタムアセットの登録例)
Posted by admin at 16:31 日時 2015/05/02
対象:バージョン5.7以降
長いページでスクロールしていくとスクロールした時点で画像が読み込まれる Lazyload に対応する方法です。また、Lazyloadに限らず、新たな Javascript ライブラリーをconcrete5に登録して呼び出す方法のサンプルでもあります。
ファイル一覧
- /application/blocks/content/controller.php (新規)
- /application/bootstrap/app.php (変更)
- /application/js/jquery.lazyload.min.js (新規)
アセットの登録
追加アセットの登録は、/application/bootstrap/app.php ファイルに追記することで行ないます。また、パッケージコントローラーからの登録も可能ですが、この記事では説明を省きます。
<?php // アセットリストの取得 $al = \Concrete\Core\Asset\AssetList::getInstance(); // jquery.lazyload.js を登録する $al->register( 'javascript', 'jquery-lazyload', 'js/jquery.lazyload.min.js', array( 'version' => '1.9.5', 'position' => \Concrete\Core\Asset\Asset::ASSET_POSITION_FOOTER, 'minify' => false, 'combine' => true ) ); // lazyloadを起動するスクリプトを登録する $al->register( 'javascript-inline', 'jquery-lazyload-init', '$(function() { $("img.lazy").lazyload(); });', array( 'position' => \Concrete\Core\Asset\Asset::ASSET_POSITION_FOOTER, 'minify' => false, 'combine' => true ) ); // 両スクリプトと、lazyloadの動作に必要なjqueryをグループとして登録する $al->registerGroup('lazyload', array( array('javascript', 'jquery'), array('javascript', 'jquery-lazyload'), array('javascript-inline', 'jquery-lazyload-init') ));
スクリプトに記載されている js/jquery.lazyload.min.js は、lazyload Javascript ライブラリの本体です。ダウンロードして取得し、/application/js/jquery.lazyload.min.js に配置します。
ブロックコントローラーのオーバーライド
記事ブロックのコントローラーは /concrete/blocks/content/controller.php にありますが、/application/blocks/content/controller.php にファイルを作成することで、このデフォルトの記事ブロックの挙動をカスタマイズすることができます。そのままコピーしても良いのですが、元の記事ブロックのコントローラーを継承した方が、意図しない範囲に影響がでないためおすすめです。
<?php namespace Application\Block\Content; use Sunra\PhpSimple\HtmlDomParser; // コアの記事ブロックのコントローラーを継承 class Controller extends \Concrete\Block\Content\Controller { // アセットの登録 function registerViewAssets($outputContent) { // 親クラスのアセット読み込みを呼び出す parent::registerViewAssets($outputContent); // Lazyloadグループを追加で呼び出す $this->requireAsset('lazyload'); } // 記事ブロックの表示内容の取得 function getContent() { // 親クラスから本来記事ブロックで表示する内容を取得 $content = parent::getContent(); // DOMパーサーの起動 $dom = new HtmlDomParser(); $r = $dom->str_get_html($content); if (is_object($r)) { // img タグを探す foreach($r->find('img') as $img) { // src属性の値を取得 $src = $img->src; // src属性は空にする $img->src = null; // data-original属性に画像のソースを登録 $img->{'data-original'} = $src; // class属性を指定 $img->class = "lazy"; } $content = (string) $r; } return $content; } }
ブロックコントローラーのオーバーライドは、キャッシュをクリアしないと反映されませんのでご注意ください。
この例では、HTMLの出力も変更する必要があったため、ブロックコントローラーをオーバーライドしていますが、登録したアセットを使用するだけなら、ブロックのカスタムテンプレートからでも可能です。その場合は、下記のように記述します。
$v = \View::getInstance(); $v->requireAsset('javascript', 'lazyload');