about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAlan Pearce2017-06-18 12:24:24 +0200
committerAlan Pearce2017-06-18 12:24:24 +0200
commitda9ff90d3e1b1348c43cd378c0806e159a700810 (patch)
treeab81bc58d982c6ffe77e160ae9b107acdc72eee6
parent3bda5fcfb7a23619ba66bef029d89bbd18d2c915 (diff)
downloadhomestead-da9ff90d3e1b1348c43cd378c0806e159a700810.tar.lz
homestead-da9ff90d3e1b1348c43cd378c0806e159a700810.tar.zst
homestead-da9ff90d3e1b1348c43cd378c0806e159a700810.zip
feat: Parse front matter as metadata
-rw-r--r--package.json3
-rw-r--r--src/index.js7
-rw-r--r--src/modules/metadata.js46
-rw-r--r--src/views/index.html4
-rw-r--r--test/data/testfile.md5
-rw-r--r--test/index.test.js9
-rw-r--r--test/modules/metadata.test.js33
-rw-r--r--yarn.lock38
8 files changed, 138 insertions, 7 deletions
diff --git a/package.json b/package.json
index e66c8a5..1cc7565 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
   "dependencies": {
     "koa": "^2.2.0",
     "koa-nunjucks-next": "^1.1.3",
-    "koa-router": "^7.2.1"
+    "koa-router": "^7.2.1",
+    "gray-matter": "^2.1.1"
   }
 }
diff --git a/src/index.js b/src/index.js
index 630ac08..c16d952 100644
--- a/src/index.js
+++ b/src/index.js
@@ -10,10 +10,15 @@ const router = new Router()
 
 const view = require('koa-nunjucks-next')
 
+const metadata = require('./modules/metadata.js')
+const postMetadata = metadata.getFolderMetadata(process.env.POST_DIR)
+
 app.use(view(`${__dirname}/views`))
 
 router.get('/', async function (ctx, next) {
-  await ctx.render('index')
+  await ctx.render('index', {
+    posts: postMetadata
+  })
 })
 
 app.use(router.routes()).use(router.allowedMethods())
diff --git a/src/modules/metadata.js b/src/modules/metadata.js
new file mode 100644
index 0000000..9f24d8e
--- /dev/null
+++ b/src/modules/metadata.js
@@ -0,0 +1,46 @@
+'use strict'
+
+const fs = require('fs')
+const path = require('path')
+const matter = require('gray-matter')
+
+const options = {
+  lang: 'toml',
+  delims: '+++'
+}
+
+function* lowercaseKeys (iterator) {
+  for (let [k, v] of iterator) {
+    yield [String(k).toLowerCase(), v]
+  }
+}
+
+function canonicaliseMetadata (meta) {
+  if (meta.data) {
+    meta.data = new Map(lowercaseKeys(Object.entries(meta.data)))
+  } else {
+    meta.data = new Map()
+  }
+  return meta
+}
+
+function readFileMetadata (filename) {
+  return canonicaliseMetadata(matter.read(filename, options))
+}
+
+function getFileMetadata (filename) {
+  const result = readFileMetadata(filename)
+  return result && result.data
+}
+
+function getFolderMetadata (folder) {
+  return fs
+    .readdirSync(folder)
+    .map(f => path.resolve(folder, f))
+    .map(readFileMetadata)
+}
+
+module.exports = {
+  getFileMetadata,
+  getFolderMetadata
+}
diff --git a/src/views/index.html b/src/views/index.html
index 3b18e51..0e900e6 100644
--- a/src/views/index.html
+++ b/src/views/index.html
@@ -1 +1,5 @@
 hello world
