先日サイトのテーマをbootstrap4に変更したのですが、以前(旧boostrapテンプレート使用時)から気になっていた点がありました。

それはヘッダーイメージとして画像ファイルが指定できるのですが、ページ内のメディアファイルに限定されてしまうという点です。

ページメディア

ページのヘッダーイメージを指定する項目はあるのですが、ページメディアに限定されてしまうのです。
※ページのヘッダーイメージを使用してファイルを指定しなかった場合は自動的にページメディアの先頭ファイルが使用されます。

サイト内ファイルや外部リンクを指定しても、無視されてしまうようで、何も表示されません。

それで一体何が困るのかというと、同一のカテゴリの記事を書く場合同じヘッダーイメージを使いまわしているのですが、上記の仕様では毎回ページ内に同じファイルを配置しなければなりません。

つまり、全く同じ内容の画像を複数アップロードしている状態です。

Gravはメディアファイルを適切に加工してサイズや容量を削減してくれますが、それでも数100キロバイトのファイルが何十枚もあればそこそこの容量になり、サーバーのリソースを食いますし、なによりページが表示されるたびに見た目は同じなのに別のファイルが読み込まれるという、WEBエンジニアとしてはなんともいえない気持ち悪さが残ります。

ネットインフラの進歩で数100キロバイト程度は問題ないかもしれませんが、チリも積もればマウンテン。
ページの読み込みは少しでも早いほうがいいと考えてしまうのがエンジニアの性。

ということでテンプレートを覗いてみました。
該当する箇所は以下の通り

File:themes/bootstrap4/templates/partials/blog_item.html.twig

~~~
        {% if big_header %}
            {{ page.media.images|first.cropResize(900,600).html('','blog-header-image')|raw }}
        {% else %}
            {% if header_image %}
                {% if header_image_file %}
                    {% set header_image_media = page.media.images[header_image_file] %}
                {% else %}
                    {% set header_image_media = page.media.images|first %}
                {% endif %}
                {{ header_image_media.cropZoom(header_image_width, header_image_height).html|raw }}
            {% endif %}
        {% endif %}
~~~

header_image 変数がヘッダーイメージ使用フラグ、header_image_file 変数が指定したヘッダーイメージのファイル名です。

みごとにページメディアオブジェクト(page.media.images変数)からファイル名を使用して画像情報を引っ張ろうとしてますね。

これではどんな指定をしても同ページ内のメディアからしか画像が指定できません。
なのでこの部分を改変します。

File:themes/bootstrap4/templates/partials/blog_item.html.twig

~~~
        {% if header_image %}
            {% if header_image_file %}
                {% set header_image_media = page.media.images[header_image_file] %}
                {% if page.media.images[header_image_file] %}
                    {% if big_header %}
                        {{ header_image_media.cropResize(900, 600).html('',page.title)|raw }}
                    {% else %}
                        {{ header_image_media.cropZoom(header_image_width, header_image_height).html('',page.title)|raw }}
                    {% endif %}
                {% else %}
                    <img alt="{{ page.title }}" src="{{ header_image_file }}" />
                {% endif %}
            {% else %}
                {% if big_header %}
                    {{ page.media.images|first.cropResize(900, 600).html('',page.title)|raw }}
                {% else %}
                    {{ page.media.images|first.cropZoom(header_image_width, header_image_height).html('',page.title)|raw }}
                {% endif %}
            {% endif %}
        {% endif %}
~~~

要約すると header_image が有効で header_image_file に指定があった場合、尚且つ page.media.images オブジェクトに header_image_file というファイルが存在しない場合は、header_image_file を文字列としてそのままimgタグのsrc 属性に突っ込んでます。

はい、まったくもってエレガントではないですね。
同じような処理が繰り返されるうえにコードも長い(;・∀・)

 

ま、まあ、狙った動きにはなっているのでよしとしましょう。
※時間があったら最適化できないか検討します。

これで、ページオプションで指定したサイト内画像をそのままソースに利用してくれるので、同一ファイルを指定することで各ページで同じファイルを使いまわしてくれるようになります。

Post If you feel like it, I would be happy if you could post it.