all repos — archive/homestead @ 69af7f12ec17f0aba65b0e23ef4045ee28f2dac8

My future indieweb platform

feat: add single post endpoint
Alan Pearce alan@alanpearce.eu
Sun, 18 Jun 2017 13:36:29 +0200
commit

69af7f12ec17f0aba65b0e23ef4045ee28f2dac8

parent

370e7add837f194bebc710c10ccd11bacfc74990

M src/index.jssrc/index.js
@@ -15,9 +15,17 @@ const posts = Posts.getFolder(process.env.POST_DIR) 
 app.use(view(`${__dirname}/views`))
 
-router.get('/', async function (ctx, next) {
+const postsArray = Array.from(posts.entries())
+router.get('/', async function (ctx) {
   await ctx.render('index', {
-    posts
+    posts: postsArray
+  })
+})
+
+router.get('/post/:filename', async function (ctx) {
+  ctx.assert(posts.has(ctx.params.filename), 404, 'Post not found')
+  await ctx.render('post', {
+    post: posts.get(ctx.params.filename)
   })
 })
 
M src/modules/posts.jssrc/modules/posts.js
@@ -28,8 +28,18 @@ function get (filename) {   return canonicaliseMetadata(matter.read(filename, grayMatterOptions))
 }
 
+function getTitle (file) {
+  return path.basename(file.path, path.extname(file.path))
+}
+
 function getFolder (folder) {
-  return fs.readdirSync(folder).map(f => path.resolve(folder, f)).map(get)
+  return new Map(
+    fs
+      .readdirSync(folder)
+      .map(f => path.resolve(folder, f))
+      .map(get)
+      .map(f => [getTitle(f), f])
+  )
 }
 
 module.exports = {
M src/views/index.htmlsrc/views/index.html
@@ -1,5 +1,5 @@ hello world
 
-{% for post in posts %}
+{% for filename, post in posts %}
   {{ post.data.get('title') }}
 {% endfor %}
A src/views/post.html
@@ -0,0 +1,3 @@+{{ post.data.title }}
+
+{{ post.content }}
M test/data/testfile.mdtest/data/testfile.md
@@ -3,3 +3,4 @@ Title = "This is a test" Description = "Test file"
 Tags = ["a", "b"]
 +++
+# Lorem ipsum
M test/index.test.jstest/index.test.js
@@ -5,7 +5,7 @@ process.env.POST_DIR = path.resolve(__dirname, '../test/data/')
 const app = require('../src/index.js')
 
-test(t => {
+test('homepage', t => {
   return request(app.listen())
     .get('/')
     .expect(200)
@@ -13,3 +13,11 @@ .expect(/hello world/)     .expect(/This is a test/)
     .then(() => t.pass())
 })
+
+test('post', t => {
+  return request(app.listen())
+    .get('/post/testfile')
+    .expect(200)
+    .expect(/Lorem ipsum/)
+    .then(() => t.pass())
+})
M test/modules/posts.test.jstest/modules/posts.test.js
@@ -24,8 +24,10 @@ tags: ['a', 'b']     })
   )
   const actual = posts.getFolder(path.resolve(__dirname, '../data/'))
-  t.true(Array.isArray(actual), 'must return an array')
-  t.true(actual.length > 0, 'must return a non-empty array')
-  t.is(actual[0].path, path.resolve(__dirname, '../data/testfile.md'))
-  t.deepEqual(actual[0].data, expected)
+  t.true(actual.size > 0, 'must return a non-empty map')
+  t.is(
+    actual.get('testfile').path,
+    path.resolve(__dirname, '../data/testfile.md')
+  )
+  t.deepEqual(actual.get('testfile').data, expected)
 })