Node.js で小規模なアプリケーションを開発する方法 その6

# はじめに
ついにその1から書き始めて1日空いてしまいました、昨日は新規事業の準備が楽しすぎてつい優先してしまいました。3週間続くと一生続くらしいので今日からまた21日間連続投稿を目指して頑張ります。

今日まで何気なく記事を書いて投稿していましたが、もしかしたら弊社の若手のプログラマーさんの勉強に使ってもらえるかもしれないので、今日からもうちょっと整理して書くように心がけます。

今はソースコードの書き方だけですが、ゆくゆくは小規模なアプリケーションの開発に含まれる下記の作業のノウハウをまとめていければと思っています。

- テストコード
- 操作手順書
- テスト仕様書
- 設計仕様書
- 契約書
- 提案書
- 見積書

全部完成するのはいつになることやら... もし、この記事を読んでくださってる方で、どれか優先したいものがあれば是非コメントをください。ここを知りたいというのがあればそれを重点的に書きますし、何より僕の励みになりますので(^^)

# 必要なページ
その5で定義した使用者の権限を満足するため、下記のページを設けます。

- / トップページ
- /admin/ ダッシュボードページ
- /admin/account/login/ ログイン
- /admin/account/logout/ ログアウト
- /admin/projects/ プロジェクト一覧ページ
- /admin/projects/add/ プロジェクト新規登録ページ
- /admin/projects/:id/ プロジェクト詳細ページ
- /admin/projects/:id/edit/ プロジェクト修正変更ページ
- /admin/projects/:id/delete/ プロジェクト削除ページ
- /admin/reports/ 日報一覧ページ
- /admin/reports/add/ 日報新規登録ページ
- /admin/reports/:id/ 日報詳細ページ
- /admin/reports/:id/edit/ 日報修正変更ページ
- /admin/reports/:id/delete/ 日報削除ページ

# app/index.js の編集

```app/index.js``` を下記のように編集します。

```app/index.js(編集前)
'use strict';

var env = process.env.NODE_ENV || 'development'

var url = require('url')
var path = require('path')
var morgan = require('morgan')
var express = require('express')
var serveStatic = require('serve-static')
var proxyMiddleware = require('proxy-middleware')
var pages = require('./routes/pages')

var siteConfig = require('./config/site')[env]

module.exports = factory

function factory(options) {
  options = options || {}

  var staticPath = options.staticPath
  var app = express()

  app.set('strict routing', true)
  app.set('views', path.join(__dirname, 'views'))
  app.set('view engine', 'jade')

  app.locals.baseUrl = siteConfig.baseUrl

  app.use(morgan('dev'))
  app.get('/', pages.anonymous.home())

  if (env === 'development') {
    app.use('/static', proxyMiddleware(url.parse('http://127.0.0.1:8080')))
  } else {
    app.use('/static', serveStatic(staticPath))
  }

  return app
}

```

```app/index.js(編集後)
'use strict';

var env = process.env.NODE_ENV || 'development'

var url = require('url')
var path = require('path')
var morgan = require('morgan')
var express = require('express')
var serveStatic = require('serve-static')
var proxyMiddleware = require('proxy-middleware')

var pages = require('./routes/pages')
var account = require('./routes/account')
var reports = require('./routes/reports')
var projects = require('./routes/projects')

var siteConfig = require('./config/site')[env]

module.exports = factory

function factory(options) {
  options = options || {}

  var staticPath = options.staticPath
  var app = express()

  app.set('strict routing', true)
  app.set('views', path.join(__dirname, 'views'))
  app.set('view engine', 'jade')

  app.locals.baseUrl = siteConfig.baseUrl

  app.use(morgan('dev'))
  app.get('/', pages.anonymous.home())

  app.get('/admin/', pages.admin.dashboard())
  app.use('/admin/account', account.admin.html)
  app.use('/admin/reports', reports.admin.html)
  app.use('/admin/projects', projects.admin.html)

  if (env === 'development') {
    app.use('/static', proxyMiddleware(url.parse('http://127.0.0.1:8080')))
  } else {
    app.use('/static', serveStatic(staticPath))
  }

  return app
}

```

変更点は下記の通りです。

