Hugo を使った個人サイトの作り方 4 テーマの自作とホームページの作成(1)

Hugo アイキャッチ画像

オリジナルテーマ作成

今回から実際にサイトを作っていきます。テーマはすべて自作とします。 オリジナルのテーマを自作するには、コマンドラインから作業ディレクトリに移って hugo new themeします。

1cd C:\NEWSITE\SITENAME
2hugo new theme [yourthemename]

C:\NEWSITE\SITENAME(サイトの作業ディレクトリ)と[yourthemename](テーマ名)はそれぞれ読み替えてください。私は「Museum」というテーマ名にしました。 さて、hugoによって新たなテーマが作成され、ディレクトリ構成はこのようになりました。

C:\NEWSITE\SITENAME\themes\yourthemename
│  LICENSE
│  theme.toml
│
├─archetypes
│      default.md
│
├─layouts
│  │  404.html
│  │  index.html ★Homepage template
│  │
│  ├─partials
│  │      footer.html
│  │      head.html
│  │      header.html
│  │
│  └─_default
│          baseof.html
│          list.html
│          single.html
│
└─static
    ├─css
    └─js

それぞれのHTMLファイルがページ各部の部品と考えてください。Go言語の標準パッケージ「html/template」エンジンで書かれたこれらのファイルを テンプレート と呼びます。これらのファイルを編集し、静的サイトを作っていきます。

トップページ(ホームページ)の作成

変数の参照と式

まずはトップページ(ホームページ)を作りたいと思います。私は、古き良き個人サイトの伝統にのっとり、トップページとそれ以外とではデザインを分けることにしました。いきなり完成形で申し訳ありませんが、トップページは以下のようなデザインになる予定です。

Theme[Museum]Homepageの完成デザイン[hugo-homepage.jpg(210,325byte)]

(普通に考えたら、この完成形にたどりつくまでの試行錯誤でかなり時間がかかるのですが)このページの雛形をHTMLとCSSで作成し、再現できるようにしておきます。HTML、CSSの記法については省略します。

Hugoではトップページ(※公式ドキュメントでは 「homepage」 と呼ばれている)はlayouts/index.htmlのテンプレートを呼び出して表示します。したがって、このファイルを編集すればOKということになります。

事前に作成した完成ページの記述をコピペすればそのまま表示されますが、それだと柔軟な設定ができません。ヘッダーとヒーローイメージ、グローバルナビゲーションの後につづく コンテンツ部分に、最新の記事を五件リスト表示するようにしたい です。図で言えば赤で示した部分がHugoの機能を使って自動挿入した部分です。

Hugoではさまざまな変数や条件分岐式が使えます。たとえば {{ .Title }} でMarkdownファイルのFrontMatterで指定した「title」にアクセスできます。今回は「まくまくHugoノート」さんの記述を参考にして使います。

./themes/Museum/layouts/index.html

1<h1>更新履歴</h1>
2<ul>
3  {{ range first 5 .Site.RegularPages.ByDate.Reverse }}
4    <li>
5     <time>{{.Date.Format "2006-01-02"}}</time> {{.Params.categories}} - <b><a href="{{.RelPermalink}}">{{.Title}}</a></b> 
6    </li>
7  {{ end }}
8</ul>
三行目 {{ range first 5 .Site.RegularPages.ByDate.Reverse } ~ {{ end }}} あたりが自動処理される部分となります。Hugoのサイト変数である.Site.RegularPages.を五件降順で出すという繰り返し処理です。ここでは記事が属するカテゴリも出力することにしました。

続けて黄色の枠で囲まれている 「てがろぐ」CGI部分 も説明してしまいます。なんか全然hugoとは関係ないですが… これはてがろぐCGIが出力した最新の1件を任意の場所にSSIで埋め込む方法 - Sakura scope に倣って、SSIではなくJavascriptのライブラリであるJqueryの機能を使って読み込んでいる形です。

Jqueryについては、ヒーローイメージをランダム表示するためにトップページのみ導入しています。

まず最新三件を読み込むスキンを「てがろぐ」側で作ります。

./umekomi/skin-cover.html

1<div class="tegalog">
2[[TEGALOG:3]]
3<p><address class="hitokoto-poweredby">[[VERSION]]</address></p>
4</div>

