EDIT

【Blogger】F-light テーマ制作ノート

2023/09/062
アイキャッチ

オリジナルテーマ制作着手から完成までの経緯を記しておきます。自分用のメモですが、どなたかの参考にも…なるかな?

Twitter での自分のツイートも纏めてありますのでよろしければこちらもどうぞ。

Blogger テーマ F-light (エフライト) 制作ノート - min.t (ミント)

着手

2020年2月頃、Bloggerの空テンプレートを作成する | バグ取りの日々という記事を参考に、真っ更な状態のブランクテーマにブログウィジェットだけ付けて、なんとか記事だけは表示出来る状態にまでできたものの、さてどこから手を付けたらいいのやら…と途方に暮れてしまい、ほとんど弄ることもなく挫折。時々気が向くと弄ってみるものの、ほぼ放置状態で2年以上が過ぎていました。

QooQ ウィジェットの v2 化

今年の5月頃に、v1 の QooQ のウィジェット(ラベルなど)のウィジェットタグを書き換えて無理やり v2 にして保存してもエラーにならないことを発見。確か以前は保存すると v1 に戻されてしまったはずだけど、仕様が変わったのか、自分の勘違いだったのかは不明。

<b:widget id='Label1' locked='false' title='ラベル' type='Label' version='2' visible='true'>

<html> タグに b:defaultwidgetversion='2' 属性を追加すれば、以降追加するウィジェットは自動的に v2 になることもわかりました。

ただし、ブログウィジェットだけは仕様が異なるため、このやり方で単純に v2 化させることは不可能。という訳でサブコンテンツだけが v2 という中途半端な状態に。この時点ではまだ v2 ブログウィジェットを弄るつもりは全くありませんでした。

Tricktree FB のバージョンアップ

上記のようにデフォルトバージョンを 2 にするやり方がわかったので、Tricktree FB もデフォルトウィジェットバージョンを 2 に変更。リンクリストも v2 になりました。

その後、固定ページ機能を付けてみることになり、放置中のテーマ(仮称 Flaw)の xml からブログウィジェットだけを移植してみたところ、問題なく追加でき、個別ページも表示されました。

コードがとっちらかってて何がなにやら分かりづらいし、不要なものも結構ありそうな感じなので一旦 b:includable を全て空にして整理することに。この作業は mizusame さんの【Blogger】b:includable タグの中身一括削除ツールのお陰で大変効率よくできました。

全て空の状態だと当然ページも空になって何も表示されません。というわけで本文を表示させるべく、必要な includable だけを取捨選択してみた結果、postpostBodypostTitle の3つだけあればいいということがわかりました。

Tricktree FB の場合はあくまでページ機能はオマケという扱いなので、これで目的は達成です。思ってたよりも簡単にできてしまいました。

この b:includable タグ を整理する作業で色々調べている内に次第に v2 の仕様や構造が理解できてきたことでやる気スイッチが入って、ふじろじっくのブログウィジェットの v2 化に挑戦して見ようとなったわけです。

ブログウィジェット v2 化

中途半端に v2 化されたふじろじっくの v1 ブログウィジェットを Flaw の v2 ブログウィジェット と入れ替え。Tricktree FB の時と同じ要領で個別ページの表示もでき、記事一覧のリストの表示まではとりあえずはできました。

入替え前の v1 ブログウィジェットのコードと見比べつつ、クラス名や ID を v2 の当該箇所に一つ一つ嵌めていったところ、ほぼ元のスタイルを復元することが出来ました。

次はコメント欄。コメントに関しては v1 ではなく v2 のコードを参考に構築。今までノータッチだった「埋め込み」や「ポップアップウィンドウ」のオプションも使えるようにしました。もちろん、ふじろじっく独自仕様の「埋め込み/別ページ 併用仕様」も復元。

