hugoで記事の一部を共通化したくなったのですが、共通記事をMarkdownで書けて、includeするという機能がhugo 0.13には無かったので、なんとかincludeを実現する方法を考えてみました。
まず運用として、共通記事はpartsというセクションに作ることにしてください。セクション名を決め打ちにしておくことで、テンプレートを使える、サイトマップやRSSに共通記事を出さないようにする、といったメリットが出ます。
include
というshortcodeを自作する
{{ $filename := index .Params 0 }}
{{ range .Page.Node.Site.Pages }}
{{ if eq .Source.File.Path $filename }}
{{ .Content }}
{{ end }}
{{ end }}
共通記事用のテンプレートを作る
Hugoの不具合?で、共通記事の投稿日がinclude元記事の投稿日よりも古いか、共通記事のweightがinclude元記事のweightより大きい場合に、コンテンツの読み込みに失敗することがあるようです。これを回避するために、意図的にweightを下げた共通記事用テンプレートを容易しておきます。
---
date: "2012-04-06"
weight: -999999
# This weight is to prevent content loading issue.
# If partial post is older or lighter than main post,
# the partial post sometimes be not loaded.
# This seems to be Hugo's bug.
---
このテンプレートはファイル名が重要です。Hugoはテンプレートのファイル名をセクション名として認識します。つまり、parts.mdの「parts」の部分はセクション名として解釈されます。従って、hugo new parts/common.md
とすると、自動的にこのテンプレートをベースに共通記事が新規作成されるようになります。
contentsに共通記事を作る
共通化したいコンテンツを通常の記事と同じように、新規記事作成します。この共通部品はSitemapとRSSから除外するためcontents/parts
にまとめる運用を行ってください。
hugo new parts/common.md
共通記事をincludeする
---
date: 2015-03-23T23:26:39+09:00
description: null
slug: null
tags: []
title: article
---
{{% include "parts/common.md" %}}
Sitemapからparts sectionを除外する
共通記事がcontentsに入っているとSitemapに掲載されるので、カスタムのサイトマップテンプレートを作って除外します。
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{{ range where .Data.Pages "Section" "!=" "parts" }}
<url>
<loc>{{ .Permalink }}</loc>
<lastmod>{{ safeHtml ( .Date.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ with .Sitemap.ChangeFreq }}
<changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
<priority>{{ .Sitemap.Priority }}</priority>{{ end }}
</url>
{{ end }}
</urlset>
RSSからparts sectionを除外する
共通記事がcontentsに入っているとRSSに掲載されるので、カスタムのRSSテンプレートを作って除外します。
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ .Title }} on {{ .Site.Title }} </title>
<generator uri="https://gohugo.io">Hugo</generator>
<link>{{ .Permalink }}</link>
{{ with .Site.LanguageCode }}<language>{{.}}</language>{{end}}
{{ with .Site.Author.name }}<author>{{.}}</author>{{end}}
{{ with .Site.Copyright }}<copyright>{{.}}</copyright>{{end}}
<updated>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</updated>
{{ range first 15 (where .Data.Pages "Section" "!=" "parts") }}
<item>
<title>{{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</pubDate>
{{with .Site.Author.name}}<author>{{.}}</author>{{end}}
<guid>{{ .Permalink }}</guid>
<description>{{ .Content | html }}</description>
</item>
{{ end }}
</channel>
</rss>