[[VERSION]]がないと無料使用の規約違反となるので気を付けます。

./umekomi/skin-onelog.html

1<article>
2<h3>[[DATE:Y/M/D]]</h3>
3<p>[[COMMENT]]</p>
4</article>

そしてHugoのテンプレート側のHead要素内に以下のスクリプトを書きます。注意点としてはJqueryのライブラリを<script src=“Jqueryのアドレス” />で読み込んだ後に書くことです。

./themes/Museum/layouts/index.html

1$(function tegalog(){
2  $("#tegalogue").load("てがろぐCGIのURL?skin=umekomi");
3});

これで<div id=“tegalogue”> ~ </div>内部に埋め込みスキンの内容が埋め込まれるようになりました。

サイトの設定(hugo.toml)

続けてフッターを作っていきたいと思います。トップページは見栄えなどの理由からヘッダー、コンテンツ部分を他のページと異なった表示にしましたが、フッターは他と共通にします。スマホなどで表示されるのと似た内容のグローバルナビゲーションがあり、作成日時と更新日時が表示され、最後に著作権表記が表示されます。

まずはメニューを作りたいです。メニューについてはHugoのメニュー機能を利用します。メニューは./content/以下のそれぞれのmarkdownファイルのFrontMatterで指定することもできますが、ところどころに記述が散らばってしまいわかりづらいのでサイトの設定ファイルに記述することにします。

./hugo.toml(Ver.0.110.0より前は「config.toml」)を開いてサイト全体の設定を記述していきます。以下、内容の晒しです。長くなるのでメニュー手前で切っています。

./hugo.toml(1)

baseURL = "https://etre.lix.jp/aksm/"
languageCode = "ja"
DefaultContentLanguage = "ja"
title = "あきかぜすみか"
theme = "Museum"
copyright = "Copyright © 2009-2023 aouma"
hasCJKLanguage = true
summarylength = 140
enableRobotsTXT = true
enableEmoji = true
canonifyurls = true
rssLimit = 10
[outputs]
  home = [ "HTML", "RSS", "Sitemap"]
  page = [ "HTML" ]
  section = [ "HTML" ]
  taxonomy = ["HTML" ]
  term = [ "HTML" ]
[markup.goldmark.renderer]
  unsafe = true
[markup.goldmark.parser.attribute]
  block = true
[markup.highlight]
  anchorLineNos = false
  codeFences = true
  guessSyntax = false
  hl_Lines = ''
  hl_inline = false
  lineAnchors = ''
  lineNoStart = 1
  lineNos = true
  lineNumbersInTable = false
  noClasses = true
  noHl = false
  style = 'witchhazel'
  tabWidth = 4
[taxonomies]
  tag = "tags"
  category = "categories"
  series = "series"
[params]
  image = "./img/icon-512.png"
  description = "aouma による BoysLove小説を展示するR18サイトです。オリジナルBL「終わりの後の夜物語」・創作戦国(毛利家中心)、二次創作もあります"

公式ドキュメントConfigure Hugo | Hugo を和訳して説明を加えます。

