前回のpostでhugoの動作確認までできました。 今回は、幾つかthemeにはない要素を追加したいので、themeをカスタマイズしていきます。
hugoでのテンプレートとthemeの考え方
themeのカスタマイズと書きましたが、themeディレクトリ以下のファイルを直接編集はしません。
Section Page Templates#Section Template Lookup Orderによるとテンプレートは下記の順番で探し、最初に見つかったものが適用されるとのこと。 なので、theme以下のテンプレートをlayouts以下にコピーした上で編集します。
- /layouts/section/<SECTION>.html
- /layouts/<SECTION>/list.html
- /layouts/_default/section.html
- /layouts/_default/list.html
- /themes/<THEME>/layouts/section/<SECTION>.html
- /themes/<THEME>/layouts/<SECTION>/list.html
- /themes/<THEME>/layouts/_default/section.html
- /themes/<THEME>/layouts/_default/list.html
サイドバーコンテンツの追加
今回はサイドバーに固定ページのリンクを作りたいので、themes/robust/layouts/partials/sidebar.html
をlayouts/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
これで、問題なく追加されます。しかしハードコードしているので、このままでは固定ページを追加したいときにテンプレートを修正する必要があります。ここに表示される内容を特定コンテンツの場合に自動生成するようにしましょう。
特定のセクションのページをサイドバーに表示する
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.css
はstyles.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の細かい設定を行っていきます。