前回のpostでhugoの動作確認までできました。 今回は、幾つかthemeにはない要素を追加したいので、themeをカスタマイズしていきます。

hugoでのテンプレートとthemeの考え方

themeのカスタマイズと書きましたが、themeディレクトリ以下のファイルを直接編集はしません。

Section Page Templates#Section Template Lookup Orderによるとテンプレートは下記の順番で探し、最初に見つかったものが適用されるとのこと。 なので、theme以下のテンプレートをlayouts以下にコピーした上で編集します。

  1. /layouts/section/<SECTION>.html
  2. /layouts/<SECTION>/list.html
  3. /layouts/_default/section.html
  4. /layouts/_default/list.html
  5. /themes/<THEME>/layouts/section/<SECTION>.html
  6. /themes/<THEME>/layouts/<SECTION>/list.html
  7. /themes/<THEME>/layouts/_default/section.html
  8. /themes/<THEME>/layouts/_default/list.html

サイドバーコンテンツの追加

今回はサイドバーに固定ページのリンクを作りたいので、themes/robust/layouts/partials/sidebar.htmllayouts/partials/へコピーします。

mkdir layouts/partials
cp themes/robust/layouts/partials/sidebar.html layouts/partials/

そしてlayouts/partials/sidebar.htmlを編集していきます。 いい感じの位置に下記内容を挿入しました。

 <aside class="l-sidebar">

  <div class="sections sidebar">
    {{ partial "author.html" . }}
    {{ partial "fixed.html" . }}
    {{ partial "latests.html" . }}
    {{ partial "categories.html" . }}
    {{ partial "tags.html" . }}
  </div>

</aside>

RobustテーマのサイドバーにはLATESTSというブロックがあり、直近10件のコンテンツが表示されます。これに習い、fixed.htmlのpartialを作ります。

<section class="sidebar">
  <header>PINNED</header>
  <div>
    <div class="articles sm">
      {{ with .Site.GetPage "page" "privacypolicy.md" }}
      {{ .Render "li_sm" }}
      {{ end }}
    </div>
  </div>
</section>

そして固定ページをcontents/privacypolicy.mdとして作成しました。

hugo new privacypolicy.md

これで、問題なく追加されます。しかしハードコードしているので、このままでは固定ページを追加したいときにテンプレートを修正する必要があります。ここに表示される内容を特定コンテンツの場合に自動生成するようにしましょう。


Sponsored Link


特定のセクションのページをサイドバーに表示する

hugoにはMenu Templatesという機能があるのですが、今回使用するテンプレートではhugoのページオブジェクトをthemes/robust/layouts/_default/li_sm.htmlに渡すことでカード状のデザインを表示しています。Menu Templatesで得られる値はPageオブジェクトを持っていないため、Pageオブジェクトから対象のPageオブジェクトを抽出します。

hugoにはsectionという概念があり、端的に言うとcontents以下のディレクトリがsectionという単位になります。また、contents直下は無名のセクションとなります。

上記の例では、privacypolicy.htmlはcontents直下に作成してあります。今後も固定ページはcontents直下に作成することとしました。 従って、すべてのPageオブジェクトのうち、無名のセクションに含まれるPageオブジェクトの一覧を得る必要がります。

方法としてwhere関数にてwhere .Site.Pages "Section" ""とすることで、無名のセクションに所属するPageオブジェクトが抜き出せます。第2引数の""は無名のセクションを表します。

ということで下記のようになります。 whereで対象のPageオブジェクトを抽出し、rangeでその値の回数li_sm.htmlをレンダリングしています。

<section class="sidebar">
  <header>FIXED</header>
  <div>
    <div class="articles sm">
      {{ range where .Site.Pages "Section" "" }}
      {{ .Render "li_sm" }}
      {{ end }}
    </div>
  </div>
</section>

そしてhugo serverを起動して動作確認すると、先ほどと同じ表示が確認できるはずです。これで固定ページをいい感じにサイドバーに表示させる仕組みが整いました。今後は固定ページを追加したい際はhugo new ****.mdして内容を書くだけで追加できます。

cssを修正する

今回使うThemeでは、各postにthumbnail(というかアイキャッチ画像?)を設定することができ、設定しない場合でもデフォルトの画像ファイルがthumbnailとして表示されます。

毎回画像を用意することは面倒だけど、毎回デフォルトの画像ファイルにするとトップページに同じ画像がいくつも並ぶことになるため、デフォルトでは非表示にすることとしました。

このThemeではthemes/robust/layouts/partials/styles.cssによってstyleタグにcssが埋め込まれるようです。このファイルをlayouts以下にコピーすることで上書きもできるのですが、themes/robust/layouts/partials/custom.cssというカスタマイズ用の空のファイルが用意されており、custom.cssstyles.cssより優先して適用されるつくりになっています。なので、layouts/partials/custom.cssを作成し、優先的に適用したい内容を記載していきます。

また、styles.cssで定義されている内容をcustom.cssで再定義する場合、styles.cssの記述自体は残る(custom.cssで定義した内容が優先される)ため、少しだけ無駄が発生することになりますが、styles.css自体をlayouts/partials/style.cssで上書きするとsubmoduleとして追加した元のリポジトリの内容が更新されたときに対応範囲が増える可能性がありお勧めできません。

{{ range $p := (where .Site.Pages ".UniqueID" "!=" "") }}
{{ if eq $p.Params.thumbnail nil }}
.thumb-{{ $p.UniqueID }} {
  display: none;
}
{{ else }}
.thumb-{{ $p.UniqueID }} {
  background-image: url({{ $.Site.BaseURL }}{{ $p.Params.thumbnail  }});
}
{{ end }}
{{ end }}

詳細は省きますが、下記のような修正を行っています。

  • デフォルトの画像ファイルを表示しないようにする
  • FrontMatterでthumbnailが指定されていない場合は.thumb-****が適用されたエレメントを非表示にし、指定されている場合はその画像を表示する
  • 上記に伴い記事部分のエレメントの高さを自動調整する

この次は

ここまででデザインの修正をひとまず終わらせることにしました。この次はHugoの細かい設定を行っていきます。