概要
GraphCMSとHugoの連携二回目。
今回はHugoの設定の話。
Hugoによるサイト構築
インストール
ここではHugoのインストール方法は割愛する。
最初にサイトを作成する。
hugo new site my-site
上記コマンドで作成した場合は以下のようなファイル構成となる。
my-site
├── archetypes
│ └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes
テーマ(themes)は既存のものを導入するとして最小限編集する必要があるのはconfig.toml
とcontent
である。
その名の通り後者が具体的なサイトのコンテンツとなる。
なのでここにGraphCMSのコンテンツを流し込むようにする。
その前にまずGitレポジトリの初期化を行う。
cd my-site
git init
echo '*~' >> .gitignore
echo '*.bak' >> .gitignore
echo '*.orig' >> .gitignore
echo '.env' >> .gitignore
echo 'public' >> .gitignore
echo 'resources' >> .gitignore
次にテーマの導入。
テーマはお好みのものを使ってもらえればいいが、本例ではAnankeを使う。
git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke
cp themes/ananke/exampleSite/config.toml .
そしてconfig.tomlの編集
title = "Hugo GraphCMS Site"
baseURL = ""
languageCode = "en-us"
theme = "ananke"
#themesDir = "../.."
#resourceDir = "../resources"
DefaultContentLanguage = "ja"
SectionPagesMenu = "main"
Paginate = 3 # this is set low for demonstrating with dummy content. Set to a higher number
googleAnalytics = ""
enableRobotsTXT = true
[languages]
#[languages.en]
# title = "My blog"
# weight = 2
# contentDir = "content/en"
[languages.ja]
title = "私のブログ"
weight = 1
#contentDir = "content/ja"
contentDir = "content"
# 以下省略
重要なのはtheme
とthemesDir
あたり。これを適切に設定しないエラーになるか真っ白な画面になる。
またlanguages.en
の設定は不要だが、後で多言語化にトライしてみるつもりなので残してある。
では確認
huge serve
ここまでのソース → Release v1.0 · higebobo/hugo-graphcms-blog
Hugoのコンテンツ形式
Hugoのコンテンツは一般的にはcontent
ディレクトリにMarkdown形式のファイルをおいてビルドする。だけである。
コンテンツのメタ情報はフロントマターと呼ばれるyaml
形式またはtoml
形式で記述する。
なのでものすごくシンプルにするとこんな感じになる。
---
title: はじめまして
date: "2021-09-16T12:58:01+09:00"
---
# こんににちは
私もブログをはじめました。
コンテンツの雛形はarchetype
と呼ばれ、コマンドでコンテンツを作成する時に呼び出される。
(Hugoのサイト作成時にarchetypes/default.md
が生成される)
例えばcontent
ディレクトリにhello.md
を作成したい場合は以下を実行する。
hugo new content/post/hello.md
するとフロントマターが生成された状態のコンテンツが作成されるので後は本文を書けばよい。
---
title: "Hello"
date: 2021-09-24T08:23:45+09:00
draft: true
---
Anankeテーマの場合
(他のテーマを使う場合は不要または適時読み替え)
Anankeテーマを使う場合はarchetype
もテーマ用のものを使う必要がある。
デフォルトではarchetypes/default.md
が呼び出されるのでテーマのものに替える。
コピーして上書きでもよいが、archetypesの検索順(参照記事)を利用して呼び出す順位を変える。
# 変更する名前はdefault.mdやpost.mdでなければよい
mv archetypes/default.md archetypes/_default.md
またAnankeテーマのコンテンツは_index.md
というインデックスページ(参照記事)を利用しているので以下のように準備する。
content
├── _index.md
└── post
└── _index.md
content/_index.md
---
title: "Hugo GraphCMS Blog"
featured_image: '/images/gohugo-default-sample-hero-image.jpg'
description: "HugoとGraphCMSを連携したブログです"
---
みなさん、こんにちは。
私のブログへようこそ
content/post/_index.md
---
title: "投稿記事"
date: 2021-09-24T09:18:44+09:00
---
ブログの投稿記事一覧です。
準備ができたら記事を作成する。
hugo new content/post/first-post.md
以上がAnankeを使う場合の作法だが、テーマごとのコンテンツ作成ルールなどは正直初見ではわかりにくい。
まずはテーマがたいていexampleSite
を用意しているのでその中のcontent
をまるっとコピーしてくるとよい。
Pythonによるコンテンツの雛形生成
archetype
のところを長々と説明したけども、今回はHugoのarchetype
の仕組みは利用せずPythonで作る。
この段階ではわざわざPythonで作る必要は無い。しかし後で述べるGraphCMSとの連携を考慮した。
Go言語がわかればHugo内で直接WEB-APIを叩いてMarkdownを作成すればよいと思うが、Pythonistaの私はPythonで実装するほうが手っ取り早い。
「Python使い」の意味だったと思うPythonistaがいつの間にかアプリ名になっている。。。
ざっと実装するとこんな感じ。
(Markdown作成の考えた方は同じなので好きな言語で実装してもらえればよいかとは思う)
app/__main__.py
import argparse
import datetime
import os
ROOT_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
CONTENT_DIR = os.path.join(ROOT_DIR, 'content', 'post')
def check_args():
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--title', default='My Post', help='blog title')
parser.add_argument('-i', '--image', help='featured image')
parser.add_argument('--tags', help='blog tags')
return parser.parse_args()
def main(content_dir=CONTENT_DIR):
args = check_args()
now = datetime.datetime.now()
timestamp = now.strftime('%Y%m%dT%H%M%S')
# ファイル名をタイムスタンプで生成
filepath = os.path.join(content_dir, f'{timestamp}.md')
if os.path.exists(filepath):
# 同一ファイル名が存在する場合は終了
print(f'{filepath} is exists')
return
# フロントマターのメタ情報設定
front_matter_map = {
'title': f'"{args.title}"',
'date': now.strftime('%Y-%m-%dT%H:%M:%S+09:00'),
}
# カバー写真の処理
if args.image:
front_matter_map.update({"featured_image": f'"{args.image}"'})
# タグの処理
if args.tags:
front_matter_map.update({"tags": str(args.tags.split(','))})
# 出力内容の生成
output = '---\n'
for k, v in front_matter_map.items():
output += f'{k}: {v}\n'
output += '---\n\n<!--more-->\n'
# ファイルへの書き込み
with open(filepath, 'w') as f:
f.write(output)
print(f'create {filepath}')
if __name__ == "__main__":
main()
オプションでフロントマターの情報を与えられるようにしたので例えば以下のように実行すると
python -m app -t "Pythonからこんにちは" -i https://www.python.org/static/community_logos/python-logo-master-v3-TM.png --tags="Python,挨拶"
こんなMarkdownが生成される。
---
title: "Pythonからこんにちは"
date: 2021-09-27T10:00:27+09:00
featured_image: "https://www.python.org/static/community_logos/python-logo-master-v3-TM.png"
tags: ['Python', '挨拶']
---
<!--more-->
適当に本文を作成してサーバ起動する。
こんな感じでできあがる。
Pythonで実装しているのでフロントマターのみならず本文もオプションで自由に設定することはできる。
例えばyoutube動画を埋め込むとかいろいろ。
しかし現実的には長々とコマンドラインに引数を与えて実行するよりも単純に
python -m app
として後は自由に編集するのが一番よいかと思う。
ここまでのソース → Release v1.1 · higebobo/hugo-graphcms-blog
まとめ
今回はHugoのコンテンツをわざわざPythonで生成する方法を解説した。
が、これは次回説明する本題のGraphCMSとHugoの連携についての前置きであるのでご了承いただきたい。