LoginSignup
6
6

More than 5 years have passed since last update.

HUGO + PostCSS + Netlifyでポートフォリオサイトを作った話

Last updated at Posted at 2018-09-29

はじめに

静的サイトジェネレーターのHUGO、Node.js製のCSSフレームワークであるPostCSS、ビルド + ホスティングサービスのNetlifyを使ってポートフォリオを作ったので、作り方を公開したいなと思い、作成しました。
https://shinya-sato.com/

shinya-sato.com_.png

今回は 「どうやって作ったか」 について書いているので、ポートフォリオの構成とかについては原則書かない事にしておきます。

HUGO

HUGOとは、Go言語製の静的サイトジェネレーターです。
「シンプルだが多機能」という特徴があります。
生のhtmlをそのまま編集するのと同じ要領で、「関連記事の表示」「多言語対応」等の高等な機能も持ち合わせています。

何故HUGOを選んだのか

結論からいうと、 参考にしたポートフォリオサイトがHUGOで実装されていたからです。
Jekyllはbuildが遅いし、カスタム投稿のページネーションは実装できないなど、痒いところに手が届かなかったので、他の静的サイトジェネレーターを探していました。
StaticGenを見たら、GithubのStar数も多いので使ってみました。

HUGOをインストールする

まずはhomebrewを使って、HUGOをインストールします。
brew install hugo

Repositoryをcloneする

さっそく作り始める、のではなく、 参考にするRepositoryをcloneするところから 始めます。
そして、 技術を徹底的にパクリまくります。

HUGOでサイトを作り始める

ある程度技術を盗んだら、早速HUGOでサイトを作り始めます。

hugo new site directory_name
Congratulations! Your new Hugo site is created in /Users/cookboys/documents/directory_name.

Just a few more steps and you're ready to go:

1. Download a theme into the same-named folder.
   Choose a theme from https://themes.gohugo.io/, or
   create your own with the "hugo new theme <THEMENAME>" command.
2. Perhaps you want to add some content. You can add single files
   with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>".
3. Start the built-in live server via "hugo server".

Visit https://gohugo.io/ for quickstart guide and full documentation.

HUGOを立ち上げてみる

コマンドを叩いたら、HUGOのサイトが出来ていると思いますので、ディレクトりに移動します。
cd directory_name

ディレクトりに移動したら、コマンドを叩いて、HUGOを立ち上げてみたいと思います。
hugo server -w
hugo-start.png
何も表示されていません(Jekyllと違って、サンプル画面すらありません)
HUGOは必要最小限の動作環境だけ提供されるので、ここから自分で環境を構築していきます。

PostCSSを導入する

必要最小限の環境しかありませんので、AltCSSの環境も自分で用意する必要があります。
なので今回は、Node.js製のCSSフレームワークである、PostCSSを導入してみたいと思います。

なぜPostCSSなのか

単刀直入に言うと、

  • Sassに飽きたから
  • トランスパイルが早いから
  • 実績ある企業が採用しているから(Facebook, Github, Qiita, Taobao等)

そもそもPostCSSって何?

PostCSSとは、先ほど申した通り、Node.js製のCSSフレームワークです。
Node.js製といえば、StylusというCSSプリプロセッサーがありますが、PostCSSはStylusと違い、インストールしただけでは何もしれくれません!
「CSSフレームワーク」の名の通り、PostCSSはプラグインを追加して、自分独自のCSSプリプロセッサーを作るツールなのです。
なので、プラグインを追加しないと、何もしれくれません。

  • Stylusの場合
    stylus.png
    Node.jsが、.styl形式で書かれたファイルを、CSSに変換する。

  • Sassの場合
    sass.png
    Rubyが、.sass形式で書かれたファイルを、CSSに変換する。

  • PostCSSの場合
    postcss.png
    Node.jsが、ファイルをCSSに変換するのはStylusと同じですが、拡張子が.cssのままです。
    当然ですが、このままでは使えるCSSになりません。
    @reset-global pc;も、@custom-media --smartphone(width <= 600px);も、CSSの構文には存在しないからです。
    これらを使えるようにするには、PostCSSのプラグインを追加しないといけません。

PostCSSを使えるようにする

では実際に、PostCSSを使えるようにしていきたいと思います。

npmを導入する

HUGOのディレクトリで、以下のコマンドを実行して、npmを導入します。
npm init

yarnをインストールする

以下のコマンドを実行して、yarnをインストールします。
npm install -g yarn

PostCSSをインストールする

以下のコマンドを実行して、PostCSSをインストールします。
yarn add postcss

