about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAlan Pearce2017-06-24 16:34:47 +0200
committerAlan Pearce2017-06-24 16:34:47 +0200
commitbdd6610208e9fe5971e6aed4378598092f2b9b5a (patch)
treedcb9d6c9ad8f3d91ca93106dce980e5a6012d517
parent6b02186505264dc5a05a74bce1f9dcc3f91d08e1 (diff)
downloadhomestead-bdd6610208e9fe5971e6aed4378598092f2b9b5a.tar.lz
homestead-bdd6610208e9fe5971e6aed4378598092f2b9b5a.tar.zst
homestead-bdd6610208e9fe5971e6aed4378598092f2b9b5a.zip
refactor: separate app, responders
-rw-r--r--src/app.js65
-rw-r--r--src/index.js124
-rw-r--r--src/responders.js76
-rw-r--r--test/app.test.js (renamed from test/index.test.js)2
4 files changed, 146 insertions, 121 deletions
diff --git a/src/app.js b/src/app.js
new file mode 100644
index 0000000..84722fc
--- /dev/null
+++ b/src/app.js
@@ -0,0 +1,65 @@
+'use strict'
+
+const Koa = require('koa')
+const app = new Koa()
+
+const streamify = require('stream-array')
+
+const send = require('koa-send')
+const responders = require('./responders.js')
+
+const config = require('./modules/config.js')
+
+const Router = require('koa-router')
+const router = new Router()
+
+app.context.getURL = router.url.bind(router)
+
+const Posts = require('./modules/posts.js')
+const posts = Posts.getFolder(config.posts.folder)
+
+function toArrayStream (iterator) {
+  return streamify(Array.from(iterator.entries()))
+}
+
+const postsStream = toArrayStream(posts)
+router.get('home', '/', async function (ctx, next) {
+  responders.home(ctx, config, postsStream)
+})
+
+router.get('post', '/post/:filename', async function (ctx, next) {
+  ctx.assert(posts.has(ctx.params.filename), 404, 'Post not found')
+  const post = posts.get(ctx.params.filename)
+  post.body = Posts.render(post)
+
+  responders.post(ctx, config, post)
+})
+
+const taxonomies = Posts.taxonomise(config.taxonomies, posts)
+for (let [term, items] of taxonomies) {
+  router.get(`taxon-${term}`, `/${term}/:value`, async function (ctx, next) {
+    const value = ctx.params.value
+    ctx.assert(
+      items.has(ctx.params.value),
+      404,
+      `Could not find ${term} ${value}`
+    )
+
+    const taxonItems = toArrayStream(items.get(value))
+
+    responders.taxon(ctx, config, taxonItems)
+  })
+}
+
+app.use(router.routes()).use(router.allowedMethods())
+
+const prefix = /^\/static\//
+app.use(async function (ctx) {
+  if (prefix.test(ctx.path)) {
+    await send(ctx, ctx.path.replace(prefix, ''), {
+      root: './static'
+    })
+  }
+})
+
+module.exports = app
diff --git a/src/index.js b/src/index.js
index a98a32d..a3e8dea 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,129 +1,13 @@
 'use strict'
 
-const Koa = require('koa')
-const app = new Koa()
-
-const fs = require('fs')
-const streamify = require('stream-array')
-
-const send = require('koa-send')
-
 const config = require('./modules/config.js')
 
 const PORT = process.env.PORT || config.server.port
 
