|||||||||||||||||||||

なんぶ電子

- 更新: 

Bloggerのテンプレートを最小化

Bloggerテーマ

Bloggerのテーマは色やサイズ等カスタムもでき便利なのですが、テーマがレスポンシブデザインに対応していないことがあったり、使わない機能が消せなかったりと、逆にそれに制限されてしまうこともあります。

今回はそのような制限から逃るために、独自のページの土台となる最小限のテンプレートXMLを作成します。

Bloggerの構造

Bloggerの構造は、投稿データとそれにまつわるタグなどのメタデータ、画像、テンプレートXMLの大きく3つに分類されます。

ページにアクセスがあると、投稿データやメタデータを読みだし、それをユーザー毎に設定されているテンプレートXMLに当てはめてページを作成します。

画像データに関してはおおむね一般的なWebサーバーと同じ運用ですが、アップロード時に機械的な名前を付けられ、Google photoのアーカイブ領域に保存されたものが表示されます。

テンプレートXML

テンプレートXMLは通常のHTMLの書式に準じた記述の他、Bloggerがページを構成する際に使われる処理命令も記述します。

また、Bloggerのインターフェースからテーマをカスタマイズし背景や文字色などの設定を変更した場合も、その情報がここに記述され、ページ表示時にCSSとして書き起こされます。

これらの「テーマ」をカスタマイズするために設けられている構造は、その意図通りに使う分には便利なのですが、そこから離れて一から自分のオリジナルのページを作ろうとする場合はページソースを汚す余計な記述となってしまうこともあります。

テンプレートXMLで使われているb:ifなどのBlogger独自のタグについて知りたい場合はリンク先の記事を参考にしていただければと思います。

ミニマムなテンプレートXMLの作成

まずは既存のテーマのテンプレートXMLを加工して、Bloggerで表示できる最小限のテンプレートXMLを作成します。

ミニマムな状態から肉付けをすることで、余計な記述や処理のない軽量なページを作れます。

Bloggerのメニューから「テーマ」を選択し、カスタマイズの右側のタブから「バックアップ」を選択するとテンプレートXMLをダウンロードできます。

ダウンロードの前に、BloggerのUIのレイアウトから自分に不要なガジェットは消しておく(必要なものがあれば加えておく)と以後の作業が楽です。

ダウンロードが終わったらXMLを編集していきます。この時、Visual Studio Code(無料)などのコードエディタがあると作業がはかどります。

テンプレートXMLの中身

b:やmacro:などで始まっているタグはBloggerの処理命令です。またdata:となっている箇所ではページ構成処理時にデータを当てはめる場所になっています。このdataはガジェットにより使うことができる種類が変わってきます。詳しくはBloggerヘルプ:「レイアウト用のデータタグ」に掲載されています。

この中のb:sectionで囲まれている部分がBloggerのレイアウトの区切りとなり、b:wedgetがガジェットの区切りになります。

b:includableがプログラム上の「関数」に相当し、b:includeはそれを呼び出す処理をしています。

b:wedget(ガジェット)内にはidの属性値が「main」となっているb:includableが必ずひとつ存在し、処理はそこから始まります。

テンプレートXMLの中身を図式化するとおおむね次のようになっています。

HTML head
HTML body
b:section(Bloggerレイアウト枠)
b:wedget(Bloggerガジェット枠)
b:wedget-settings(Bloggerガジェット設定枠)
b:wedget-setting(Bloggerガジェット設定)
b:wedget-setting
b:includable(Bloggerにおける関数) id=main
idが関数名として扱われます。idがmainとなっているincludable(最初に呼び出されるメイン関数)がガジェット毎に必ず1つあります。
処理やb:include(関数呼び出し)
関数の呼び出しにはb:inculdeタグが使われます。name属性で呼び出す関数名(b:includableのid)を指定しています。
b:includable id=任意
id=main以外のincludableの有無は任意です。
処理やb:include(関数呼び出し)
b:wedget b:section内にガジェットは複数存在できます。
...
b:section テンプレートXML内にb:sectionは複数存在できます。
...

条件分岐を示すb:ifタグやループ構造を作るb:loopタグ、data:はb:sectionタグの外側にも存在できます。デフォルトだとheadで「all-head-content」という、記述のない関数の呼び出しがありますが、これはBloggerのシステムにビルドインされている関数だそうです。

サンプルテンプレート

筆者が作成した「ヘッダー」と「ブログの投稿」だけ残したサンプルは次のようになっています。

b:skinタグはないと動かせないので中身を空にして残しています。同様に消しても復活してくるb:includableも処理の中身を消しています。

