Shopifyの画像の出力時、対象画像の存在有無は確認できない

Shopify

調べたことのメモとして。根拠の投稿が少し古いので現在ではできるのかもしれませんが、調べた限りでは見つからず。

実現したいこと

  • {{ 'example.jpg' | image_url | img_tag }}で画像を表示させる
  • 対象画像が取得できない場合は別の画像を表示させる

上記が実現したいことでした。

調査結果

ある種結論ですが、2013年のShopifyスタッフによる以下の投稿があります。

Hi Graham, no theme checks for the presence of an image in the theme assets. It’s not possible as far as I know to do that.

For each image, you must add a checkbox in the theme settings, and assume that your user will know to toggle it on and off, when he wants to show the image, or hide it.

要約すると以下のようになると思います。

  • テーマのアセットに画像があるかどうかをチェックすることは不可能(この発言者の知る限りは)
  • 存在チェックではなく、ユーザーが画像を非表示にできる機能をつけることが必要

書き方次第ではfalsenullのような値が帰ってくると思ったのですが、判定方法がない模様です。

参考にできない実現方法

前出の投稿のあとで以下のようにJSを使って判定する方法の投稿がありました。


function checkImage(src) {
  var img = new Image();
  img.onload = function() {
  	/* we haz image */
  };
  
  img.onerror = function() {
  	/* no image */
  };

  img.src = src; 
}

checkImage('{{ asset_url | 'somepic.jpg'}}');

onerrorを用いる方法なのでShopifyに限らず使える方法ですが、試しに作って動かすと以下のような状態になりました。

  • 画像のエラーを検知して動くため、エラー自体は消せず、無駄なリクエストと404エラーが発生する

普通のユーザーは開発者ツールは開いていないので404エラーを確認できないとは思いますが、存在しない画像の読み込みは表示速度の低下要因ではありますし、あまり実用的とは思えませんでした。

ただ、コード次第にはなりますが何らかのミスで一時的に画像が存在しなくなった場合の一時凌ぎにはなるかもしれません。
少なくとも画面上は画像壊れではない状態になるため、短期間ならば許容できそうではあります。

一応ですが、試作したコードを自分用のメモとして記載します。
どうなるのかを確認するためだったのでかなり適当ですし参考にしないでください。


{% unless link.links == blank %}
  <ul class="local-nav__sub">
  {% for sub_link in link.links %}
    <li class="local-nav__sub__item">
      <a href="{{ sub_link.url }}" class="local-nav__sub__item__link">
        {%- if sub_link.type == 'collection_link' -%}
          {% assign subLinkHandle = sub_link.url | split: "/" | last | append: '.jpg' %}
          <div id='local-nav__sub__{{ subLinkHandle }}__image--{{ forloop.index}}'></div>
          <script>
            function checkImage(src) {
              var img = new Image();
              var t = document.getElementById('local-nav__sub__{{ subLinkHandle }}__image--{{ forloop.index}}');
              var imgTag = document.createElement('img');
              img.onload = function() {
                imgTag.src = src;
                imgTag.alt = '{{ sub_link.title }}';
                t.appendChild(imgTag);
              }
              img.onerror = function() {
                imgTag.src = '{{ 'noimage.jpg' | asset_img_url: '300x' }}';
                imgTag.alt = '';
                t.appendChild(imgTag);
              };
              img.src = src;
            }
            checkImage('{{ subLinkHandle | file_img_url: '300x' }}');
          </script>
        {%- endif -%}
        <div>{{ sub_link.title | escape }}</div>
      </a>
    </li>
  {% endfor %}
  </ul>
{% endunless %}

結び

何かしら方法はあるのではと思ったものの、正規の方法が用意されているわけではありませんでした。

代替案も微妙なところがあるので、現状では実現不可という認識です。

0人がこの記事を評価

役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。

連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。

コメント欄