CLIをインストールする

以下のコマンドを実行して、postcss-cliをインストールします。
yarn add postcss-cli

CLIの設定をする

CLIを使うために、設定ファイルの作成と、スクリプトを設定します。

  • postcss.config.js
module.exports = (ctx) => ({
  plugins: []
});
  • package.json
{
  "scripts": {
    "start": "hugo server -w & postcss postcss/*.css -d static/assets/styles/ -w",
    "build": "hugo & postcss postcss/*.css -d docs/assets/styles/"
  },
  "dependencies": {
    "postcss": "^6.0.19",
    "postcss-cli": "^5.0.0"
  }
}

HUGOを実行するスクリプトと、PostCSSを実行するスクリプトを一緒にしました。
これで、yarn startを実行すると、HUGOとPostCSSが同時に起動します。

PostCSSのプラグインをインストールする

さて、準備ができましたので、この画像のCSSを使えるようにするために、PostCSSのプラグインをインストールします。

postcss02.png

yarn add postcss-css-reset postcss-mixins postcss-simple-vars postcss-color-function postcss-nested postcss-custom-media postcss-media-minmax 
  • postcss-css-reset

    • PostCSSでreset.cssを設定できる。
  • postcss-mixins

    • Postcssでmixinsを設定できる。
  • postcss-simple-vars

    • $を使った変数を使うことができる。
  • postcss-color-function

    • color変数を使うことができる。
  • postcss-nested

    • PostCSSでNest(入れ子)を使うことができる。
  • postcss-custom-media

    • @mediaに名前をつけてコンポーネント化することができる。
  • postcss-media-minmax

    • @mediaを不等号で指定できる。

configファイルに設定を記載する

プラグインを追加しただけではまだダメなので、postcss.config.jsに設定を記載します。

module.exports = (ctx) => ({
  plugins: [
    require('postcss-css-reset'),
    require('postcss-mixins'),
    require('postcss-simple-vars'),
    require('postcss-color-function'),
    require('postcss-nested'),
    require('postcss-custom-media'),
    require('postcss-media-minmax')
  ]
});

この順番通りにプラグインが読み込まれるので、順番は非常に重要です。

HUGOで条件分岐をする

PostCSSの設定が終わったので、HUGOに戻ります。

トップページのタイトルを変える

トップページはタイトルを変えたいので、条件分岐を設定していきます。

<title>{{if .IsHome}}{{ .Site.Params.homeTitle }}{{ else }}{{ .Title }}{{ end }} | {{ .Site.Params.SiteName }}</title>

これで、トップページの際はconfig.tomlで設定した、homeTitleが呼び出されて、それ以外のページはHUGOのFrontMatterで設定したTitleが呼び出されます。

その他の条件分岐も設定していきます

<meta name="keywords" content="{{ with .Params.Keyword }}{{ . }}{{ else }}{{ .Site.Params.Keyword }}{{ end }}">
<meta name="description" content="{{ with .Params.Description }}{{ . }}{{ else }}{{ .Site.Params.Description }}{{ end }}">
<meta property="og:title" content="{{if .IsHome}}{{ .Site.Params.homeTitle }}{{ else }}{{ .Title }}{{ end }} | {{ .Site.Params.SiteName }}">
<meta property="og:description" content="{{ with .Params.excerpt }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }}">
<meta property="og:url" content="{{ .Permalink }}">
<meta property="og:image" content="{{ .Site.BaseURL }}{{ with .Params.ogp }}{{ . }}{{ else }}images/ogp.jpg{{ end }}">
<meta property="og:type" content="{{if .IsHome}}website{{ else }}article{{ end }}">
<meta property="og:site_name" content="{{ .Site.Params.SiteName }}">
<meta property="og:locale" content="{{ .Site.Params.LanguageCode }}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{if .IsHome}}{{ .Site.Params.homeTitle }}{{ else }}{{ .Title }}{{ end }} | {{ .Site.Params.SiteName }}">
<meta name="twitter:description" content="{{ with .Params.excerpt }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }}">
<meta name="twitter:image:src" content="{{ .Site.BaseURL }}{{ with .Params.ogp }}{{ . }}{{ else }}images/twitter_ogp.jpg{{ end }}">
<meta name="twitter:domain" content="{{ .Site.Params.Domain }}">
<meta name="keywords" content="{{ with .Params.Keyword }}{{ . }}{{ else }}{{ .Site.Params.Keyword }}{{ end }}">

