こんにちは、tamaoki (@t0shiya) です。
今回は、静的サイトジェネレータ Hugo の メニュー について解説します。
メニューとは?
Hugoにはシンプルなメニュー構築機能が備わっています。メニュー機能は以下のような特徴があります。
- コンテンツを任意のメニュー(複数可)に追加できる
- メニューを階層化できる
- コンテンツなしでもメニューを追加できる
- 選択中のメニュー表示を変更できる
内部構造的に言うとメニューとは .Site.Menu という変数でアクセスできる連想配列のようなものです。
例えば main というメニューは .Site.Menu.main
でアクセスします。
メニューには以下のようなプロパティがあります。
URL | コンテンツのパーマリンク、または指定URL |
---|---|
Name | 表示名 |
Menu | 所属メニュー |
Identifier | セクション名、または指定文字列 |
Pre | 指定HTML |
Post | 指定HTML |
Weight | 並び順 |
Parent | 親メニュー名 |
Children | 子メニュー |
また、HasChildren
という関数で子メニューが存在するか確認できます。
メニューの追加
メニューを追加する方法は二つあります。一つはコンテンツのフロントマターで指定する方法、もう一つは config.toml で指定する方法です。
コンテンツをメニューに追加
コンテンツのフロントマターにメニュー項目を書くだけで、メニュー定義の追加とメニューへのコンテンツ登録が行われます。
フロントマターには以下のように記述します。
---
// YAML形式の場合
menu: "main"
// 複数のメニューに追加する場合
menu: ["main", "footer"]
---
次のように親メニュー項目を指定して階層化したり、weight で並べ替えをすることもできます。
---
// YAML形式の場合
menu:
main:
parent: 'extras'
weight: 20
---
config.toml でメニューを追加
menuの表示順を変更したり、リンク等のコンテンツに紐付かないメニューを追加する場合は config.toml に定義を記載します。
[[menu.main]]
name = "about hugo"
pre = "<i class='fa fa-heart'></i>"
weight = -110
identifier = "about"
url = "http://gohugo.io/"
[[menu.main]]
name = "getting started"
pre = "<i class='fa fa-road'></i>"
weight = -100
url = "/getting-started/"
各項目は前述の通りです。url は絶対パスまたはbaseURLからの相対パスで指定してください。
メニューを表示
冒頭で記した通りテンプレートからは .Site.Menus 変数を介してアクセスします。
例えば、メニュー項目 main を表示するには以下のように記述します。
<ul class="menu">
{{ $currentNode := . }}
{{ range .Site.Menus.main }}
{{ if .HasChildren }}
<li class="sub-menu{{if $currentNode.HasMenuCurrent "main" . }} active{{end}}">
<a href="javascript:;" class="">
{{ .Pre }}
<span>{{ .Name }}</span>
<span class="menu-arrow arrow_carrot-right"></span>
</a>
<ul class="sub">
{{ range .Children }}
<li{{if $currentNode.IsMenuCurrent "main" . }} class="active"{{end}}><a href="{{.URL}}"> {{ .Name }} </a> </li>
{{ end }}
</ul>
</li>
{{else}}
<li>
<a class="" href="{{.URL}}">
{{ .Pre }}
<span>{{ .Name }}</span>
</a>
</li>
{{end}}
{{end}}
</ul>
2行目は range の中から現在の表示ページ情報を参照するため、$currentNode に . を代入しています。
.Site.Menus.main
に対して階層化されているかどうかで処理を切り替えています。$currentNode.HasMenuCurrent
, $currentNode.IsMenuCurrent
でそれぞれ表示中のコンテンツが当該メニューの配下にいるか、当該メニューであるか、を判定しています。
セクションをメニューに登録
次の設定を config.toml に記載すると全セクション、コンテンツが main メニューに一括登録されます。
SectionPagesMenu = "main"
デフォルトでは、セクション名が表示名になります。表示名や並び順を変更したい場合は config.toml に定義を追加してください。この時、identifier
をセクション名にしてください。
[[menu.main]]
name = "This is the post section"
weight = -110
identifier = "post"
url = "/post/"
feedtailor では、静的サイトジェネレータの利用に限らず、ウェブサイト静的化の御相談を承っておりますのでお気軽にお問い合わせください。