Bloggerのトップページを「投稿」で管理
Bloggerのトップページの編集は手間がかかります。
テーマのHTML編集から好きなようにページを作ることはできますが、全体のレイアウトも兼ねているのでミスが怖いですし、見通しもよくありません。
その問題を解決するためにJavaScriptで既存の「投稿」や「ページ」を読み込みして表示するようにしてみました。
トップページの中身を作成
トップページはBloggerの「投稿」や「ページ」で作成します。公開してパーマリンクを確定させたら、そのアドレスを使ってトップページから読み込みに行きます。
「ページ」で作成する際は、タイトルとして入れた文字が半角文字ならそのままアドレスになります。たとえばタイトルにtop-pageと入れると作成されるページのアドレスはhttps://ブログのドメイン/p/top-page.htmlとなります。
中身を取得できるように一つ余分に外枠を作って記述します。もともとのDOMから部分的にコピーしてトップページに持っていきますので、CSSの効果範囲には注意をして記述してください。
外枠はあとでクラス名を使って取得しますので、他と重ならないようにクラス名をつけてください。div要素が最適だと思います。
投稿やページ
<div class="top-page-contents">ここにトップページに持っていきたい記述をします。
</div>
実際のトップページの場所の確認
Bloggerのトップページが記述されているのは通常「ブログの投稿(Blog1)」ウィジット(ガジェット)です。
まず、<b:widget id='Blog1'...>という記述をたよりにブログの投稿を見つけます。その中に、b:includable要素で、idがmainになっているものがあります。ここからスクリプトはスタートします。使用しているレイアウトにより記述方法が様々ですが、その処理のどこかで通常のページ、トップページ、アーカイブページ等に分けて処理が記述されています。
途中でb:includeという要素がでてきたら、そこにnameとして指定してある値をidに持つb:includableを呼び出していることになります。
これを見つけて修正するのが今回の一番の難所です。HTMLの編集する前には必ずバックアップを取っておきましょう。
スクリプト
トップページが記述されている場所を見つけて、HTMLを整えたらスクリプトを挿入します。
動的に取得するページのサイズを固定できるか否かによって少し対応が変わります。スクロール等使って固定できるならCSSで表示箇所のサイズを固定して、非同期通信をしてasyncやdeferで遅延読み込みもすることができます。
固定できないなら同期通信にしてスクリプトも遅延させないほうがいいと思います。後からページを表示させてレイアウトがずれると「CLSの問題」が発生します。
ただ、XMLHttpRequestで同期通信は非推奨なので、それを許容するか、CLSの問題を許容するか、ページの評価的にはどちらがましなのでしょうか? 筆者はこのスクリプトの結果をクローラに認識してもらいたいので、同期の方がいいと考えています。
コードは次のようになります。「投稿」や「ページ」で記述したトップページの中身をクラス名を使って中身を取得し、スクリプトを記述する直前に入れたdiv要素の中にコピーします。「投稿」や「ページ」から中身を取得する際はレスポンス全体を一旦div要素のinnerHTMLに入れることでparseして、そのあとにgetElementsByClassNameで目的の場所を取得しています。div要素のメソッドでgetElementByIdが使えたらな、と筆者は思うのですが、documentからしか使えないそうです。
...
<div id="top-page-reserve"></div>
<script>
const getTopPage = () => {
let req = new XMLHttpRequest();
const strTargetUrl="/p/top-page.html";
const strRemoteTargetElement="top-page-contents";
req.onreadystatechange=() => {
if (req.readyState == 4 && req.status == 200) {
let div = document.createElement('div');
div.innerHTML=req.responseText;
document.getElementById("top-page-reserve").innerHTML=div.getElementsByClassName(strRemoteTargetElement)[0].innerHTML;
}
}
//falseをtrueにすると非同期通信になります。
req.open('GET',strTargetUrl,false);
req.send(null);
}
getTopPage();
</script>
...
これでトップページのコンテンツを変えたい場合は、ページを編集すれば可能になりました。筆者のトップページの場合は、固定ページを少し書き込んだのちに、サイトマップを取り込んで表示しています。