```
diff --git a/app/index.js b/app/index.js
index 31f9fb8..ab92668 100644
--- a/app/index.js
+++ b/app/index.js
@@ -8,7 +8,11 @@ var morgan = require('morgan')
 var express = require('express')
 var serveStatic = require('serve-static')
 var proxyMiddleware = require('proxy-middleware')
+
 var pages = require('./routes/pages')
+var account = require('./routes/account')
+var reports = require('./routes/reports')
+var projects = require('./routes/projects')
 
 var siteConfig = require('./config/site')[env]
 
@@ -29,6 +33,11 @@ function factory(options) {
   app.use(morgan('dev'))
   app.get('/', pages.anonymous.home())
 
+  app.get('/admin/', pages.admin.dashboard())
+  app.use('/admin/account', account.admin.html)
+  app.use('/admin/reports', reports.admin.html)
+  app.use('/admin/projects', projects.admin.html)
+
   if (env === 'development') {
     app.use('/static', proxyMiddleware(url.parse('http://127.0.0.1:8080')))
   } else {

```

まだRouterを追加していないので起動しようとすると```routes/account.js```などが見つからない旨のエラーが表示されます。

# Routerの追加

まずは```pages.js```を編集します。

```app/routes/pages.js(変更前)
'use strict';

module.exports = {
  anonymous: {
    home: anonymousHome,
  },
}

function anonymousHome() {
  return function (req, res) {
    res.render('pages/anonymous-home.jade')
  }
}

```

```app/routes/pages.js(変更後)
'use strict';

module.exports = {
  admin: {
    dashboard: adminDashboard,
  },

  anonymous: {
    home: anonymousHome,
  },
}

function adminDashboard() {
  return function (req, res) {
    res.render('pages/admin-dashboard')
  }
}

function anonymousHome() {
  return function (req, res) {
    res.render('pages/anonymous-home')
  }
}

```

変更点は下記の通りです。

```
diff --git a/app/routes/pages.js b/app/routes/pages.js
index 480a631..5ee08de 100644
--- a/app/routes/pages.js
+++ b/app/routes/pages.js
@@ -1,13 +1,23 @@
 'use strict';
 
 module.exports = {
+  admin: {
+    dashboard: adminDashboard,
+  },
+
   anonymous: {
     home: anonymousHome,
   },
 }
 
+function adminDashboard() {
+  return function (req, res) {
+    res.render('pages/admin-dashboard')
+  }
+}
+
 function anonymousHome() {
   return function (req, res) {
-    res.render('pages/anonymous-home.jade')
+    res.render('pages/anonymous-home')
   }
 }

```

```routes``` ディレクトリに ```account.js```, ```reports.js```, ```projects.js``` を追加します。

```
touch routes/account.js
touch routes/reports.js
touch routes/projects.js
```

それぞれ内容は下記の通りです。

```account.js
'use strict';

var express = require('express')

var adminHtml = express.Router({ strict: true })

module.exports = {
  admin: {
    html: adminHtml,
  },
}

adminHtml.get('/login/', adminHtmlLogin())
adminHtml.get('/logout/', adminHtmlLogout())

function adminHtmlLogin() {
  return function (req, res) {
    res.render('account/admin-login')
  }
}

function adminHtmlLogout() {
  return function (req, res) {
    res.render('account/admin-logout')
  }
}

```

```reports.js
'use strict';

var express = require('express')

var adminHtml = express.Router({ strict: true })

module.exports = {
  admin: {
    html: adminHtml,
  },
}

adminHtml.get('/', adminHtmlList())
adminHtml.get('/add/', adminHtmlAdd())
adminHtml.get('/:id([0-9]+)/', adminHtmlDetail())
adminHtml.get('/:id([0-9]+)/edit/', adminHtmlEdit())
adminHtml.get('/:id([0-9]+)/delete/', adminHtmlDelete())

function adminHtmlList() {
  return function (req, res) {
    res.render('reports/admin-list')
  }
}

function adminHtmlAdd() {
  return function (req, res) {
    res.render('reports/admin-add')
  }
}

function adminHtmlDetail() {
  return function (req, res) {
    res.render('reports/admin-detail')
  }
}

function adminHtmlEdit() {
  return function (req, res) {
    res.render('reports/admin-edit')
  }
}

function adminHtmlDelete() {
  return function (req, res) {
    res.render('reports/admin-delete')
  }
}

```