-const Router = require('koa-router')
-const router = new Router()
-
-const rheo = require('rheo')
-
-const Posts = require('./modules/posts.js')
-const posts = Posts.getFolder(config.posts.folder)
-
-const templateReader = template => () =>
-  fs.createReadStream(`${__dirname}/templates/${template}.html`)
-const templates = {
-  layout: templateReader('layout'),
-  home: templateReader('home'),
-  post: templateReader('post'),
-  taxon: templateReader('taxon')
-}
-
-function setTitle (pageTitle) {
-  return rheo.template(function (s) {
-    return s
-      .inner('title', rheo((pageTitle ? ' · ' : '') + config.site.title))
-      .inner('body header h1', rheo(config.site.title))
-  })
-}
-
-function renderPostListItem (template, [, post]) {
-  return template
-    .attribute('a', 'href', () => router.url('post', post.basename))
-    .inner('a', () => rheo(post.data.get('title')))
-}
-
-function toArrayStream (iterator) {
-  return streamify(Array.from(iterator.entries()))
-}
-
-function showPage (name) {
-  return function (els) {
-    return rheo(templates[name]())
-  }
-}
-
-const postsStream = toArrayStream(posts)
-router.get('home', '/', async function (ctx, next) {
-  ctx.set('Content-Type', 'text/html')
-  ctx.body = templates
-    .layout()
-    .pipe(rheo())
-    .outer('main', showPage('home'))
-    .inner('.posts', function (postsTemplate) {
-      return postsStream.pipe(postsTemplate.map(renderPostListItem))
-    })
-    .pipe(setTitle())
-    .render()
-})
-
-router.get('post', '/post/:filename', async function (ctx, next) {
-  ctx.assert(posts.has(ctx.params.filename), 404, 'Post not found')
-  const post = posts.get(ctx.params.filename)
-  post.body = Posts.render(post)
-
-  ctx.set('Content-Type', 'text/html')
-  ctx.body = templates
-    .layout()
-    .pipe(rheo())
-    .inner('main', showPage('post'))
-    .inner('article h1', rheo(post.data.get('title')))
-    .inner('article main', rheo(post.body))
-    .pipe(setTitle())
-    .render()
-})
-
-const taxonomies = Posts.taxonomise(config.taxonomies, posts)
-for (let [term, items] of taxonomies) {
-  router.get(`taxon-${term}`, `/${term}/:value`, async function (ctx, next) {
-    const value = ctx.params.value
-    ctx.assert(
-      items.has(ctx.params.value),
-      404,
-      `Could not find ${term} ${value}`
-    )
-
-    ctx.set('Content-Type', 'text/html')
-    ctx.body = templates
-      .layout()
-      .pipe(rheo())
-      .inner('main', showPage('taxon'))
-      .inner('h1', rheo(config.site.title))
-      .inner('.posts', function (postsTemplate) {
-        return toArrayStream(items.get(value)).pipe(
-          postsTemplate.map(renderPostListItem)
-        )
-      })
-      .pipe(setTitle())
-      .render()
-  })
-}
-
-app.use(router.routes()).use(router.allowedMethods())
-
-const prefix = /^\/static\//
-app.use(async function (ctx) {
-  if (prefix.test(ctx.path)) {
-    await send(ctx, ctx.path.replace(prefix, ''), {
-      root: './static'
-    })
-  }
-})
+const app = require('./app.js')
 
 module.exports = app
 
-if (require.main === module) {
-  app.listen(PORT, () => {
-    console.log(`App listening on port ${PORT}`)
-  })
-}
+app.listen(PORT, () => {
+  console.log(`App listening on port ${PORT}`)
+})
diff --git a/src/responders.js b/src/responders.js
new file mode 100644
index 0000000..1a9e8ce
--- /dev/null
+++ b/src/responders.js
@@ -0,0 +1,76 @@
+'use strict'
+
+const fs = require('fs')
+const rheo = require('rheo')
+
+const templateReader = template => () =>
+  fs.createReadStream(`${__dirname}/templates/${template}.html`)
+const templates = {
+  layout: templateReader('layout'),
+  home: templateReader('home'),
+  post: templateReader('post'),
+  taxon: templateReader('taxon')
+}
+
+function setTitle (siteTitle, pageTitle) {
+  return rheo.template(function (s) {
+    return s
+      .inner('title', rheo((pageTitle ? ' · ' : '') + siteTitle))
+      .inner('body header h1', rheo(siteTitle))
+  })
+}
+
+function renderPostListItem (ctx) {
+  return function (template, [, post]) {
+    return template
+      .attribute('a', 'href', () => ctx.getURL('post', post.basename))
+      .inner('a', () => rheo(post.data.get('title')))
+  }
+}
+
+function showPage (name) {
+  return function (els) {
+    return rheo(templates[name]())
+  }
+}
+
+module.exports = {
+  home (ctx, config, postsStream) {
+    ctx.set('Content-Type', 'text/html')
+    ctx.body = templates
+      .layout()
+      .pipe(rheo())
+      .outer('main', showPage('home'))
+      .inner('.posts', function (postsTemplate) {
+        return postsStream.pipe(postsTemplate.map(renderPostListItem(ctx)))
+      })
+      .pipe(setTitle(config.site.title))
+      .render()
+  },
+
+  post (ctx, config, post) {
+    ctx.set('Content-Type', 'text/html')
+    ctx.body = templates
+      .layout()
+      .pipe(rheo())
+      .inner('main', showPage('post'))
+      .inner('article h1', rheo(post.data.get('title')))
+      .inner('article main', rheo(post.body))
+      .pipe(setTitle(config.site.title, post.data.get('title')))
+      .render()
+  },
+
+  taxon (ctx, config, taxonItems) {
+    ctx.set('Content-Type', 'text/html')
+    ctx.body = templates
+      .layout()
+      .pipe(rheo())
+      .inner('main', showPage('taxon'))
+      .inner('h1', rheo(config.site.title))
+      .inner('.posts', function (postsTemplate) {
+        return taxonItems.pipe(postsTemplate.map(renderPostListItem(ctx)))
+      })
+      .pipe(setTitle(config.site.title))
+      .render()
+  }
+}
diff --git a/test/index.test.js b/test/app.test.js
index 769097f..04596fa 100644
--- a/test/index.test.js
+++ b/test/app.test.js
@@ -5,7 +5,7 @@ const request = require('supertest')
 const config = require('../src/modules/config.js')
 config.posts.folder = path.resolve(__dirname, './data/')
 
-const app = require('../src/index.js')
+const app = require('../src/app.js')
 
 test('homepage', t => {
   return request(app.listen())