【 Cocoon 】AMP でスワイプ対応の画像拡大ギャラリーを実装するカスタマイズ

amp-lightbox-galleryをCocoonで使う方法

Akira

福岡在住ウェブデザイナー。Web サイト制作に役立つ情報を「見やすさ」と「使いやすさ」にこだわり紹介しています。

WordPress テーマ「 Cocoon 」の AMP に、 Lightbox 風の画像ギャラリーを実装する方法のご紹介です。

使用する AMP コンポーネントは、 amp-lightbox-gallery

画像の拡大と一覧表示、そしてスワイプ操作でのスライド表示に対応しています。

Cocoon に実装後の動作は、こんな感じです。

また、 AMP By Example 内の画像で、 amp-lightbox-gallery の動作を体験できます。

もし、 Cocoon 親テーマで実装されていれば、使う方は多いような気がします。

カスタマイズは、 100% コピペの 3 ステップで終わる簡単さです。

amp-image-lightbox との違い

以前「【 Cocoon 】AMP で画像拡大表示のライトボックスを実装する方法」という記事を書きました。

この記事では、 amp-image-lightbox を使った画像拡大のカスタマイズをご紹介しています。

amp-lightbox-gallery の実装方法をご紹介する前に、 amp-image-lightbox との違いをご説明します。

今回ご紹介する amp-lightbox-gallery は、下記の特色があります。

  • 画像を拡大できる
  • 拡大時にキャプションを表示できる
  • 画像の一覧表示ができる
  • 複数の画像がある時は、スワイプ操作でスライド表示ができる
  • amp-carousel と併用できる
  • 動作中に暗い背景をクリックしても、元には戻らない。元に戻す時は、「閉じる」アイコンのクリックが必要

amp-lightbox-galleryの閉じるアイコンamp-lightbox-galleryの閉じるアイコン

一方、 amp-image-lightbox は、下記の特色があります。

  • 画像を拡大できる
  • 拡大時にキャプションを表示できる
  • 動作中に暗い背景をクリックすると、元に戻る
  • 画像の一覧表示はできない
  • 複数の画像があっても、スライド表示はできない

それぞれの特色を考慮すると、サイトにぴったりなコンポーネントを選べます。

今回の amp-lightbox-gallery が適しているのは、こんなサイトです。

  • スワイプ対応のギャラリー機能が欲しい
  • 画像がメインコンテンツ
  • Cocoon 設定 → 画像より、「 baguetteBox(スマホ向け)」「 Lightbox 」を選んでいる

一方、 amp-image-lightbox が適しているのは、こんなサイトです。

  • 画像の拡大機能のみが欲しい
  • Cocoon 設定 → 画像より、「 Lity(単機能・軽量)」を選んでいる

この 2 つのコンポーネントは、併用できません。

私が試した限り、併用すると amp-image-lightbox が優先して動作します。

それでは、実装方法をご紹介します。

amp-lightbox-gallery スクリプトの読み込み

amp-lightbox-gallery コンポーネントを使うために、 <head></head> 内でスクリプトを読み込ます。

子テーマの tmp-user / amp-head-insert.php に、下記のスクリプトを追加します。

<script async custom-element="amp-lightbox-gallery" src="https://cdn.ampproject.org/v0/amp-lightbox-gallery-0.1.js"></script>

amp-img の置換

amp-lightbox-gallery は、 <amp-img> に lightbox 属性を付けることで動作します( amp-carousel と併用する時は、 <amp-carousel> に付ける)。

<amp-img> に属性を付けるために、下記のコードを子テーマの functions.php に追加します。

// 独自の AMP 用へのコンテンツ置換
function my_convert_content_for_amp( $the_content ) {
    if( is_amp() === false ) {
        return $the_content;
    }
    
    // amp-img を amp-lightbox-gallery 用に置換
    $pattern     = '/<p><a href="[^"]+?\/wp-content\/uploads.+?"><amp-img(.+?)><\/a><\/p>/i';
    $append      = '<p><amp-img lightbox$1></p>';
    $the_content = preg_replace( $pattern, $append, $the_content );
    
    return $the_content;
}

