GitHub Pages + Hugo でブログを開設する
目次
自分のブログを作りたくなった#
これまで Qiita に記事を書いていたけども、数学や散文的なものとか、エンジニアリング以外のことも書きたくなったので、自分のブログを作ることにした。
あと Sam Altman のブログ1を見て触発されたのもある。
なぜ Hugo か#
いざブログを作ろうと思うと、色々要件が湧き出てくる。
- 数式を書きたい
- Markdown で記事を書きたい
- タグ付けしたり、カテゴリ分けしたりしたい
- OGP とか Twitter カードとかのメタデータを設定したい
- Google Analytics とかのアクセス解析をしたい
- …
はじめは Sam Altman の使っている POSTHAVEN は思想がよさそうだったので選択肢として考えていた。ただ一つクリティカルな難点が、数式が書けそうにないこと。これでやめた。
WordPress はめんどくさい。 GitHub Pages はいいけど、手動で HTML を書くのはめんどくさい。そのため静的サイトジェネレーターを使いたい。
静的サイトジェネレーターはいろいろあるけど Hugo にした。強い理由があるわけではない。 Hugo 以外では Jekyll が有名だろうけれども、 Google トレンドを見ると Hugo の方が人気があるようだし、だいたい Hugo で要件も満たせそうなので Hugo にした。
Hugo でブログを作る#
あとで見返してわかるように、やったことをメモしておく。
quickstart#
https://gohugo.io/getting-started/quick-start/
を見ればだいたいわかる。
theme#
Blowfish にした。デモサイトが良くて、ドキュメントも充実している。
デモサイトを見て、実現したいことがあれば repo を見て、必要ならドキュメントを見て、というのが基本的な流れ。
これは git submodule として追加した。備忘録として、新たに repository を clone する場合のコマンドは以下の通り。
git submodule init
git submodule update
favicon#
https://blowfish.page/docs/partials/#favicons
を見る。 favicon.io という素晴らしいサイトがあることがわかった。
icon#
例えばホームの Qiita や note のバッチ。これは
https://blowfish.page/docs/shortcodes/#icon
を参照する。各サービスのアイコンはガイドラインをちゃんと読む。 Udemy も載せようと思ったけれども、ガイドラインを読むと Udemy のロゴは利用許諾を得る必要があったのでやめた。
数式#
以下を参照した。
https://blog.atusy.net/2019/05/09/katex-in-hugo/
具体的には以下のスクリプトを追加した themes/blowfish/layouts/partials/footer.html
を layouts/partials/footer.html
にコピーした。上 3 行は KaTeX の公式サイトの最新のやつ を参照した。
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css"
integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV"
crossorigin="anonymous"
/>
<script
defer
src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"
integrity="sha384-XjKyOOlGwcjNTAIQHIpgOno0Hl1YQqzUOEleOLALmuqehneUG+vnGctmUb0ZY0l8"
crossorigin="anonymous"
></script>
<script
defer
src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"
integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05"
crossorigin="anonymous"
onload="renderMathInElement(document.body);"
></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
renderMathInElement(document.body, {
delimiters: [
{ left: "$$", right: "$$", display: true },
{ left: "$", right: "$", display: false },
],
});
});
</script>
アイコンの線画#
で作った。
OGP#
記事それぞれに cover.png
を作ると勝手に反映される。
これは便利なのだけど、後で思ったことで、記事それぞれにいちいち画像をつけるのは、運用上ちょいめんどさを感じる。 DALL-E で簡単に生成できるとはいえ、もっと手軽に書きたい。故に、画像を設定するのをそもそもやめる。
その上で、線画のアイコンを OGP にする。
設定の仕方は以下を参照した。
https://miyahara.hikaru.dev/posts/20200319/
要するに、 static
に画像を配置して、 hugo.toml
に以下の行を追加する。
[params]
description = '近藤憲児'
images = ['kondokenji.png']
GitHub Pages へのデプロイと GitHub Actions#
https://gohugo.io/hosting-and-deployment/hosting-on-github/
これをやればすぐうまくいった。
URL マネジメント#
それぞれの記事のテンプレートを以下のようにした。
---
title: "GitHub Pages + Hugo でブログを開設する"
tags: ["Hugo", "GitHub", "技術"]
# externalUrl: ""
showSummary: false
date: 2024-01-03T06:13:09+09:00
draft: false
url: 518407ac-4c8e-4ca7-b534-723a3ba0e72e
---
特に、 url
の部分を UUID にした。というのもデフォルトだと記事を配置している directory 構造に従って URL が決まるのだけれども、それだと directory 構造を整理したときに URL が変わってしまうので、それを避けるために UUID にした。 slug
もあるけれど、url
のセクションのほうが完全に一意に記事を特定できるので、そのようにした。
Google Analytics#
https://blowfish.page/docs/partials/#google-analytics
超簡単。ここに Google Analytics の ID を書くだけ。
これをやると Google 検索に現れる。
記事を作るときのルーティン#
開発用のサーバーを立ち上げる。
hugo server -D
以下のようなスクリプトを準備して、すぐ記事を作れるようにする。 hugo のコマンドで記事のテンプレートを作れるけれども、それでも全然良い。どちらでも良いのと directory を作るところまで自動的にやりたいので、スクリプトを書いた。
# %%
# !pip install pytz
import os
import uuid
from datetime import datetime
import pytz
def get_current_datetime_jst():
current_date = datetime.now()
jst = pytz.timezone("Asia/Tokyo")
current_time_jst = current_date.astimezone(jst)
return current_time_jst
def get_datetime_str(dt: datetime) -> str:
formatted_time = dt.strftime("%Y-%m-%dT%H:%M:%S%z")
formatted_time_with_colon = formatted_time[:-2] + ":" + formatted_time[-2:]
return formatted_time_with_colon
def get_directory_name(dt: datetime) -> str:
# 2021/08/01-{uuid} という形式でディレクトリ名を作成
directory_name = dt.strftime("%Y/%m/%d-") + str(uuid.uuid4().hex[:8])
return directory_name
current_datetime = get_current_datetime_jst()
formatted_datetime_str = get_datetime_str(current_datetime)
directory_name = get_directory_name(current_datetime)
# Create a new directory
_current_dir = os.path.dirname(os.path.abspath(__file__))
target_dir = os.path.join(_current_dir, "../content/posts/", directory_name)
# Create the directory
os.makedirs(target_dir, exist_ok=True)
# Read the template file
with open(os.path.join(_current_dir, "index.md.template"), "r") as file:
filedata = file.read()
# Replace {{date}} with the current date and time
filedata = filedata.replace("{{date}}", formatted_datetime_str)
# Replace {{url}} with uuid4
filedata = filedata.replace("{{url}}", str(uuid.uuid4()))
# Write the file out again
with open(target_dir + "/index.md", "w") as file:
file.write(filedata)
index.md.template
---
title: ""
tags: []
# externalUrl: ""
showSummary: false
date: {{date}}
draft: false
url: {{url}}
---
書き終えたら main に push する。すると GitHub Actions が走って、自動的にデプロイされる。
おわり。