もうこれで半分終わったぞ!って感覚ですっかりテンション上がってしまいましたが、実はここからが結構大変でした(^^;

data タグの置き換え

一見問題なく実装できてるように見えましたが、所々で表示がおかしかったり表示自体がされていない箇所が。どうやら v1 と v2 では data タグの名前や仕様が違っていたり v2 で廃止されていたりするものもあるらしく、それらを v2 で使えるものに置き換える必要があるのです。Soraya さんのブログを見て初めてこの事を知りました(^^;

ファビコンBlogger Code PE
サムネイル
Les équivalents des données des gadgets version 1 dans l…(バージョン 1 のガジェット データに相当するバージョン 2)
La liste des données Version 1 qui ont été renommées, déplacé…
http://bloggercode-blogconnexion.blogspot.com/2019/05/upgrade-data-v1-to-V2.html

この記事には v1 と v2 data の対応表が紹介されていますが、この記事に書かれていない data も他にいくつもあって、検索で探しながら一つ一つ地道に置き換え作業を行いました。

投稿日 / 更新日

これも当初、時刻表示がバグって「NaN」になってしまってましたが、タグの置き換えで難なく修正。

v2 の場合はタイムゾーン時刻表示フォーマットのカスタマイズもやりやすいので、更新日表示のスクリプトも自力で書けるほど簡単でした。

投稿日と同じ場合にだけ更新日を表示させるスクリプトの v1 の時と v2 の比較です。投稿日も更新日も同じフォーマットで出力できるので、同じかどうか判別させる部分のコードがシンプルで済みます。

<script>
  const pub_date=new Date(&quot;<data:post.timestampISO8601/>&quot;);
  const up_date=new Date(&quot;<data:post.lastUpdatedISO8601/>&quot;);
/*<![CDATA[*/
  const pub_y=pub_date.getFullYear();const pub_m=("0"+(pub_date.getMonth()+1)).slice(-2);const pub_d=("0"+pub_date.getDate()).slice(-2);const up_y=up_date.getFullYear();const up_m=("0"+(up_date.getMonth()+1)).slice(-2);const up_d=("0"+up_date.getDate()).slice(-2);if(pub_y!=up_y||pub_m!=up_m||pub_d!=up_d){const up_text="|<svg aria-label='更新日' class='svg svg-arrows-rotate' style='margin:0 5px 0 8px'><use href='#svg-arrows-rotate'/></svg>"+up_y+"/"+up_m+"/"+up_d;document.getElementById("single-header-update").innerHTML=up_text};
/*]]>*/</script>
↓↓
<script>
  const p_date=&#39;<data:post.date.year/>/<b:eval expr='data:post.date.month lt 10 ? &quot;0&quot; + data:post.date.month : data:post.date.month'/>/<b:eval expr='data:post.date.day lt 10 ? &quot;0&quot; + data:post.date.day : data:post.date.day'/>&#39;;
  const u_date=&#39;<data:post.lastUpdated.year/>/<b:eval expr='data:post.lastUpdated.month lt 10 ? &quot;0&quot; + data:post.lastUpdated.month : data:post.lastUpdated.month'/>/<b:eval expr='data:post.lastUpdated.day lt 10 ? &quot;0&quot; + data:post.lastUpdated.day : data:post.lastUpdated.day'/>&#39;;
/*<![CDATA[*/
  p_date!=u_date&&(document.querySelector("#p-header-udate").innerHTML='&nbsp;\uFF5C<svg aria-label="更新日" class="svg svg-arrows-rotate" style="margin:0 5px 0 8px"><use href="#svg-arrows-rotate"/></svg>'+u_date)
/*]]>*/
</script>

2022/08/24 追記: JavaScript は使わず Blogger 独自タグによる処理に変更しました。

投稿日も更新日も同じフォーマットで出力できるということは、JavaScript を使わずとも独自タグで表示・非表示の処理ができることに気づいたので、以下のようなコードに変更しました。年・月・日のいずれかが違う場合に更新日が表示されます。

<b:if cond='data:post.date.year != data:post.lastUpdated.year or data:post.date.month != data:post.lastUpdated.month or data:post.date.day !=  data:post.lastUpdated.day'>
    <span id='p-header-udate'><svg aria-label="更新日" class="svg svg-arrows-rotate" style="margin:0 5px 0 8px"><use href="#svg-arrows-rotate"/></svg><data:post.lastUpdated.year/>/<b:eval expr='data:post.lastUpdated.month lt 10 ? &quot;0&quot; + data:post.lastUpdated.month : data:post.lastUpdated.month'/>/<b:eval expr='data:post.lastUpdated.day lt 10 ? &quot;0&quot; + data:post.lastUpdated.day : data:post.lastUpdated.day'/></span>
</b:if>

記事一覧アイキャッチ画像の WebP 化スクリプト

v2 でも IB-Note さんのスクリプトコードを使わせて頂くことにしましたが、画像 URL を取得するための data タグを変えれば、複雑な正規表現などを使わなくてもシンプルに出来ることがわかったので、一部を改造。

resizeImage を使えば、新旧どちらの URL でも必ず p-k-no-nu (YouTube は n-k-no-nu)というパラメータが付けられるので、-k-no-nu だけ置き換えてやればいいということです。

例:
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPlV3CoJmGeSFY5ZpENs9cXfAb4w1hnuWX3PnvYKMvgMGnK3Vlsi5Ns-i7LTJrEg6uv3jSO1CaBQFViVbSQHxm-Yff2qAtdD0ZHXDksUiPl3iQdVQAiz4g0TT0uSLxA0V-4DczqLddo3I/w320-h180-p-k-no-nu/F-light-production-notes.png

<script>
(function () {
  const idx = <data:i/> ;
  let img = "<b:eval expr='resizeImage(data:post.featuredImage, 320, "16:9")'/>";
  let webp;
  if (img.match(/-k-no-nu/)) {
    webp = img.replace('-k-no-nu', '-rw-e365');
  }
  if (img.match(/lh3-testonly/)) { // YouTube 例外対応
    webp=img.replace('lh3-testonly', 'lh3').replace('-k-no-nu', '-rw-e365');
  }
  let eyecatch = document.getElementsByClassName('article-img')[idx];
  let html = '';
  html += '&lt;img alt="<data:post.title.escaped/>" height="180" data-src="' + webp + '" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZJl0lD6fAzWtKis0dtNx5u2dCpGeRe-geIuBXUsdSZOUlrcdjPt0rlzM3ZD7oW-oeMeY8REjMGUpu__hAQV3cEgIIN9Ng0AhyKrrRxtIKWZKdDw0gaRMH_Ue31u25pV-HkiGLoR6lQ3DH/w320-c-h180-rw/blank.png"/&gt;';
  eyecatch.innerHTML = html;
}());
</script>

置き換え後 URL:
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPlV3CoJmGeSFY5ZpENs9cXfAb4w1hnuWX3PnvYKMvgMGnK3Vlsi5Ns-i7LTJrEg6uv3jSO1CaBQFViVbSQHxm-Yff2qAtdD0ZHXDksUiPl3iQdVQAiz4g0TT0uSLxA0V-4DczqLddo3I/w320-h180-p-rw-e365/F-light-production-notes.png

ブログウィジェットのその他の部分

なるべく効率がよくなるような配置や構成を考えて構築。これで一応ブログウィジェットに関しては完了しました。

その他のウィジェット

「注目の投稿」と「人気の投稿」

トップページを2カラム化した時に検討していたウィジェットの追加をすることに。とりあえず定番の「注目の投稿」と「人気の投稿」の2つ。

ウィジェットを追加した直後は何故か main の includable しかない状態で、細部のカスタマイズは困難なのか??と困惑しましたが、試しに影響なさそうなところをちょこっと変更して保存してみたところ、それまで消えていた各種 includable が見えるようになりカスタマイズ出来る状態に! でもなんで最初から出しといてくれないんだろう?(^^;

どうやらブログウィジェットと構造が似ているようで、記事一覧ページのリストと同じデザインにしたり、先述の Webp 変換スクリプトの実装もできそうな感じ。クラスや ID だけ変えてコードを移植してみたところ、どちらもバッチリいい感じに。

注目の投稿の方はメインカラムの一番上に置いたため、トップページ記事一覧リストと区別できるようにデザインを工夫。タイトル横のマークが記事一覧が■なのに対し、注目の投稿は★になっています(^^;

プロフィールウィジェット

この辺りまで来ると次第にテーマの公開配布も考えるようになり、プロフィールウィジェットも用意することに。ふじろじっくでは HTML ウィジェットで自作していますが、デフォルトのウィジェットもちゃんと表示されるように調整します。

プロフウィジェットはあまり使ったことがなくて今まで知らなかったのですが、ブログの管理者が複数いる場合は全員のリスト(アイコンと名前のみ)が表示される仕様になっています。プロフが非公開でもリストに載ってしまい、表示するプロフを選択するオプションもない模様。サブ垢のテストブログでメイン垢も共同管理者として登録していたためこの仕様に気づくことが出来ました。というわけで通常の管理者が一人だけの場合と複数の場合の両方に適用できるように CSS を調整。HTML に関しては、複数ユーザーの詳細リンクを付けた以外に大きな変更は加えていません。

プロフィールウィジェット

ラベルウィジェット

v1 と構造は同じなので特に苦労はなく、ハッシュタグ振り分け機能も問題なく機能。

defaultmarkup 機能

v2 独自の機能として defaultmarkup という機能があります。実は今までその存在理由もわかっていなかったのですが、結城永人さんの Bloggerのdefaultmarkupタグの最初は便利で最後は不要な使い方という記事を読んで漸くその便利さを知ることが出来ました(^^;

要するに、ウィジェットのカスタマイズ済みの設定(各 includable)を defaultmarkup タグで囲って置くと初期設定として保存され、同じウィジェットを新規追加した時に、カスタマイズ済みの includable が自動的に適用されるというもの。

F-light では、ハッシュタグ機能が復元されるようにするため、ラベルウィジェットだけ defaultmarkup として実装しました。

基本構造の見直しと最終チェック

メインやサブを囲っている div などの無駄なものは極力外したり別のタグに置き換えるなど、構造を見直し。レイアウトが崩れたところは CSS で調整。class や ID も全て名前を変更。

これで一応理想のテーマは完成。あとは徹底的にバグのチェックとテストを実施。

一般公開へ

着手前の時点でフルカスタマイズしていたので既に QooQ とはほぼ別物状態になっていましたが、今回の v2 化により完全に別物になりましたので、テンプレートを公開しようという判断に至り、リリースすることとなりました。

その判断へのご意見も含め、F-light テンプレートに対するご指摘、ご質問等ありましたら、コメントで伝えていたければ幸いです。