baseURL
ルートのホストネーム(とパス)を書く。サブディレクトリを切る場合はcanonifyurlstrueに。
languageCode
RSSの出力やHTML要素のlang属性に利用される。日本語だったらja
DefaultContentLanguage
コンテンツの言語設定。デフォルトで"en"になっているので日本語だったらja
title
サイトのタイトル。
theme
表示用テーマ。フォルダ名を指定。
copyright
コピーライト表示。サイト下部の表示に使用される場合も。
hasCJKLanguage
中国語、日本語、韓国語の設定。.Summaryや.Wordcountといったページ変数で正しい字数が計算されるようになる。trueを指定。
summarylength
.Summaryで表示されるテキスト量。ツイッターと揃えて140を指定しておいた。上記のhasCJKLanguageがfalseだと単語での区切りになるため非常に長大な分量になってしまう。
enableRobotsTXT
検索エンジン等のロボットを制御するrobot.txtの自動生成機能。trueに指定しているが、細かい内容は自分で記述する。
enableEmoji
絵文字を使用するかどうか。適当に使って表示されないと悲しい:sweat:のでtrueを指定:blush: チートシートEmoji cheat sheet for GitHub, Basecamp, Slack & more
canonifyurls
相対URLを常に絶対URLに変換。baseURLがトップドメインでなくサブディレクトリを切っている場合(例:https://bep.is/hoge/)はtrueに設定。相対URLを可能にする「relativeURLs」もある。
rssLimit
RSSで出力される件数の指定。デフォルトだと全て出力するので10を指定。

続けてテーブル内の設定です。

[outputs]テーブル

出力フォーマットを自在に設定できる。ここでは、トップページ以外でRSSやサイトマップを出力してほしくなかったので、以下のように指定。

home = [ "HTML", "RSS", "Sitemap"]
page = [ "HTML" ]
section = [ "HTML" ]
taxonomy = ["HTML" ]
term = [ "HTML" ]

[markup.goldmark.renderer]テーブル

markdownファイル内でHTMLタグを有効化するにはunsafe = trueを設定。詳しくはConfigure Markup | Hugo

[markup.goldmark.parser.attribute]テーブル

markdownファイル内でブロックレベル要素にclassを付ける記法を有効にする。デフォルトで無効になっているため、block = trueを設定。

[markup.highlight]テーブル

markdownファイル内でコードを色分けするための設定。詳しくはSyntax Highlighting | Hugo

私は色合いをwitchhazelに変更しています。

[taxonomies]テーブル

Hugoの分類機能を有効にするための設定。ユーザーが自由に項目を設定できるが、汎用的なタグ、カテゴリ、シリーズのみを有効化。

tag = "tags"
category = "categories"
series = "series"

必要ない場合はdisableKinds = [ “taxonomy”,“term” ] などと設定する。 許容されるリストは

[params]テーブル

ユーザーやテーマ作成者が自由に設定できるセクション。 サイト全体のイメージ画像のパスと、概要を記入。 テンプレートなどからサイト変数で利用される。

長くなりましたが、ここからサイト全体で利用できるメニューを設定しています。

メニューの設定(hugo.toml)

./hugo.toml(2)

[menu]
  [[menu.global]]
  name = 'Home'
  pre = " "
  identifier = 'home'
  title = 'Toppage of Akikazesumika'
  url = '/'
  weight = -120
  [[menu.global]]
  identifier = 'about'
  name = 'Info'
  pre = " "
  title = 'Site Information and Bookmarks'
  url = '/about/'
  weight = -110
  [[menu.global]]
  identifier = 'original'
  pre =" "
  name = 'Original'
  title = 'Original Novels'
  url = '/original/'
  weight = -100
  [[menu.global]]
  identifier = 'history'
  pre = " "
  name = 'History'
  title = 'Historical BoysLove Novels'
  url = '/history/'
  weight = -90
  [[menu.global]]
  identifier = 'niji'
  pre = " "
  name = 'Fan-fic'
  title = 'Fanfictions'
  url = '/niji/'
  weight = -80
  [[menu.global]]
  identifier = 'blog'
  pre = " "
  name = 'Blog'
  title = 'Weblog by Tegalog'
  url = 'てがろぐCGIのURL'
  weight = -70

メニューを作成するにはいくつか方法がありますが、私は前述のようにサイト設定に記述する形にしました。[[menu.global]]で「globalという名のメニュー」にアイテムを追加していきます。 ここではHomeを例にとって説明します。参考:Menu Entry Properties | Hugo

name
Homeを指定。個々の項目の名前を文字列で設定。
pre
メニュー項目の前に入れるHTMLコードなど。fontawesomeのコード<i class='fa-solid fa-house-chimney'>を入れました。
identifier
メニュー項目の中で一意に定まる名前。子メニューなどでnameキーが被ったりした時に利用するらしい。homeを指定。
title
A要素のtitle属性などに使用。Toppage of Akikazesumika と説明を付記。
url
メニュー項目のパス。baseURLからの相対パスを記入する(すべて自動的に正しい絶対パスへと置き換わる)/を設定。
weight
-120と記入。メニュー項目の重みづけを指定する。並び順の制御値。

これでサイト設定を終え、メニューを作成できました。 長くなってしまったので次回はフッター表示用の Partial Template について書きます。