headやbodyを閉じる部分で「<!-」としているのは、テンプレートXMLからHTMLを出力する際に、headやbodyタグの出力を契機に自動付与されるJavaScriptをまとめてコメントアウトするためです。この時、必要なタグ自身もコメントアウトに巻き込まれるので、別途出力する記述をしています。

blank.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' expr:lang='data:blog.locale' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>
 
<!-- head出力時に一緒に出力されるJSをエスケープ -->
&lt;!--<head>--&gt;
<!-- エスケープに巻き込まれたheadタグを出力 -->
&lt;head&gt;  
<meta charset='utf-8'/>

<meta content='width=device-width,minimum-scale=1,initial-scale=1' name='viewport'/> 
<b:include data='blog' name='all-head-content'/> 
<title><data:blog.pageTitle/></title>

<b:skin><![CDATA[]]></b:skin>
&lt;!--</head>--&gt;
&lt;/head&gt;
<body>
    <b:section id='section-header'>
      <b:widget id='Header1' locked='true' title='ヘッダー' type='Header' version='1'>
        <b:widget-settings>
          <b:widget-setting name='displayUrl'></b:widget-setting>
          <b:widget-setting name='displayHeight'>260</b:widget-setting>
          <b:widget-setting name='sectionWidth'>719</b:widget-setting>
          <b:widget-setting name='useImage'>true</b:widget-setting>
          <b:widget-setting name='shrinkToFit'>false</b:widget-setting>
          <b:widget-setting name='imagePlacement'>BEHIND</b:widget-setting>
          <b:widget-setting name='displayWidth'>1576</b:widget-setting>
        </b:widget-settings>
        <b:includable id='main'>
          <div>タイトル</div>
        </b:includable>
        <b:includable id='description'/>
        <b:includable id='title'/>
      </b:widget>
    </b:section>
    
    <b:section id='section-main'>
      <b:widget id='Blog1' locked='false' title='ブログの投稿' type='Blog' version='1'>
        <b:widget-settings>
          <b:widget-setting name='showDateHeader'>true</b:widget-setting>
          <b:widget-setting name='style.textcolor'>#000000</b:widget-setting>
          <b:widget-setting name='showShareButtons'>false</b:widget-setting>
          <b:widget-setting name='authorLabel'>By</b:widget-setting>
          <b:widget-setting name='showCommentLink'>false</b:widget-setting>
          <b:widget-setting name='style.urlcolor'>#008000</b:widget-setting>
          <b:widget-setting name='showAuthor'>false</b:widget-setting>
          <b:widget-setting name='disableGooglePlusShare'>true</b:widget-setting>
          <b:widget-setting name='style.linkcolor'>#0000ff</b:widget-setting>
          <b:widget-setting name='style.unittype'>TextAndImage</b:widget-setting>
          <b:widget-setting name='style.bgcolor'>#ffffff</b:widget-setting>
          <b:widget-setting name='reactionsLabel'/>
          <b:widget-setting name='showAuthorProfile'>false</b:widget-setting>
          <b:widget-setting name='style.layout'>1x1</b:widget-setting>
          <b:widget-setting name='showLabels'>false</b:widget-setting>
          <b:widget-setting name='showLocation'>false</b:widget-setting>
          <b:widget-setting name='showTimestamp'>false</b:widget-setting>
          <b:widget-setting name='postsPerAd'>1</b:widget-setting>
          <b:widget-setting name='showBacklinks'>false</b:widget-setting>
          <b:widget-setting name='style.bordercolor'>#ffffff</b:widget-setting>
          <b:widget-setting name='showInlineAds'>false</b:widget-setting>
          <b:widget-setting name='showReactions'>false</b:widget-setting>
        </b:widget-settings>
        <b:includable id='main' var='top'>      
          <!-- 投稿かページなら -->
          <b:if cond='data:blog.pageType in {&quot;static_page&quot;, &quot;item&quot;}'>   
            <b:loop values='data:posts' var='post'>
                <!-- 複数ページがありループで戻ってきていたら、divタグを閉じる -->
                <b:if cond='data:post.isDateStart and not data:post.isFirstPost'>
                    <!-- 閉じタグをそのまま書くと、コードチェックにひっかっかるのでエスケープ -->
                    &lt;/div&gt;&lt;/div&gt;
                </b:if>
                <b:if cond='data:post.isDateStart'>
                    &lt;div class=&quot;date-outer&quot;&gt;
                </b:if>
                <b:if cond='data:post.dateHeader'>
                    <h2 class='date-header'><data:post.dateHeader/></h2>
                </b:if>
                <b:if cond='data:post.isDateStart'>
                    &lt;div class=&quot;date-posts&quot;&gt;
                </b:if>
                <div class='post-outer'>
                    <b:include data='post' name='post'/>         
                </div>
            </b:loop>

            <b:if cond='data:numPosts != 0'>
                &lt;/div&gt;&lt;/div&gt;
            </b:if>

            <!-- 次へ・前へ(必要ならincludableも復元して下さい)
              <b:include name='nextprev'/>
            -->
          <b:else/>
            <!-- 投稿かページ以外 -->
            <b:if cond='data:blog.homepageUrl == data:blog.url'>
              <div>トップページコンテンツ</div>       
            <b:else/>
              <!-- 検索やラベルなどのサマリ表示呼び出し -->
              <b:include data='posts' name='disppostsummary'/>
              <!-- 次へ・前へ(必要ならincludableも復元して下さい)
                <b:include name='nextprev'/>
              -->
            </b:if>
          </b:if>
        </b:includable>
        <b:includable id='backlinkDeleteIcon' var='backlink'/>
        <b:includable id='backlinks' var='post'/>
        <b:includable id='comment-form' var='post'/>
        <b:includable id='commentDeleteIcon' var='comment'/>
        <b:includable id='comment_count_picker' var='post'/>
        <b:includable id='comment_picker' var='post'/>
        <b:includable id='comments' var='post'/> 
        <b:includable id='disppostsummary' var='posts'>
          <!-- 検索やラベルなどのサマリ表示の本体 -->
          <b:loop values='data:posts' var='post'>
            <div>
              <div style='float:left; margin-right:1em;'>
                <a expr:href='data:post.url'><img alt='' expr:src='data:post.thumbnailUrl' height='72' loading='lazy' width='72'/></a>
              </div>
              <div><a expr:href='data:post.url'><data:post.title/></a></div>
              <div>
                <data:post.snippet/>
              </div>
              <hr style='clear:both;'/>
            </div>
          </b:loop>
        </b:includable>
        <b:includable id='feedLinks'/>
        <b:includable id='feedLinksBody' var='links'/>
        <b:includable id='iframe_comments' var='post'/>
        <b:includable id='mobile-index-post' var='post'/>
        <b:includable id='mobile-main' var='top'/>
        <b:includable id='mobile-nextprev'/>
        <b:includable id='mobile-post' var='post'/>
        <b:includable id='nextprev'/>
        <b:includable id='post' var='post'>
          <!-- 投稿・ページ出力本体 -->
          <main>
            <b:if cond='data:post.title'>
              <h1 class='post-title'>
                <b:if cond='data:post.link or (data:post.url and data:blog.url != data:post.url)'>
                  <a expr:href='data:post.link ? data:post.link : data:post.url'><data:post.title/></a>
                <b:else/>
                  <data:post.title/>
                </b:if>
              </h1>
            </b:if>
            <data:post.body/>
          </main>
        </b:includable>
        <b:includable id='postQuickEdit' var='post'/>
        <b:includable id='shareButtons' var='post'/>
        <b:includable id='status-message'/>
        <b:includable id='threaded-comment-form' var='post'/>
        <b:includable id='threaded_comment_js' var='post'/>
        <b:includable id='threaded_comments' var='post'/>
      </b:widget>
    </b:section>
  &lt;!--</body>--&gt;&lt;/body&gt;