// AMP 化処理
function html_ampfy_call_back( $html ) {
    if( is_admin() ) {
        return $html;
    }
    
    if( !is_amp() ) {
        return $html;
    }
    
    global $post;
    
    $transient_id    = TRANSIENT_AMP_PREFIX.$post->ID;
    $transient_file  = get_theme_amp_cache_dir().$transient_id;
    $file_path_cache = get_transient( $transient_id );
    
    if( $file_path_cache && DEBUG_CACHE_ENABLE ) {
        if( file_exists( $transient_file ) ) {
            $html_cache = get_file_contents( $transient_file );
            if( $html_cache ) {
                return $html_cache;
            }
        }
    }
    
    $head_tag = null;
    $body_tag = null;
    $style_amp_custom_tag = null;
    
    if( preg_match( '{<!doctype html>.+</head>}is', $html, $m ) ) {
        if( isset( $m[0] ) ) {
            $head_tag = $m[0];
        }
    }
    
    if( preg_match( '{<body .+</html>}is', $html, $m ) ) {
        if( isset( $m[0] ) ) {
            $body_tag = $m[0];
        }
    }
    
    if( preg_match( '{<style amp-custom>.+</style>}is', $head_tag, $m ) ) {
        if( isset( $m[0] ) ) {
            $default_style_amp_custom_tag = $m[0];
            $dieted_style_amp_custom_tag  = get_dieted_amp_css_tag( $default_style_amp_custom_tag, $body_tag );
            
            $head_tag = str_replace( $default_style_amp_custom_tag, $dieted_style_amp_custom_tag, $head_tag );
        }
    }
    
    if( $head_tag && $body_tag ) {
        $body_tag = convert_content_for_amp( $body_tag );
        // 独自の置換処理で body タグ内を AMP 化
        $body_tag = my_convert_content_for_amp( $body_tag );
        $html_all = $head_tag . $body_tag;
        
        $is_include_body = includes_string( $html_all, '</body>' );
        if( $is_include_body && DEBUG_CACHE_ENABLE ) {
            set_transient( $transient_id, $transient_file, DAY_IN_SECONDS * 1 );
            put_file_contents( $transient_file, $html_all );
        }
        
        return $html_all;
    }
    
    return $html;
}

上記のコードで lightbox 属性が付く画像は、下記の 3 つの条件を満たしている画像です。

  • href 属性のみを持った <a></a> が、画像を囲んでいる
  • その href 属性に wp-content/uploads が含まれている
  • <a></a> を、さらに <p></p> が囲んでいる

つまり、画像周りの HTML が、このようになっている必要があります。

<p>
  <a href="サイトURL/wp-content/uploads/~">
    <amp-img 以下略></amp-img>
  </a>
</p>

条件を満たす画像として想定しているのは、「メディアを追加」から「リンク先」を「メディアファイル」で埋め込んだ投稿本文内の画像です。

アフィリエイトバナーなどギャラリーに含めるとまずい画像は、 lightbox 属性は付かないはずです。

CSS を追加

画像が拡大可能であることを分かりやすくするために、 CSS を指定します。

子テーマの amp.css に、下記の CSS を追加します。

amp-img[lightbox] {
  cursor: zoom-in;
}

マウスポインターが画像の上にある時に、マウスカーソルの形状が虫眼鏡に変化します。

ただ、 AMP ページにはスマホからのアクセスがほとんどのはずなので、この CSS の指定は必須ではありません。

あとは、 Cocoon 設定 → キャッシュ削除より、「 AMP キャッシュの削除」を行います。

これでカスタマイズは終わりです。

カスタマイズの注意点

今回のカスタマイズには、 2 つの注意点があります。

注意点:その 1

子テーマの function.php に追加するコードには、親テーマで定義している html_ampfy_call_back() 関数が含まれます。

今後、 Cocoon のアップデートで html_ampfy_call_back() 関数が変更された場合には、アップデート内容が自動的に適用されません。

ご自身で変更に対応する必要がありますが、不安がある場合にはカスタマイズはおすすめできません。

ただ、今回のカスタマイズでの変更は、下記の 2 行を追加しているだけです。

// 独自の置換処理で body タグ内を AMP 化
$body_tag = my_convert_content_for_amp( $body_tag );

注意点:その 2

以前紹介した「【 Cocoon 】AMP で画像拡大表示のライトボックスを実装する方法」をもとに、カスタマイズをされている方への注意点です。

下記の 2 つの理由により、以前のカスタマイズは白紙に戻す必要があります。

  • amp-lightbox-gallery と amp-image-lightbox は併用できない
  • 子テーマの function.php に追加するコードに、同じ関数名を使っている

削除するコードは、子テーマの 3 つのファイルにあります。

  • tmp-user / amp-head-insert.php
  • tmp-user / amp-footer-insert.php
  • function.php

コードを削除後に、今回のカスタマイズを行います。

amp-lightbox-gallery が今後できるようになること

時期は未定ですが、 amp-lightbox-gallery はアップデートが予定されています。

現在は、画像のみが amp-lightbox-gallery の対象です。

しかし、将来は、動画も対象に加わります。

EC サイトや不動産サイトなどに嬉しいアップデートです。

また、ライトボックスビュー内に、広告を設置できるようになります。

おまけ: amp-carousel と併用した例

頂いたコメントを参考に amp-carousel を Cocoon に実装しつつ、 amp-carousel に amp-lightbox-gallery を使った例。


amp-lightbox-gallery は、 Chrome 67 で正常に動作していませんでした。

なので、 1 ヶ月前に記事はほぼ完成していたのですが、記事を公開できなかった…。

けれど、 Chrome 68 でちゃんと動くようになり、やっと紹介できました。

amp-image-lightbox より amp-lightbox-gallery を好む方は、多い気がしないでもない。