```projects.js
'use strict';

var express = require('express')

var adminHtml = express.Router({ strict: true })

module.exports = {
  admin: {
    html: adminHtml,
  },
}

adminHtml.get('/', adminHtmlList())
adminHtml.get('/add/', adminHtmlAdd())
adminHtml.get('/:id([0-9]+)/', adminHtmlDetail())
adminHtml.get('/:id([0-9]+)/edit/', adminHtmlEdit())
adminHtml.get('/:id([0-9]+)/delete/', adminHtmlDelete())

function adminHtmlList() {
  return function (req, res) {
    res.render('projects/admin-list')
  }
}

function adminHtmlAdd() {
  return function (req, res) {
    res.render('projects/admin-add')
  }
}

function adminHtmlDetail() {
  return function (req, res) {
    res.render('projects/admin-detail')
  }
}

function adminHtmlEdit() {
  return function (req, res) {
    res.render('projects/admin-edit')
  }
}

function adminHtmlDelete() {
  return function (req, res) {
    res.render('projects/admin-delete')
  }
}

```

これでひとまずは起動するようになるはずです、起動してかったらどこかにタイプミスなどがあるか、この記事が間違っている可能性が高いです。後者の場合は恐れ入りますがご連絡ください。

# Viewの追加
```app/views``` にファイルを作成します。

- pages/admin-dashboard.jade
- account/admin-login.jade
- account/admin-logout.jade
- reports/admin-add.jade
- reports/admin-edit.jade
- reports/admin-list.jade
- reports/admin-delete.jade
- reports/admin-detail.jade
- projects/admin-add.jade
- projects/admin-edit.jade
- projects/admin-list.jade
- projects/admin-delete.jade
- projects/admin-detail.jade

それぞれ内容は下記の通りです。

```account/admin-login.jade
extends ../layouts/full-width/admin

```

```account/admin-login.jade以外
extends ../layouts/2-column/admin

```

動作確認のために```views/layouts/2-column/admin.jade```を編集します。

```views/layouts/2-column/admin.jade(変更前)
extends ./base

block sub
  ul.nav
    li
      a(href='#{baseUrl}/admin/lorem/') Lorem
    li
      a(href='#{baseUrl}/admin/ipsum/') Ipsum
    li
      a(href='#{baseUrl}/admin/dolor/') Dolor
    li
      a(href='#{baseUrl}/admin/sit/') Sit
    li
      a(href='#{baseUrl}/admin/amet/') Amet

```

```views/layouts/2-column/admin.jade(変更後)
extends ./base

block sub
  ul.nav
    li
      a(href='#{baseUrl}/admin/') ダッシュボード
    li
      a(href='#{baseUrl}/admin/projects/') 案件一覧
    li
      a(href='#{baseUrl}/admin/reports/') レポート一覧
    li
      a(href='#{baseUrl}/admin/account/logout/') ログアウト

```

変更点は下記の通りです。

```
diff --git a/app/views/layouts/2-column/admin.jade b/app/views/layouts/2-column/admin.jade
index c750c5e..b22940f 100644
--- a/app/views/layouts/2-column/admin.jade
+++ b/app/views/layouts/2-column/admin.jade
@@ -3,12 +3,10 @@ extends ./base
 block sub
   ul.nav
     li
-      a(href='#{baseUrl}/admin/lorem/') Lorem
+      a(href='#{baseUrl}/admin/') ダッシュボード
     li
-      a(href='#{baseUrl}/admin/ipsum/') Ipsum
+      a(href='#{baseUrl}/admin/projects/') 案件一覧
     li
-      a(href='#{baseUrl}/admin/dolor/') Dolor
+      a(href='#{baseUrl}/admin/reports/') レポート一覧
     li
-      a(href='#{baseUrl}/admin/sit/') Sit
-    li
-      a(href='#{baseUrl}/admin/amet/') Amet
+      a(href='#{baseUrl}/admin/account/logout/') ログアウト

```

上記の追加・編集が完了したら http://localhost:3000/admin/ にアクセスします。うまくいくとサブカラムに案件一覧などへのリンクが表示されますのでクリックして404やビューが見つからないエラーなどが発生しないかどうかを確かめます、問題がなければOKです。

# おわりに
前回の投稿から今回の投稿まで日が空いてしまいました、しっかりと自己管理して継続したいと思います。

次回は、アプリケーション開発の流れを検討しておこうと思います。初回にやれよ！って感じですが書き始めた時はこれを自社の若手のプログラマーさんの学習に役立ててもらおうと思ってなかったので、徒然なるままに書いてしまいました...

何事も計画性が大事であることを学びました。