メインコンテンツへスキップ
GitHub Pages + Hugo でブログを開設する

GitHub Pages + Hugo でブログを開設する

·
Hugo GitHub 技術
近藤 憲児
著者
近藤 憲児
目次

自分のブログを作りたくなった
#

これまで 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.htmllayouts/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>

アイコンの線画
#

https://tech-lagoon.com/imagechef/image-to-edge.html?cache=20240103034923&reloaded=true#google_vignette

で作った。

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 が走って、自動的にデプロイされる。

おわり。

Related

お問い合わせ
近藤 憲児 (KONDO Kenji)