Wordpress

Lazy Block製Blog Cardをパワーアップ

久々のLazy Blockネタにゃー
以前作ったBlog Cardをパワーアップしよう
ということで長らく適当なアイコンを使っていた箇所をサイトのスクリーンショットにするにゃー

人物のアイコン素材 その5

本当に久しぶりですね
よくあの適当なやつを放置していましたね

失敬な!
あれはあれでリンクとわかりやすいアイコンだっただろーが!

人物のアイコン素材 その5

そうなんですけど
ソレ以前にデザイン性がね
アレだからね

何を言いたいのかよくわからんが
久しぶりにLazy Blockの画面を開いたらビビったぞ!
CSSやJSの設定項目も追加されているぞ!
これでカスタムブロックに紐づいたCSSとJSも同時に管理できて最高じゃあないか!

人物のアイコン素材 その5

アレ、本当だ!
テーマのCSSとの衝突までは考慮されないでしょうけど
配布する際に便利なので開発者の方には刺さる機能ですね!

今までは無理やり全部一つのコードの中に押し込めていたけどこれはイイね!
早速使おう!

人物のアイコン素材 その5

いや、どうやらこれはPro版だけの機能みたいですね

なんだよ!
つまらん!

人物のアイコン素材 その5

テーマ開発者とかのプロフェッショナル向け機能なのでまさにPro版で解放されるのでしょう

まあいい
話をもとに戻すとスクリーンショット機能だけど
元々Handlebarsだけで作り込んでいたのでこれだけで実現するのは不可能
Web APIを探索してスクリーンショットが取れるやつを見つけたにゃー

人物のアイコン素材 その5

そういうAPIが公開されているのですね

いくつか同種のAPIがあったのだけどwordpress.comが提供しているmShotsというやつがあったのにゃー
非公式のサービスらしいけどほかでも動作実績があるらしいのでこれを採用したにゃー

人物のアイコン素材 その5

大丈夫なのか?

大丈夫だろ
ダメだったらもとに戻すだけだし

人物のアイコン素材 その5

不安だな

あとはAPIから戻ってきた画像を貼り付けるだけなんだけど
このAPI呼び出しがなかなか大変だったので実際のコードを見ながら解説していきたいにゃー

コードのポイント解説

{{#compare url '&&' string}}
  {{#if newopen}}
<a class="bcv1-container1 bcv1-clay" href="{{url}}" target="_blank" rel="noopener noreferrer">
  {{else}}
<a class="bcv1-container1 bcv1-clay" href="{{url}}">
  {{/if}}
  <div class="item1 bcv1-clay">
    {{string}}
  </div>
  <picture class="item2 bcv1-clay">
    <img loading="lazy" decoding="async" alt="{{truncate string 30 'true'}}" class="lazy" src="" onerror="this.onerror=null;this.dataset.src='https://s.wordpress.com/mshots/v1/' + encodeURIComponent('{{url}}') + '?w=150&h=150';this.src=this.dataset.src;" data-src="">
  </picture>
</a>
{{/compare}}
人物のアイコン素材 その5

これが実際のコードですね

うむ
ポイントとなるのはimgタグの部分にゃー

人物のアイコン素材 その5

なにやら以前と比べて増えてますね

APIはhttps://s.wordpress.com/mshots/v1/[対象URL]の形で呼び出すにゃー
wとかhは画像サイズのパラメータにゃー

人物のアイコン素材 その5

Lazy Blocksとしては対象URLを入力するブロックを作ればよい、ということですね

そうなのにゃー
だけど問題があって対象URLにパラメータが含まれているとAPIのパラメータと区別がつかなくなるにゃー

人物のアイコン素材 その5

あー
APIのパラメータとして受け取ってしまって正しい対象URLにならないということですね

たまにパラメータ指定でしかコンテンツ生成しないサイトがあるからにゃー
でこの問題を回避するには対象URLの部分をエスケープ処理しないといけないのにゃー

人物のアイコン素材 その5

Handlebarsにはその機能はないのですか?

HTMLのエスケープ処理はできるみたいだけどURLパラメータのエスケープ処理はないみたいにゃー
で、調べてみると標準関数でencodeURIComponent()というやつがあったのにゃー

人物のアイコン素材 その5

なるほど
だからこれを使っているのですね

これってJavaScriptだから呼び出さないといけないのだけど
srcの部分に直接書いても呼び出してくれないのにゃー

人物のアイコン素材 その5

普通にURLとして認識されてしまうということですね

うむ
普通はscriptタグとか使ったりが必要だけど実行するトリガーも考えないとダメにゃー
で、もう少し調べるとイベントハンドラの中だったら使えるということでonerrorの中で呼び出すことにしたのにゃー

人物のアイコン素材 その5

onerrorのトリガーはどうやっているのでしょうか?

srcに画像のURLを指定せず空にすることでエラーを誘発しているにゃー

人物のアイコン素材 その5

なるほど
それでエラーをトリガーとしてonerrorで関数を呼び出している、と

それでonerrorを呼んで
最初にthis.onerror=null;でもう一度呼ばれないようにonerrorをクリアしているにゃー

人物のアイコン素材 その5

実際に画像を読み込んで失敗したら無限ループになりますからね

その次のthis.dataset.src=…..の部分がAPIで画像を拾ってくる部分にゃー
ここでencodeURIComponent()でエスケープ処理しているにゃー

人物のアイコン素材 その5

this.dataset.srcってなんですか?

data-srcのことにゃー
どうやらWordPressはLazy loadingでdata-srcを見ているみたいなのでまずはここにURLをセットにゃー

人物のアイコン素材 その5

なるほど
こちらも元々空でセットされていますね
その後にthis.src=this.dataset.src;で同じURLにしている、と

おそらくdata-srcだけセットすればLazy loadingの処理の中でsrcにも値をセットするのだろうけどよくわからんからこちらで指定しているにゃー

人物のアイコン素材 その5

かなりトリッキーですね

まとめると
srcが空だからエラーが発生
onerrorでAPI向けのURLを組み立て(encodeURIComponentの実行)
this.dataset.srcにURLをセットして画像を読み込み
という流れにゃー

人物のアイコン素材 その5

これ以上機能を増やすのならば素直にPHPで作ったほうがいいかもしれませんね

onerrorを使うのがなかなかのトリッキーだからね
これ自体XSSの心配があるけどonerror自体は非推奨ではないらしいのでいいかな、と

人物のアイコン素材 その5

初回はちゃんと画像が出ないですね

サーバ側でキャッシュされてないと生成中画像しか出ないみたいにゃー
リロードすると画像が出るにゃー

人物のアイコン素材 その5

取得失敗でもなんらかの画像は返してくれるのでそこの処理は考えなくてよかったですね

頑張ればHandlebarsでもなんとかなるということがわかったのでよかったにゃー

人物のアイコン素材 その5

素直にPHPを使えばもう少し楽に実装できたのでは!?

それでは今回はこの辺で
Arrivederci

人物のアイコン素材 その5

ミラノ・コルティナダンペッツォオリンピックの影響か!?

,