layouts/home.html
layouts/home.htmlの解説
$ cat themes/my-theme/layouts/home.html
{{ define "main" }}
{{ .Content }}
{{ range site.RegularPages }}
<section>
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ .Summary }}
</section>
{{ end }}
{{ end }}
このファイルは、Hugoのテーマにおけるホームページのレイアウトを定義するテンプレートです。
コードの構造と機能
{{ define "main" }}
{{ .Content }}
{{ range site.RegularPages }}
<section>
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ .Summary }}
</section>
{{ end }}
{{ end }}
1. {{ define "main" }}
- このテンプレートは"main"というブロックを定義しています
- これは親テンプレート(_default/baseof.htmlなど)で
{{ block "main" . }}{{ end }}と定義された部分に挿入されます
2. {{ .Content }}
- ホームページのコンテンツを表示します
- 通常、content/_index.mdファイルのマークダウンコンテンツがHTMLに変換されて表示されます
3. {{ range site.RegularPages }}
- サイト内の通常ページ(記事やコンテンツページ)をループで処理します
site.RegularPagesはドラフトではない通常のコンテンツページのコレクションです
4. 各ページの表示
<section>タグ内に各ページの情報をまとめています{{ .RelPermalink }}: ページの相対URLを取得します{{ .LinkTitle }}: ページのタイトルを表示します(frontmatterの"linkTitle"があればそれを、なければ通常の"title"を使用){{ .Summary }}: ページの要約を表示します(frontmatterで"summary"が指定されるか、コンテンツの先頭部分)
動作概要
このテンプレートはホームページで以下を行います:
layouts/page.html
Hugoのlayouts/page.htmlの解説
$ cat themes/my-theme/layouts/page.html
{{ define "main" }}
<h1>{{ .Title }}</h1>
{{ $dateMachine := .Date | time.Format "2006-01-02T15:04:05-07:00" }}
{{ $dateHuman := .Date | time.Format ":date_long" }}
<time datetime="{{ $dateMachine }}">{{ $dateHuman }}</time>
{{ .Content }}
{{ partial "terms.html" (dict "taxonomy" "tags" "page" .) }}
{{ end }}
この page.html ファイルは Hugo のテーマで使われるページレイアウトテンプレートです。ページコンテンツの表示方法を定義しています。
コード解説
{{ define "main" }}
<h1>{{ .Title }}</h1>
define "main"- このテンプレートの「main」ブロックを定義します。これは通常、ベーステンプレートの対応するブロックに挿入されます。<h1>{{ .Title }}</h1>- ページのタイトルを h1 見出しとして表示します。
{{ $dateMachine := .Date | time.Format "2006-01-02T15:04:05-07:00" }}
{{ $dateHuman := .Date | time.Format ":date_long" }}
<time datetime="{{ $dateMachine }}">{{ $dateHuman }}</time>
- 日付を2つのフォーマットで処理しています:
$dateMachine- 機械可読な ISO 8601 形式の日付(HTML5のdatetime属性用)$dateHuman- 人間が読みやすい長い日付形式(表示用)
<time>タグを使用して、日付を意味論的に正しく表示します。
{{ .Content }}
- ページのメインコンテンツを表示します。Markdown ファイルの本文が HTML に変換されてここに挿入されます。
{{ partial "terms.html" (dict "taxonomy" "tags" "page" .) }}
{{ end }}
partial- 別のテンプレートファイル(terms.html)を読み込みます。dict- パラメータとして辞書(連想配列)を作成し、タクソノミーとして「tags」を指定し、現在のページオブジェクトも渡します。- このパーシャルは、おそらくページに関連付けられたタグを表示するために使用されます。
このテンプレートはシンプルですが、タイトル、日付(機械と人間の両方のフォーマット)、コンテンツ、およびタグを効果的に表示するページレイアウトを提供します。
layouts/_partials/head/js.html
Hugoのlayouts/_partials/head/js.htmlの解説
このコードは Hugo テーマの部分テンプレートで、JavaScript ファイルを処理して HTML に挿入するための部分です。詳細に解説します:
$ cat themes/my-theme/layouts/_partials/head/js.html
{{- with resources.Get "js/main.js" }}
{{- $opts := dict
"minify" (not hugo.IsDevelopment)
"sourceMap" (cond hugo.IsDevelopment "external" "")
"targetPath" "js/main.js"
}}
{{- with . | js.Build $opts }}
{{- if hugo.IsDevelopment }}
<script src="{{ .RelPermalink }}"></script>
{{- else }}
{{- with . | fingerprint }}
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
{{- end }}
{{- end }}
{{- end }}
{{- end }}
全体の流れ
assets/js/main.jsファイルを読み込む- 開発環境かどうかに応じて適切な処理オプションを設定
- JavaScriptファイルをビルド
- 本番環境ではセキュリティ強化のためインテグリティハッシュを追加
コードの詳細解説
リソースの取得
{{- with resources.Get "js/main.js" }}
resources.Get: Hugo のリソースパイプラインを使用してassets/js/main.jsファイルを取得withステートメントはファイルが存在する場合のみ内部のコードを実行
ビルドオプションの設定
{{- $opts := dict
"minify" (not hugo.IsDevelopment)
"sourceMap" (cond hugo.IsDevelopment "external" "")
"targetPath" "js/main.js"
}}
dict: キーと値のペアを持つ辞書(マップ)を作成minify: 開発環境以外(本番環境)でJSファイルを圧縮するsourceMap: 開発環境では外部ソースマップを生成し、本番環境では生成しないtargetPath: ビルド後のファイルの出力先
JavaScript のビルド
{{- with . | js.Build $opts }}
.: 現在のコンテキスト(main.js ファイル)js.Build: Hugo の JavaScript ビルド機能を使用してファイルを処理$opts: 先ほど定義したビルドオプション
環境に応じたスクリプトタグの出力
{{- if hugo.IsDevelopment }}
<script src="{{ .RelPermalink }}"></script>
{{- else }}
{{- with . | fingerprint }}
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
{{- end }}
{{- end }}
- 開発環境:シンプルなスクリプトタグを出力
- 本番環境:
fingerprint: ファイルの内容に基づくハッシュを生成integrity: Subresource Integrity (SRI) を実装し、ブラウザがスクリプトを実行前に検証できるようにするcrossorigin="anonymous": クロスオリジンリクエストでクレデンシャル(Cookie など)を送信しない
このテンプレートは、開発と本番環境で異なる最適化を適用し、本番環境ではセキュリティを強化するベストプラクティスを実装しています。
layouts/_partials/head/css.html
Hugoのlayouts/_partials/head/css.html解説: CSS読み込みの部分
このコードは、Hugoテーマにおいて最適化されたCSSファイルの読み込みを行う部分です。開発環境と本番環境で異なる処理を行っています。
$ cat themes/my-theme/layouts/_partials/head/css.html
{{- with resources.Get "css/main.css" }}
{{- if hugo.IsDevelopment }}
<link rel="stylesheet" href="{{ .RelPermalink }}">
{{- else }}
{{- with . | minify | fingerprint }}
<link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
{{- end }}
{{- end }}
{{- end }}
コードの流れ
{{- with resources.Get "css/main.css" }}- サイトの “assets” ディレクトリ内の “css/main.css” ファイルを取得します- 環境に応じた処理を分岐します:
- 開発環境の場合: CSSをそのままリンク
- 本番環境の場合: CSSを最小化(minify)し、整合性チェック用のハッシュ(fingerprint)を生成
詳細解説
{{- with resources.Get "css/main.css" }}
resources.Getは指定されたファイルをリソースとして取得する関数-は出力時の余分な空白を削除するための指示子- このブロック内では取得したCSSファイルが
.として参照可能
{{- if hugo.IsDevelopment }}
hugo.IsDevelopmentは現在の環境が開発モードかどうかを確認- 開発中は
hugo serverコマンドで実行する場合が該当
開発環境時
<link rel="stylesheet" href="{{ .RelPermalink }}">
- CSSファイルをそのままリンク (最適化なし)
.RelPermalinkはリソースのURLパスを生成
本番環境時
{{- with . | minify | fingerprint }}
<link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
{{- end }}
minify: CSSファイルを最小化して容量を削減fingerprint: ファイルの内容に基づくハッシュ値を生成integrity: Subresource Integrity (SRI) 用のハッシュ値を出力crossorigin="anonymous": クロスオリジンリクエストの処理方法を指定
メリット
- 開発時は元のコードを保持して作業効率を上げる
- 本番環境ではファイルサイズ縮小とキャッシュ最適化
- SRIによるセキュリティ強化
このような処理により、開発のしやすさと本番環境でのパフォーマンス・セキュリティの両方を確保しています。
layouts/_partials/head.html
Hugoのlayouts/_partials/head.htmlについて
$ cat themes/my-theme/layouts/_partials/head.html
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>{{ if .IsHome }}{{ site.Title }}{{ else }}{{ printf "%s | %s" .Title site.Title }}{{ end }}</title>
{{ partialCached "head/css.html" . }}
{{ partialCached "head/js.html" . }}
このコードは、Hugoテーマのhead.html部分テンプレート(パーシャル)で、HTMLの<head>セクションを定義しています。各行の説明は以下の通りです:
<meta charset="utf-8">:- ウェブページの文字エンコーディングをUTF-8に設定します。これは特殊文字や多言語対応に必要です。
<meta name="viewport" content="width=device-width">:- レスポンシブデザイン用のビューポート設定です。
- デバイスの画面幅に合わせてページを表示します(モバイル対応)。
<title>{{ if .IsHome }}{{ site.Title }}{{ else }}{{ printf "%s | %s" .Title site.Title }}{{ end }}</title>:- ページタイトルを動的に設定します。
- もしホームページなら、サイトタイトルのみ表示
- それ以外のページなら、「ページタイトル | サイトタイトル」の形式で表示
{{ partialCached "head/css.html" . }}:- CSSスタイルシートを読み込むためのパーシャルテンプレート
partialCachedはパフォーマンス向上のためキャッシュ機能を使用
{{ partialCached "head/js.html" . }}:- JavaScriptファイルを読み込むためのパーシャルテンプレート
- 同じくキャッシュ機能を利用
この部分テンプレートは各ページの<head>セクションに挿入され、メタデータ、タイトル、スタイルシート、JavaScriptを適切に設定する役割を持っています。