【Hugo】ゴリラでも分かる静的サイトジェネレーターHugoでオリジナルテーマ作り
ゴリラ素材は、最近ゴリラくんシールを作り出した素材工場さんから。
ゴリラくんシールの使用例
ゴリラくんシールは3月5日に大阪梅田にて開催される「FRONTEND CONFERENCE 2016」で配られるみたいです。
FRONTEND CONFERENCEも面白そうですね。
最近、静的サイトジェネレーターに興味を持ちましして、
Go言語製の「Hugo」でブログを作ってみました。
そのブログはこちら
Pickles
Hugoには配布されているテーマもありますが、オリジナルで作りたい人もいると思うので、
制作手順をまとめてみました。
(なんでWordPressで書いてるの?というツッコミは置いといて…。)
目次
- Hugoの特徴
- Hugoの導入
- Hugoをはじめる
- オリジナルテーマ作り
- HTMLの部品化
- CSSの作成
- 個別記事ページの作成
- 記事を作成してみる
- 記事一覧に記事情報を表示
- ページネーションをつける
- 固定ページを作る
Hugoの特徴
HugoはGo言語で動いている静的サイトジェネレーターです。
静的サイトジェネレーターというとJekllyやHexo、Middleman、Wintersmithとかよく聞きます。
それぞれ特徴があるわけで、Hugoのいいところはサイトの生成が速い(らしい)。
生成が速いと何がいいのか?
静的サイトジェネレーターでサイトを作る場合、
WordPressのようにテンプレート化したものから全てのページのHTMLファイルが生成されます。
この生成に時間がかかってしまうと、記事を書いたり、サイトの修正をしたり、公開用にデプロイするときなど、
事あるごとに待たされてしまいます。
生成時間を比較したブログがあったので参考までに。
静的サイトジェネレータの生成時間比較
数記事だとそんなに差はないですが、記事数がどんどん増えていくとHugoの速さが分かります。
この記事をもとにすると、例えばちょっとフォントのサイズを変えて確認したいとき、
10記事程度しかなくても、Octopressだとフォントサイズの変更から実際確認するまで約3秒もかかることになります。
たかが3秒ですが、これが積み重なると結構苦痛…。
それに対してHugoは10記事で0.2秒。1000記事でも1秒かかっていません。
生成までほんの一瞬です。
Hugoの欠点
Hugoの欠点はデザインテーマが少ないとか、
公開されてるけど個性的などよく挙げられてます。
Hugo Themes Site
ってことで自分で作りましょう。
Hugoの導入
Macでの導入方法です。
Windowsは…調べてください。
Githubからダウンロードする方法もありますが、
Homebrewでインストールしてみます。
HomebrewはRubyを使いますので、Rubyをインストールしておいてください。
ただ、Macは標準で入ってるので大丈夫なはず。
Ruby
Homebrewのインストール
以下のコマンドでHomebrewをインストールします。
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
次に以下コマンドを
$ brew doctor
その結果、最新版のインストールが可能な場合は以下のコマンドで最新にしておきます。
$ brew update
Hugoのインストール
Homebrewが入ったら以下のコマンドでHugoをインストールします。
brew install hugo
インストール後以下コマンドでバージョンが表示されたらインストール完了です。
$ hugo version
Hugoをはじめる
Hugoのインストールができたので、サイトを作成してみます。
まずは以下コマンドでファイル一式を作成します。
hugo new site ディレクトリ名
newthemeという名前で作ってみました。
hugo new site newtheme
するとnewthemeというディレクトリができ、中に以下のようなファイルができあがります。
生成されたファイルについて
hugo new siteコマンドで生成されたファイルやディレクトリの役割を紹介します。
archetypes
記事を書くための「〇〇.md」というデフォルトのマークダウンファイルを置くディレクトリです。
新しく記事を書くコマンドを打った時、このマークダウンファイルの内容を元に作られます。
デフォルトは空。
config.toml
サイトの設定をするファイル。
デフォルトではサイトのURLや言語、サイトのタイトルを設定する記述が書かれています。
baseurl = "http://xxx.com/" languageCode = "en-us" title = "My New Hugo Site"
パラメーターを追記すれば、独自の設定を追加できます。
baseurl = "http://xxx.com/" languageCode = "ja" title = "サイトのタイトル" [Params] description = "サイトの説明" twitter_account = "xxxxxx" github_account = "xxxxxx" analytics = "UA-01234567-8"
content
マークダウンファイルの置き場です。
マークダウンファイルを新規作成するコマンドを打てば、このディレクトリ内に生成されます。
記事生成のコマンド
hugo new xxx.md
ブログ記事を書く場合は、このディレクトリ内にマークダウンファイルを追加し、
記事を書いていきます。
data
config.toml以外にサイトで使うデータを設定できるフォルダ。
YAML、JSON、TOMLが使えるようです。
config.tomlと同じような書き方です。
layouts
ディレクトリ名の通り、サイトのレイアウトとなるファイルを置く場所。
ここにオリジナルのindex.htmlなどを作っていきます。
static
ここに置いたファイルは記事生成時にそのまま公開ディレクトリ(後述)内にコピーされます。
例えばCSSやJS、画像などを置いておきます。
オリジナルテーマを作る前に…
この後オリジナルテーマを作っていきますが、
別に配布テーマでいいという場合は、「themes」ディレクトリを作ります。
その中に、テーマファイル一式を置き、以下コマンドでそのテーマでサイトを生成できます。
hugo -t テーマ名
オリジナルテーマ作り
オリジナルテーマ作りの大まかな流れは、
- layoutsディレクトリでhtmlを作成
- staticディレクトリでCSSを作成
- contentディレクトリで記事を書く
という感じです。
オリジナルテーマの仕様
今回は以下の仕様のブログテーマを作ってみます。
- トップページで記事を10件表示
- 記事作成日と記事タイトルを表示
- 10件より多い場合はページネーションを表示
最低限のブログ機能を実装してみます。
HTMLファイル
HTMLファイルはシンプルに以下のような感じにしています。
html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>newtheme</title> <link rel="stylesheet" href="style.css"> </head> <body> <header> <h1>newtheme</h1> </header> <main> <article> <ul> <li><a href="#"><span>2016/02/10</span>記事タイトル10</a></li> <li><a href="#"><span>2016/02/09</span>記事タイトル9</a></li> <li><a href="#"><span>2016/02/08</span>記事タイトル8</a></li> <li><a href="#"><span>2016/02/07</span>記事タイトル7</a></li> <li><a href="#"><span>2016/02/06</span>記事タイトル6</a></li> <li><a href="#"><span>2016/02/05</span>記事タイトル5</a></li> <li><a href="#"><span>2016/02/04</span>記事タイトル4</a></li> <li><a href="#"><span>2016/02/03</span>記事タイトル3</a></li> <li><a href="#"><span>2016/02/02</span>記事タイトル2</a></li> <li><a href="#"><span>2016/02/01</span>記事タイトル1</a></li> </ul> </article> <nav> <a href="#">前へ</a> <a href="#">次へ</a> </nav> </main> <footer> <small>copyright</small> </footer> </body> </html>
HTMLの部品化
ヘッダーやフッターなどサイト内で共通になる部分は部品として、別ファイルにしておきます。
header.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>newtheme</title> <link rel="stylesheet" href="style.css"> </head> <body> <header> <h1>newtheme</h1> </header> <main>
footer.html
</main> <footer> <small>copyright</small> </footer> </body> </html>
部品化したheader.htmlとfooter.htmlは、
layoutsディレクトリ内に「partials」ディレクトリを作成し、
その中に置いておきます。
部品の読み込み
部品として切り分けた、header.htmlとfooter.htmlをindex.htmlにで読み込みます。
partialsディレクトリ以下の部品を読み込むには以下のように書きます。
{{ partial "xxx.html" . }}
これを利用してindex.htmlを書き直すと以下のようになります。
index.html
{{ partial "header.html" . }} <article> <ul> <li><a href="#"><span>2016/02/10</span>記事タイトル10</a></li> <li><a href="#"><span>2016/02/09</span>記事タイトル9</a></li> <li><a href="#"><span>2016/02/08</span>記事タイトル8</a></li> <li><a href="#"><span>2016/02/07</span>記事タイトル7</a></li> <li><a href="#"><span>2016/02/06</span>記事タイトル6</a></li> <li><a href="#"><span>2016/02/05</span>記事タイトル5</a></li> <li><a href="#"><span>2016/02/04</span>記事タイトル4</a></li> <li><a href="#"><span>2016/02/03</span>記事タイトル3</a></li> <li><a href="#"><span>2016/02/02</span>記事タイトル2</a></li> <li><a href="#"><span>2016/02/01</span>記事タイトル1</a></li> </ul> </article> <nav> <a href="#">前へ</a> <a href="#">次へ</a> </nav> {{ partial "footer.html" . }}
表示を確認する
ここまできたら一旦表示を確認してみます。
ターミナルを使って、最初に作成したディレクトリへ移動します。
cd newtheme
そして以下コマンドを打ちます。
hugo server --watch
「hugo server」だけでもいいですが、「-watch」をつけるとhtmlやcssの変更時に自動更新してくれます。
特にエラーが出なければ「http://127.0.0.1:1313/」にアクセスすると表示を見ることができます。
たぶんこんな感じになってるはず。
そして、「hugo server」もしくは「hugo server -watch」をすると「public」ディレクトリが生成されていると思います。
中身はこんな感じで、部品化したheaderやfooterとindex.htmlを結合して、書き出してくれています。
CSSの作成
CSSを使って見た目を整えます。
まずは、「static」ディレクトリ内にstyle.cssを作成します。
CSSは好きなように作ってください。
一応html,cssは分かる人が見てるかなと思ってるので。
とりあえず進めたい方は適当に作ったものがあるのでコピペしてください。
* { margin: 0; padding: 0; } a { text-decoration: none; } li { list-style: none; } header, main, footer { width: 70%; max-width: 700px; margin: 0 auto; } header { padding-top: 16px; } header::after, .entry-header::after { content: ""; clear: both; display: block; } h1 { float: left; } main, nav, footer { margin-top: 40px; } li { margin-bottom: 16px; } li span { margin-right: 16px; } nav, footer { text-align: center; } .entry-date { float: right; } .entry-content { margin-top: 40px; }
CSSを読み込む
作ったCSSファイルを読み込むにはパスを指定しなければなりません。
header.htmlで以下のようにパスを書き換えます。
html.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>newtheme</title> <!-- 書き換え前 --> <!-- <link rel="stylesheet" href="style.css"> --> <!-- 書き換え後 --> <link rel="stylesheet" href="{{ .Site.BaseURL }}/style.css"> </head> <body> <header> <h1>newtheme</h1> </header> <main>
「{{ .Site.BaseURL }}」と書くと、「config.toml」で設定した「baseurl」を書き出してくれます。
つまり、絶対パスでしていすることになります。
このように書き換えて、再び実際の画面を見ると見た目が変わっていると思います。
個別記事ページの作成
記事の一覧ページの見た目はできたので、個別記事ページを作ってみます。
「layouts」ディレクトリ以下に「_default」ディレクトリを作ります。
ちなみに「layouts」ディレクトリ以下は現在このようになってるはず。
そして、「single.html」を作ります。
中身はこのようにしました。
single.html
{{ partial "header.html" . }} <article> <header class="entry-header"> <span class="entry-date">2016/02/01</span> <h1 class="entry-title">サンプルブログ記事のタイトル</h1> </header> <div class="entry-content"> <p>テスト記事です。</p> </div> </article> {{ partial "footer.html" . }}
共通部分のヘッダー、フッターはindex.htmlと同様に読み込んでおきます。
sigle.htmlのテンプレート化
sigle.htmlをテンプレート化し、記事作成日や記事のタイトル、記事内容によってhtmlが書き出されるように変更します。
先ほどのsingle.htmlを以下のように書き換えます。
{{ partial "header.html" . }} <article> <header class="entry-header"> <span class="entry-date">{{ .Date }}</span> <h1 class="entry-title">{{ .Title }}</h1> </header> <div class="entry-content"> <p>{{ .Content }}</p> </div> </article> {{ partial "footer.html" . }}
「{{ .Params.post_date }}」で記事の作成日、「{{ .Title }}」で記事タイトル、「{{ .Content }}」で記事の内容を読み出します。
記事を作成してみる
single.htmlで記事ページのテンプレートができたので、試しに記事を書いてみます。
ただ、その前にデフォルトのマークダウンファイルを作りましょう。
絶対必要ではないですが、自分用にあった方がいいと思います。
default.mdを作る
「archetypes」ディレクトリ以下に「default.md」というファイルを作ります。
そして、中身を以下のようにします。
+++ date = "" Title = "" +++
記事作成日、記事タイトルを書けるようにしています。
他にも独自に設定することもできますが、それは別の機会に書きます。
記事を作成する
現在「hugo server -watch」でプレビューを表示してる状態だと思いますが、一旦中止します。
ターミナルで「cntrol+c」で中止できます。
そして、以下コマンドで記事を作成します。
hugo new 記事タイトル.md
記事をディレクトリで区切ることもできます。
hugo new ディレクトリ名/記事タイトル.md
今回はやりませんが、後々カテゴリ別にリストを作ったりしたい場合はやっておくといいです。
では、試しに以下コマンドで新しいマークダウンファイルを作ります。
hugo new first.md
するとこんなメッセージが
newtheme/content/first.md created
「content」ディレクトリ以下をみると、マークダウンファイルができています。
タイトルと日付は自動で入ってますね。
そして、適当に書いてみます。
+++ Title = "Hello, World!" date = "2016-02-06T16:15:21+09:00" +++ Hugoでオリジナルブログを作るサンプル記事です。
書き終えたら、再度以下コマンドを
hugo server --watch
すると、「public」ディレクトリ内に記事のタイトル名のディレクトリができます。
first.mdというマークダウンファイルを作っていれば、
「http://127.0.0.1:1313/first/」にアクセスすると記事を表示できると思います。
日付の表示がちょっとイケてないので、
single.htmlの「{{ .Date }}」を以下に書き換えます。
<span class="entry-date">{{ .Date.Format "Jan 01, 2006" }}</span>
すると日付だけの表示になります。
記事一覧に記事情報を表示
記事一覧ページと個別記事を作りましたが、まだ記事一覧に先ほど書いた記事の情報は出ていません。
記事を書いたら、自動で記事一覧に追加してくれるように変更を加えます。
list.htmlを作る
「layouts」ディレクトリ内の「_default」内に「list.html」作ります。
そして以下のように書きます。
list.html
<li><a href="{{ .Permalink }}"> <span>{{ .Date.Format "Jan 02, 2006" }}</span>{{ .Title }} </a></li>
要はindex.htmlに書いてある繰り返すリストを書いています。
そして、index.htmlのliタグ部分を書き換えます。
index.html
{{ partial "header.html" . }} <article> <ul> {{ range (.Paginator 10).Pages }} {{ .Render "list" }} {{ end }} </ul> </article> <nav> <a href="#">前へ</a> <a href="#">次へ</a> </nav> {{ partial "footer.html" . }}
これで、再度トップページを表示すると、記事一覧に投稿日と記事タイトルが表示されていて、
それをクリックすると記事ページにリンクするようになりました。
ページネーションをつける
このまま記事の更新を続けると、記事の一覧がずっと下に続いてしまいます。
ページネーションをつけて、10記事目以降は次のページに追加されるようにします。
index.htmlのナビゲーション部分を以下に書き換えます。
{{ partial "header.html" . }} <article> <ul> {{ range (.Paginator 10).Pages }} {{ .Render "list" }} {{ end }} </ul> </article> {{ if or (.Paginator.HasPrev) (.Paginator.HasNext) }} <nav class="pagination"> {{ if .Paginator.HasPrev }} <a href="{{ .Paginator.Prev.URL }}">前へ</a> {{ end }} <span class="current-page">Page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }}</span> {{ if .Paginator.HasNext }} <a href="{{ .Paginator.Next.URL }}">次へ</a> {{ end }} </nav> {{ end }} {{ partial "footer.html" . }}
少し説明すると、「.Paginator.HasPrev」は前に記事一覧がある、
「.Paginator.HasNext」は次に記事一覧があるという条件です。
これを利用してページネーションを表示したり、非表示にしたりしています。
また、記事一覧のulタグ内に書かれている「{{ range (.Paginator 10).Pages }}の「10」という数字を変えれば、
一ページに何記事分表示させるかを指定できます。
公開ファイル
ここまででブログの最低限の機能をもたせてみました。
あとは、マークダウンファイルを新規作成して、記事を更新していきます。
実際に公開する場合、「pubulic」ディレクトリ内にできたファイル一式をサーバーにアップすると公開できます。
気をつけないといけないのは、
「hugo server -wathch」で生成されたファイル一式はURLが「http://127.0.0.1:1313/」になっています。
パスは絶対パスなので、このまま公開するとリンク先がない状態になってしまいます。
公開前に以下コマンドで生成し直します。
hugo
これで「config.toml」で指定したURLになります。
hugoコマンドを打った後にできた「pubulic」ディレクトリ以下のファイル一式を公開しましょう。
固定ページを作る
Hugoの続きの記事「固定ページを作る」を書きました。
さいごに
Hugoにはまだまだいろな機能があるみたいなので、続きはまた今度書こうと思います。
もっといい使い方もあるはず。。
最初にも書きましたがHugoは生成が早いので、長くブログを続けようと思っているならオススメです。