+
+{% for post in posts %}
+  {{ post.data.get('title') }}
+{% endfor %}
diff --git a/test/data/testfile.md b/test/data/testfile.md
new file mode 100644
index 0000000..6899d52
--- /dev/null
+++ b/test/data/testfile.md
@@ -0,0 +1,5 @@
++++
+Title = "This is a test"
+Description = "Test file"
+Tags = ["a", "b"]
++++
diff --git a/test/index.test.js b/test/index.test.js
index 2e55b2c..ebac87d 100644
--- a/test/index.test.js
+++ b/test/index.test.js
@@ -1,12 +1,15 @@
 const test = require('ava')
+const path = require('path')
 const request = require('supertest')
 
+process.env.POST_DIR = path.resolve(__dirname, '../test/data/')
 const app = require('../src/index.js')
 
-test(t =>
-  request(app.listen())
+test(t => {
+  return request(app.listen())
     .get('/')
     .expect(200)
     .expect(/hello world/)
+    .expect(/This is a test/)
     .then(() => t.pass())
-)
+})
diff --git a/test/modules/metadata.test.js b/test/modules/metadata.test.js
new file mode 100644
index 0000000..139de60
--- /dev/null
+++ b/test/modules/metadata.test.js
@@ -0,0 +1,33 @@
+const test = require('ava')
+const path = require('path')
+
+const metadata = require('../../src/modules/metadata.js')
+
+test('getFileMetadata', t => {
+  const expected = new Map(
+    Object.entries({
+      title: 'This is a test',
+      description: 'Test file',
+      tags: ['a', 'b']
+    })
+  )
+  t.deepEqual(
+    metadata.getFileMetadata(path.resolve(__dirname, '../data/testfile.md')),
+    expected
+  )
+})
+
+test('getFolderMetadata', t => {
+  const expected = new Map(
+    Object.entries({
+      title: 'This is a test',
+      description: 'Test file',
+      tags: ['a', 'b']
+    })
+  )
+  const actual = metadata.getFolderMetadata(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)
+})
diff --git a/yarn.lock b/yarn.lock
index 5d00b63..f92a4f8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -83,6 +83,12 @@ ansi-escapes@^1.0.0, ansi-escapes@^1.1.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
 
+ansi-red@^0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c"
+  dependencies:
+    ansi-wrap "0.1.0"
+
 ansi-regex@^2.0.0, ansi-regex@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@@ -101,6 +107,10 @@ ansi-styles@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
 
+ansi-wrap@0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
+
 any-promise@^1.1.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
@@ -887,6 +897,10 @@ code-point-at@^1.0.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
 
+coffee-script@^1.12.4:
+  version "1.12.6"
+  resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.6.tgz#285a3f7115689065064d6bf9ef4572db66695cbf"
+
 color-convert@^1.0.0:
   version "1.9.0"
   resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
@@ -1568,6 +1582,12 @@ expand-range@^1.8.1:
   dependencies:
     fill-range "^2.1.0"
 
+extend-shallow@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
+  dependencies:
+    is-extendable "^0.1.0"
+
 extend@^3.0.0, extend@~3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
@@ -1907,6 +1927,16 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
 
+gray-matter@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-2.1.1.tgz#3042d9adec2a1ded6a7707a9ed2380f8a17a430e"
+  dependencies:
+    ansi-red "^0.1.1"
+    coffee-script "^1.12.4"
+    extend-shallow "^2.0.1"
+    js-yaml "^3.8.1"
+    toml "^2.3.2"
+
 har-schema@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
@@ -2160,7 +2190,7 @@ is-error@^2.2.0:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c"
 
-is-extendable@^0.1.1:
+is-extendable@^0.1.0, is-extendable@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
 
@@ -2400,7 +2430,7 @@ js-tokens@^3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
 
-js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@^3.8.2:
+js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@^3.8.1, js-yaml@^3.8.2:
   version "3.8.4"
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6"
   dependencies:
@@ -4113,6 +4143,10 @@ to-fast-properties@^1.0.1:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
 
+toml@^2.3.2:
+  version "2.3.2"
+  resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.2.tgz#5eded5ca42887924949fd06eb0e955656001e834"
+
 tough-cookie@~2.3.0:
   version "2.3.2"
   resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"