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

Akira

福岡在住ウェブデザイナー。Web サイト制作に役立つ情報を紹介しています。AMP が大好き。

FacebookTwitter で記事の更新をお知らせしています。

Cocoon 1.1.8 で amp-lightbox-gallery が実装されたため、カスタマイズは不要になりました。また、当記事をもとにカスタマイズをされた場合は、カスタマイズ箇所を削除し、Cocoon 親テーマをアップデートされることを強くおすすめします。Cocoon での設定方法は、「AMPページの画像拡大効果のLightbox・ギャラリー表示について」をご参考ください。

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

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

動作

Cocoon の AMP ページに Lightbox 風の画像ギャラリーを実装後は、画像のタップで画像の「拡大表示」「スライド表示」「一覧表示」が可能です。

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

Example: <amp-lightbox-gallery> – amp.dev にて、実際の動作を体験できます。

amp-image-lightbox との違い

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

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

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

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

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

<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() ) {
    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;
}

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

  • 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 つの注意点があります。

親テーマのアップデートが適用されない

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

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

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

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

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

amp-image-lightbox のカスタマイズと併用は不可

以前紹介した【 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 を使った例。

コメント

  1. 早速試してみました!
    AMPでスライド表示ができるとのこてで

    画像は普通に縦に並ぶんですね・・

    画像が多いサイトは
    amp-carouselで良いような気がします

    • amp-lightbox-gallery は Lightbox の動作なので、画像をクリックしないとスライド表示にはならないです。

      最初からカルーセルやスライダーで画像を表示するには、 Gacoon さんのおっしゃる通り amp-carousel がぴったりです。

      それに、 amp-carousel に対して、 amp-lightbox-gallery が使えるのも魅力です。

      面白そうでしたので、 Cocoon で amp-carousel と amp-lightbox-gallery を併用してみました。

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

      また、 AMP by Example「 Usage with Carousel 」 でも、併用例をご確認いただけます。

      amp-carousel だけではできない、ギャラリーを実装できるのは魅力に感じます。

      暗い背景で画像が目立つのもポイントが高いです。

      さらに、ユーザーに対して 2 つの画像の閲覧方法を提供でき、使い勝手の良いサイトになります。

      amp-carousel と amp-lightbox-gallery は、とても相性が良いと思います。

  2. これ、本題よりイイですねw
    Cocoon で amp-carousel と amp-lightbox-gallery の実装方法
    是非ご教示ください
    m(__)m

    • AMP のことだけしか考えないのであれば、このような感じで実装できます。

      amp-lightbox-gallery スクリプトは、すでに読み込んでいるとします。

      ① 子テーマの tmp-user / amp-head-insert.php で、 amp-carousel スクリプトを読み込み。

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

      ② 「カスタム HTML 」 ウィジェットをお好きなウィジェットエリアに放り込み、表示設定で AMP ページのみで表示するようにする。

      ③ 「カスタム HTML 」 ウィジェットに、画像の HTML を書く。 Cocoon であれば、画像は <img> でも可。その画像を lightbox 属性のある <amp-carousel> で囲む。

      <amp-carousel
        lightbox
        height="225"
        layout="fixed-height">
        <amp-img
          src="#"
          width="400"
          height="225">
        </amp-img>
        <amp-img
          src="#"
          width="400"
          height="225">
        </amp-img>
      </amp-carousel>

      基本的な実装は、これで終わりです。

      あとは width や height の値、 layout 属性、 amp-carousel のオプションの微調整が必要です。

      通常ページにもカルーセルを設置する場合には、 amp-carousel と同じ動作になるよう JavaScript を書く必要があります。 Swiper であれば、 amp-carousel に似せることはできるかもしれません。

送信に失敗しました

ボットと判定された可能性があります。

大変お手数をおかけしますが、以下の内容をご確認の上、再度のコメントの送信をお願い申し上げます。