Express上でPugを使って静的なWebページを書くまでの全て


これの続き

環境

  • OS X El Capitan 10.11.6
  • Docker 17.03.0-ce-mac2
  • Express 4.15.2

前回までのあらすじ

  • express-generatorでプロジェクトを自動生成した
jumpage/
  ├ app/
  |  └ jumpage
  |    ├ app.js
  |    ├ bin
  |    |  └ www
  |    ├ public
  |    |  ├ images/
  |    |  ├ javascripts/
  |    |  └ stylesheet/
  |    ├ routes
  |    |  ├ index.js
  |    |  └ users.js
  |    ├ views
  |    |  ├ index.pug
  |    |  ├ layout.pug
  |    |  └ error.pug
  |    ├ node_modukes
  |    └ package.json
  ├ scripts/
  |  └ docker_run.sh
  └ Dockerfile

手順

Pugとは何かを理解する

  • HTMLを、少ない記述量で、簡単にかける
  • HTMLの中に、ループや継承などのロジックを組み込める

作りたいページの構成を考える

  • ポートフォリオサイトが欲しいので、ここではそれを作る
  • 全ページ共通部分
    • ヘッダー
      • タイトル
      • ナビゲーション
        • サイト上の他のコンテンツへのリンクを提供
    • フッター
      • コンタクト
        • Twitterへのリンク
  • コンテンツ部分
    • どのページも似たような構成になるので、レイアウトファイルを使い、差分だけを渡すようにしたい

Pugを使って実現する方法を考える

  • 全ページ共通部分
    • includeを使って、別ファイルに切り出す
  • コンテンツ部分
    • extendsを使って、レイアウトファイルを継承する
      • レイアウトファイルの一部をblockに設定し、後から差し替えることができる

Pugを学びつつ、最低限のbodyを書いてみる

コンテンツ部分の記述例

  • Pug
profile.pug
#profile
  h1#title 自己紹介
  #hobby.profile_item
    h2.subtitle 趣味
    .hobby_each
      h3 折り紙
      ul
        li.hobby_info 高校では折り紙研究部に所属
        li.hobby_info
          | 浪人時代に
          a(href='https://goo.gl/5dM954') ペーパークラフトでサクラダファミリア
          | を作成
        li.hobby_info 現在は、折り紙でtech系のロゴマークを作るのにはまっている
  • HTML変換後
<div id="profile">
    <h1 id="title">自己紹介</h1>
    <div class="profile_item" id="hobby">
        <h2 class="subtitle">趣味</h2>
        <div class="hobby_each">
            <h3>折り紙</h3>
            <ul>
                <li class="hobby_info">高校では折り紙研究部に所属</li>
                <li class="hobby_info">浪人時代に<a href="https://goo.gl/5dM954">ペーパークラフトでサクラダファミリア</a>を作成</li>
                <li class="hobby_info">現在は、折り紙でtech系のロゴマークを作るのにはまっている</li>
            </ul>
        </div>
    </div>
</div>

Pugで最低限覚えること

  • HTMLタグの<>を書かない
  • 内包関係を、インデント(字下げ)で表現
  • #hogeを付けるとid="hoge"に、.hogeを付けるとclass="hoge"になる
    • タグ名を省略すると、divタグになる
  • 属性は、タグ名の後に()で記述
  • プレーンテキスト
    • 1行: タグ名+半角スペース+Text
    • 複数行: タグ名+改行してインデント+|+半角スペース+Text
  • コメントは、//(htmlに残す)か//-(htmlに残さない)

ヘッダーとフッターを書く

  • ヘッダー
header.pug
doctype html
html(lang="ja")
  head
    meta(charset="utf-8")
    title jumpage
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    #header
      p#logo JUMPAGE
      #navigation
        ul
          li
            a(href='/portfolio/profile') 自己紹介
          li
            a(href='/portfolio/works') 作ったもの
      hr
  • フッター
footer.pug
#footer
  hr
  #twitter
    p
      | お問い合わせは
      a(href='https://twitter.com/jumpei_ikegami' target='_blank') @jumpei_ikegami
      | までお願いします

コンテンツ部分からheader.pugとfooter.pugをincludeする

profile.pug
include header.pug
#profile
  h1#title 自己紹介
//- 中略
include footer.pug

Expressのルーティングを設定する

  • "users"を"portfolio"に変更
app.js
// 略
-var users = require('./routes/users');
+var portfolio = require('./routes/portfolio');
// 略
-app.use('/users', users);
+app.use('/portfolio', portfolio);
// 略
  • routes/portfolio.jsを作成
routes/portfolio.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.redirect('/portfolio/profile');
});
router.get('/profile', function(req, res, next) {
  res.render('profile');
});
router.get('/works', function(req, res, next) {
  res.render('works');
});

module.exports = router;

profileページをブラウザで確認

コンテンツ部分のレイアウトファイルを作る

  • layout.pugを書き換える
layout.pug
include header.pug
block content
include footer.pug
  • block [block名]の部分は、継承先でHTMLの塊が渡されると、差し替えられる

profile.pugを、layout.pugを継承するように書き換える

profile.pug
extends layout.pug
block content
  #profile
    h1#title 自己紹介
    //- 以下略
  • block content以下の内容で、layout.pugの対応するblockが差し替えられる

別のページのコンテンツ(works.pug)を、同様に作成

works.pug
extends layout.pug
block content
  #works
    h1#title 作ったもの
    #application.works_item
      h2.application アプリケーション
      .application_each
        h3 histleap -タイムリープ型観光アプリ-
        ul
          li.application_info
            a(href='http://urbandata-challenge.jp/' target='_blank') アーバンデータチャレンジ2016
            | に提出するために作成したアプリ
          li.application_info
            a(href='https://goo.gl/fy4Ff0' target='_blank') GooglePlayストア
            | で公開中
          li.application_info
            | ソースコードは
            a(href='https://github.com/phlocs201/histleap' target='_blank') こちら
  • レイアウトファイルがあることで、ヘッダーやフッターの記述を繰り返し書かなくてもよくなって幸せ

worksページをブラウザで確認

ここまでのディレクトリ構造(再掲)

jumpage/
  ├ app/
  |  └ jumpage
  |    ├ app.js
  |    ├ bin
  |    |  └ www
  |    ├ public/
  |    |  ├ images/
  |    |  ├ javascripts/
  |    |  └ stylesheet
  |    |     └ style.css
  |    ├ routes
  |    |  ├ index.js
  |    |  └ portfolio.js
  |    ├ views
  |    |  ├ index.pug
  |    |  ├ layout.pug
  |    |  ├ header.pug
  |    |  ├ layout.pug
  |    |  ├ profile.pug
  |    |  ├ works.pug
  |    |  └ error.pug
  |    ├ node_modukes
  |    └ package.json
  ├ scripts/
  |  └ docker_run.sh
  └ Dockerfile