beta

HUGOサイトのメニューを設定ファイルからカスタマイズできるようにする

HUGOサイトでは、サイトメニューはHTMLテンプレートにベタ書きする以外にも、HUGO設定ファイルからカスタマイズできるようにする方法があります。今回は、その仕組みと使い方を見ていきます。

公開日:2019年3月27日

設定ファイルのメニューに関する変数は「menu」

HUGOでは、メニューに関する設定を、HUGOの全体設定ファイル(プロジェクトルートのconfig.toml)に記述することで、動的にメニューを設定出来るようになります。

HUGO公式サイトにある例を拝借しますと、

[menu]

  [[menu.main]]
    identifier = "about"
    name = "about hugo"
    pre = "<i class='fa fa-heart'></i>"
    url = "/about/"
    weight = -110

  [[menu.main]]
    name = "getting started"
    post = "<span class='alert'>New!</span>"
    pre = "<i class='fa fa-road'></i>"
    url = "/getting-started/"
    weight = -100

という形になります。

Menus | HUGO

本記事では、この例を元に各パーツを分解しながら解説していきます。

記述方式は、tomlの配列方式になっています。tomlの記述方式については、こちらがわかりやすいので、併せてご覧ください。

まず必要なのは、最初の[menu]の部分です。これでこのブロックがmenuであることを宣言します。

[menu]

続いて、メニューの中身を設定します。こちらは連想配列になっていて、二重の[]でくくります。

[[menu.main]]

menuとドットでつないだ後ろの部分がメニューのキーになります。こちらはメニュー詳細をまとめる役割を持っていて、テンプレートでメニューを呼び出す時に使います。

これで、menuという配列の中にmainというキーで配列が渡されます。ここはいくつでも作成できるので、例えば、

[[menu.header]]
設定内容...

[[menu.sidebar]]
設定内容...

[[menu.footer]]
設定内容...

という風に、keyの部分を追加していくことで、メニュー配列いくつも設定することが出来ます。

メニューの詳細を設定する

次に、メニューの詳細情報を書きます。各項目の意味は下記の通りです。

  [[menu.main]]
    identifier = "about"
  //親要素名
    name = "about hugo"
  //メニューで表示するテキスト
    pre = "<i class='fa fa-heart'></i>"  //メニューテキストの前に表示するコード
    post = ""  //メニューテキストの後に表示するコード
    url = "/about/"
  //メニューのリンク先
    weight = -110
  //メニューの表示順

注意したいのは、メニューブロックの部分はキーを宣言した連想配列になっていますが、メニューの中身については連想配列にはできません。

それでは複雑なメニューを設定するのに不便なのですが、HUGOでは「identifier」や「weight」を使って複雑なメニューを組めるようにしています。

identifierは親要素名

メニューの階層式にしたい時に使うブロックです。階層式にしない場合は省略して構いません。

例えばメニュー構成を下記のようにしたいとすると、

スマートフォン
├── iPhone
└── Android

メニューの記述は下記のようになります。

  [[menu.main]]
    identifier = "smartphone"
    name = "スマートフォン"
    url = "/smartphone/"

  [[menu.main]]
    parent = "smartphone"
    name = "iPhone"
    url = "/smartphone/iphone/"

  [[menu.main]]
    parent = "smartphone"
    name = "Android"
    url = "/smartphone/andoird/"

identifierで親メニューを設定して、parentで紐付ける形になっています。

url部分は一見すると親要素の直下に連結されそうなイメージですが、ここはベタのテキストになっているのでurlのフルパスをしっかりと書きます。

parentを持つメニューもidentifierを記述すれば親になれるので、2階層以上のメニューも組むことができます。

weightは表示順

PHPやRubyなどの感覚からすると、入力した順番で配列が格納されているように思えますが、HUGOの設定ファイルはそうはなっていないため、表示順を制御するために「weight」ブロックを使います。

ここは数字が少ない順番で表示されていく形式になるので、その点を注意しましょう。

これでconfig.tomlファイルに記述するメニューは完了です。

テンプレート側でメニュー設定を呼び出す

メニューの設定ができたので、テンプレート側で表示させる方法をみていきます。

メニュー変数は「.Site.Menus」

テンプレート側でメニューを呼び出す際の変数は、

.Site.Menus

内に入っています。この中に、設定ファイルで記述したすべてのメニューが格納されています。

設定ファイルでは[menu]で宣言していますが、テンプレート側では「.Menus」と複数形になるところは注意してください。

「.Site.Menus」は連想配列になっているので、設定ファイルで記述したキー名をピリオドでつなぐことでメニューを指定できます。

.Site.Menus.header

ループ関数である「range」を使えばそのままメニューが表示されます。各メニューの変数には、

{{ .Name}}

など、メニューで設定したキー名でアクセスできます。

階層式メニューのケース

メニューが階層式になっている場合は、「.HasChildren」という値がセットされ、子メニューは「.Children」という配列に格納されています。

{{ range .Site.Menus.header }}
  親メニュー
  {{ if .HasChildren }}
    {{ range .Children }}
       子メニュー
    {{ end }}
  {{ end }}
{{ end }}

子メニューも、各変数へはキー名でアクセスができます。

現在のページのメニューを取得する

現在のページに応じてメニューにクラス「active」などを付与したい場合は判定キー「IsMenuCurrent 」で条件分岐が可能です。

{{ if $currentPage.IsMenuCurrent "main" . }}active{{ end }}

ただし、各ページのフロントマッターにmenuがある場合にしか効果がないので、注意しましょう。


HUGOでメニューを設定する方法をみてきました。

メニューをHTMLテンプレート側にベタ書きするのもいいですが、複数サイトを作る際やテーマとして配布する際は、できるだけ設定ファイルでメニューをカスタマイズできるようになっていたほうがいいので、ぜひ使ってみてください。