2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GraphCMSとHugoを連携してGithub Pagesで公開する(2)〜Hugoの設定

Posted at

概要

GraphCMSとHugoの連携二回目。
今回はHugoの設定の話。

Hugoによるサイト構築

インストール

ここではHugoのインストール方法は割愛する。

最初にサイトを作成する。

hugo new site my-site

上記コマンドで作成した場合は以下のようなファイル構成となる。

my-site
├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes

テーマ(themes)は既存のものを導入するとして最小限編集する必要があるのはconfig.tomlcontentである。
その名の通り後者が具体的なサイトのコンテンツとなる。
なのでここに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"
# 以下省略

重要なのはthemethemesDirあたり。これを適切に設定しないエラーになるか真っ白な画面になる。
またlanguages.enの設定は不要だが、後で多言語化にトライしてみるつもりなので残してある。

では確認

huge serve

FireShot Capture 115 - 私のブログ - localhost.png

ここまでのソース → 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-->

適当に本文を作成してサーバ起動する。

FireShot Capture 116 - Pythonからこんにちは - 私のブログ - localhost.png

こんな感じでできあがる。

Pythonで実装しているのでフロントマターのみならず本文もオプションで自由に設定することはできる。
例えばyoutube動画を埋め込むとかいろいろ。
しかし現実的には長々とコマンドラインに引数を与えて実行するよりも単純に

python -m app

として後は自由に編集するのが一番よいかと思う。

ここまでのソース → Release v1.1 · higebobo/hugo-graphcms-blog

まとめ

今回はHugoのコンテンツをわざわざPythonで生成する方法を解説した。
が、これは次回説明する本題のGraphCMSとHugoの連携についての前置きであるのでご了承いただきたい。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?