</html>

テンプレートXML上でコメントアウトすると、表示されるページソースにはその部分は出力されないことがありました。発生条件も不明で、バクなのか仕様なのかわかりませんが、コメントアウトした部分をページに出力したい場合は先ほど同様に「&lt;!-」という記述を使います。

2022/01追記

headを閉じる場所(/head)をコメントアウトした状態で、BloggerのメニューからAdSense連携をONにすると、意図したように機能しません。

headを閉じる過程でbolggerがHTMLのコメントを出力するのが原因で、HTMLではコメントの多重化は許可されていないため、自動出力のコメント閉じタグでコメントが終わってしまうのが原因です。

そこで筆者は、templateで囲って次のように/headタグを修正しました。template内にheadがあることは既に構造的にはおかしいのですが、少しでも改善するためにtemplate内でhead開始タグを追加して、タグのバランスを保つようにしています。

templateなのでチェックはされますが、レンダリングされません。

&lt;template&gt;<head></head>&lt;/template&gt;
&lt;/head&gt;

また、筆者がblogger立上げた時からお世話になっている「バグ取りの日々」というサイトでもBloggerの空のテンプレートを作る方法を紹介しているようです。こちらを参考にしてhtmlにb:js=falseを加えることで、/headがある状態での軽量化ができました。ありがとうございました。そちらのページでは筆者の方法とはまた違った方法で、/headの問題も解決しているようなので、よろしかったらそちらのページも参考にしてみてください。

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告