上記の条件分岐の場合、HUGOのFrontMatter内にkeywordがあれば呼び出し、ない場合はconfig.tomlで設定した、Keywordが呼び出されます。

---
title: "title"
keyword: "keywordが入ります"
date: 2018-04-05
categories: ['photos']
caption: "Photoshop"
eyecatch: '/images/photos/photo01_firstview_ja.png'
ogp: 'images/photos/photo01_firstview.png'
url: '/photos/photo01/'
draft: false
---

上記の場合は、keywordが入りますが呼び出され、もしない場合はconfig.tomlで設定した、Keywordが呼び出されます。

部品をコンポーネント化していく

HUGOのPartialを使って、繰り返し使いそうな部品はコンポーネント化しておきます。

<!DOCTYPE html>
<html lang="{{ .Site.Params.LanguageCode }}">
<head>
  <meta charset="UTF-8">
  <title>{{if .IsHome}}{{ .Site.Params.homeTitle }}{{ else }}{{ .Title }}{{ end }} | {{ .Site.Params.SiteName }}</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <meta name="keywords" content="{{ with .Params.Keyword }}{{ . }}{{ else }}{{ .Site.Params.Keyword }}{{ end }}">
  <meta name="description" content="{{ with .Params.Description }}{{ . }}{{ else }}{{ .Site.Params.Description }}{{ end }}">
  {{ partial "ogp.html" . }}
  {{ partial "styles.html" . }}
</head>

多言語対応していく

作っていく途中で多言語対応をしたくなったので、やってみました。
これが、HUGOの目玉機能の一つです。

参考にしたポートフォリオは多言語対応していなかったので、Githubを検索しまくって、参考になりそうなRepositoryを探します。

SkycoinのRepositoryを真似る

Skycoinのブログが、一番機能的に豊富で、わかりやすい構成になっていたので、
SkycoinのブログのRepositoryを真似ることにしました。

Netlifyに対応させていく

最初はGithub Pagesを使ってサイトを公開していましたが、以下の理由から、Netlifyに乗り換えました。

  • 独自ドメインのSSL対応が大変
  • 毎回buildコマンドを打つのが面倒になった
  • Formを使ってみたくなった

Formは、Netlifymが提供しているNetlify Formsを使って、簡単に導入することができました。

<div class="form__wrapper">
  <form name="contact" netlify-honeypot="bot-field" action="thank-you" method="post" netlify="true">
  <input type="hidden" name="form-name" value="contact" />
    <h2>{{ i18n "formTitle" }}</h2>
    <div class="field__container">
      <div class="field__contents">
        <div class="mc-field-group field__input">
          <div class="form__label__wrapper">
            <figure class="gopher__wrapper"><img src="{{ .Site.BaseURL }}images/icon/gopher_h.svg" alt=""></figure>
            <label class="form__label">{{ i18n "formName" }}<span class="span__required">{{ i18n "formRequired" }}</span></label>
          </div>
          <input type="text" name="NAME" required>
        </div>
        <div class="mc-field-group field__input">
          <div class="form__label__wrapper">
            <figure class="gopher__wrapper"><img src="{{ .Site.BaseURL }}images/icon/gopher_u.svg" alt=""></figure>
            <label class="form__label">{{ i18n "formMailaddress" }}<span class="span__required">{{ i18n "formRequired" }}</span></label>
          </div>
          <input type="email" name="EMAIL" required>
        </div>
      </div>
      <div class="field__contents">
        <div class="mc-field-group field__textarea">
          <div class="form__label__wrapper">
            <figure class="gopher__wrapper"><img src="{{ .Site.BaseURL }}images/icon/gopher_o.svg" alt=""></figure>
            <figure class="gopher__wrapper"><img src="{{ .Site.BaseURL }}images/icon/gopher_g.svg" alt=""></figure>
            <label class="form__label">{{ i18n "formInquiry" }}<span class="span__required">{{ i18n "formRequired" }}</span></label>
          </div>
          <textarea name="Message" cols="30" rows="10" required></textarea>
        </div>
      </div>
    </div>
    <div class="form__button__wrapper">
      <button class="submit__button" type="submit">{{ i18n "formSubmit" }}</button>
    </div>
  </form>
</div>

まとめ

HUGOはシンプルだが多機能、かつ動作も速く、
PostCSSは設定が大変だが、これもNode製だから動作も早く、プラグインを組み合わせて自分だけのCSSプリプロセッサーを作ることができます。
Netlifyは、ただのホスティングサービスだけでなく、静的サイトジェネレーターの弱点であるFormまで補ってくれる、とても素晴らしいサービスでした。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6