about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--package.json3
-rw-r--r--posts/testfile.md6
-rw-r--r--src/index.js82
-rw-r--r--src/templates/index.html36
-rw-r--r--src/views/index.njk17
-rw-r--r--src/views/layouts/main.njk13
-rw-r--r--src/views/post.njk8
-rw-r--r--src/views/term.njk7
-rw-r--r--test/index.test.js2
-rw-r--r--yarn.lock133
10 files changed, 193 insertions, 114 deletions
diff --git a/package.json b/package.json
index c844414..4c3d91b 100644
--- a/package.json
+++ b/package.json
@@ -32,10 +32,11 @@
     "configly": "^4.1.0",
     "gray-matter": "^2.1.1",
     "koa": "^2.2.0",
-    "koa-nunjucks-next": "^1.1.3",
     "koa-router": "^7.2.1",
     "koa-send": "^4.1.0",
     "markdown-it": "^8.3.1",
+    "rheo": "^2.2.0",
+    "stream-array": "^1.1.2",
     "toml": "^2.3.2"
   }
 }
diff --git a/posts/testfile.md b/posts/testfile.md
new file mode 100644
index 0000000..bafc456
--- /dev/null
+++ b/posts/testfile.md
@@ -0,0 +1,6 @@
++++
+Title = "This is a test"
+Description = "Test file"
+Tags = ["a", "b"]
++++
+# Lorem ipsum
diff --git a/src/index.js b/src/index.js
index fe0351d..93d61a4 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,6 +3,9 @@
 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')
@@ -12,51 +15,80 @@ const PORT = process.env.PORT || config.server.port
 const Router = require('koa-router')
 const router = new Router()
 
-const view = require('koa-nunjucks-next')
+const rheo = require('rheo')
 
 const Posts = require('./modules/posts.js')
 const posts = Posts.getFolder(config.posts.folder)
 
-app.use(
-  view(`${__dirname}/views`, {
-    extname: 'njk',
-    globals: {
-      site: config.site,
-      url: (...args) => router.url(...args)
-    }
-  })
-)
+const index = () => fs.createReadStream(`${__dirname}/templates/index.html`)
 
-const postsArray = Array.from(posts.entries())
-router.get('home', '/', async function (ctx) {
-  await ctx.render('index', {
-    posts: postsArray
-  })
+function setTitle (pageTitle) {
+  return rheo.template(s =>
+    s.inner('title', rheo((pageTitle ? ' · ' : '') + 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()))
+}
+
+const postsStream = toArrayStream(posts)
+router.get('home', '/', async function (ctx, next) {
+  ctx.set('Content-Type', 'text/html')
+  ctx.body = index()
+    .pipe(rheo())
+    .inner('body', pages => pages.find('main.homepage'))
+    .inner('h1', rheo(config.site.title))
+    .inner('.posts', function (postsTemplate) {
+      return postsStream.pipe(postsTemplate.map(renderPostListItem))
+    })
+    .pipe(setTitle())
+    .render()
 })
 
-router.get('post', '/post/:filename', async function (ctx) {
+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)
-  await ctx.render('post', {
-    post: post
-  })
+
+  ctx.set('Content-Type', 'text/html')
+  ctx.body = index()
+    .pipe(rheo())
+    .inner('body', pages => pages.find('main.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) {
+  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}`
     )
-    await ctx.render('term', {
-      term: term,
-      [term]: value,
-      posts: items.get(ctx.params.value)
-    })
+
+    ctx.set('Content-Type', 'text/html')
+    ctx.body = index()
+      .pipe(rheo())
+      .inner('body', pages => pages.find('main.taxon'))
+      .inner('h1', rheo(config.site.title))
+      .inner('.posts', function (postsTemplate) {
+        return toArrayStream(items.get(value)).pipe(
+          postsTemplate.map(renderPostListItem)
+        )
+      })
+      .pipe(setTitle())
+      .render()
   })
 }
 
diff --git a/src/templates/index.html b/src/templates/index.html
new file mode 100644
index 0000000..412b4ec
--- /dev/null
+++ b/src/templates/index.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8"/>
+    <title></title>
+  </head>
+  <body>
+    <main class="homepage">
+      <h1>hello world</h1>
+
+      <ul class="posts">
+        <li class="post">
+          <a href="/">Test post please ignore</a>
+        </li>
+      </ul>
+    </main>
+    <main class="post">
+      <article>
+        <h1>post title</h1>
+        <main>
+          Fringilla ut morbi tincidunt augue interdum velit euismod!
+          Interdum velit laoreet id donec ultrices tincidunt arcu, non
+          sodales neque sodales ut etiam sit amet nisl purus, in
+          mollis nunc sed. 
+        </main>
+      </article>
+    </main>
+    <main class="taxon">
+      <ul class="posts">
+        <li class="post">
+          <a href="/">Test post please ignore</a>
+        </li>
+      </ul>
+    </main>
+  </body>
+</html>
diff --git a/src/views/index.njk b/src/views/index.njk
deleted file mode 100644
index 9a7cc80..0000000
--- a/src/views/index.njk
+++ /dev/null
@@ -1,17 +0,0 @@
-{% extends "layouts/main.njk" %}
-
-{% block body %}
-
-  <h1>hello world</h1>
-
-  <ul>
-    {% for filename, post in posts %}
-      <li>
-        <a href="{{ router.url('post', post.basename)}}">
-          {{ post.data.get('title') }}
-        </a>
-      </li>
-    {% endfor %}
-  </ul>
-
-{% endblock %}
diff --git a/src/views/layouts/main.njk b/src/views/layouts/main.njk
deleted file mode 100644
index 1fe1a93..0000000
--- a/src/views/layouts/main.njk
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8"/>
-    <title>{% block title %}{{ site.title }}{% endblock %}</title>
-  </head>
-  <body>
-    <main>
-      {% block body %}
-      {% endblock %}
-    </main>
-  </body>
-</html>
diff --git a/src/views/post.njk b/src/views/post.njk
deleted file mode 100644
index d6a4f92..0000000
--- a/src/views/post.njk
+++ /dev/null
@@ -1,8 +0,0 @@
-{% extends "layouts/main.njk" %}
-
-{% block body %}
-
-{{ post.data.title }}
-
-{{ post.body | safe }}
-{% endblock %}
diff --git a/src/views/term.njk b/src/views/term.njk
deleted file mode 100644
index 6ac932e..0000000
--- a/src/views/term.njk
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends "layouts/main.njk" %}
-
-{% block body %}
-{% for post in posts %}
-  {{ post.data.get('title') }}
-{% endfor %}
-{% endblock %}
diff --git a/test/index.test.js b/test/index.test.js
index 73bbd19..769097f 100644
--- a/test/index.test.js
+++ b/test/index.test.js
@@ -12,7 +12,7 @@ test('homepage', t => {
     .get('/')
     .expect(200)
     .expect(/<title>Test Site<\/title>/)
-    .expect(/hello world/)
+    .expect(/<h1>Test Site<\/h1>/)
     .expect(/This is a test/)
     .then(() => t.pass())
 })
diff --git a/yarn.lock b/yarn.lock
index 0179800..5536609 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -190,10 +190,6 @@ arrify@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
 
-asap@^2.0.3:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f"
-
 asn1@~0.2.3:
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
@@ -708,6 +704,10 @@ buf-compare@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a"
 
+buffer-shims@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
+
 builtin-modules@^1.0.0, builtin-modules@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
@@ -750,7 +750,7 @@ camelcase-keys@^2.0.0:
     camelcase "^2.0.0"
     map-obj "^1.0.0"
 
-camelcase@^2.0.0, camelcase@^2.0.1:
+camelcase@^2.0.0:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
 
@@ -792,7 +792,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
-chokidar@1.6.1, chokidar@^1.4.2, chokidar@^1.6.0:
+chokidar@1.6.1, chokidar@^1.4.2:
   version "1.6.1"
   resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
   dependencies:
@@ -869,7 +869,7 @@ cli-width@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
 
-cliui@^3.0.3, cliui@^3.2.0:
+cliui@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
   dependencies:
@@ -1083,6 +1083,12 @@ crypto-random-string@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
 
+cssauron@^1.2.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/cssauron/-/cssauron-1.4.0.tgz#a6602dff7e04a8306dc0db9a551e92e8b5662ad8"
+  dependencies:
+    through X.X.X
+
 currently-unhandled@^0.4.1:
   version "0.4.1"
   resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
@@ -1247,12 +1253,44 @@ doctrine@^2.0.0:
     esutils "^2.0.2"
     isarray "^1.0.0"
 
+dom-serializer@0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
+  dependencies:
+    domelementtype "~1.1.1"
+    entities "~1.1.1"
+
+domelementtype@1, domelementtype@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
+
+domelementtype@~1.1.1:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+
+domhandler@^2.3.0:
+  version "2.4.1"
+  resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"
+  dependencies:
+    domelementtype "1"
+
+domutils@^1.5.1:
+  version "1.6.2"
+  resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.6.2.tgz#1958cc0b4c9426e9ed367fb1c8e854891b0fa3ff"
+  dependencies:
+    dom-serializer "0"
+    domelementtype "1"
+
 dot-prop@^4.1.0:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.1.1.tgz#a8493f0b7b5eeec82525b5c7587fa7de7ca859c1"
   dependencies:
     is-obj "^1.0.0"
 
+double-ended-queue@^0.9.7:
+  version "0.9.7"
+  resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-0.9.7.tgz#8ae0a7265df66cdc3f07dce558e9716adb586ab8"
+
 duplexer2@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
@@ -1284,7 +1322,7 @@ empower-core@^0.6.1:
     call-signature "0.0.2"
     core-js "^2.0.0"
 
-entities@~1.1.1:
+entities@^1.1.1, entities@~1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
 
@@ -2042,6 +2080,17 @@ hosted-git-info@^2.1.4:
   version "2.4.2"
   resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67"
 
+htmlparser2@^3.8.3:
+  version "3.9.2"
+  resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
+  dependencies:
+    domelementtype "^1.3.0"
+    domhandler "^2.3.0"
+    domutils "^1.5.1"
+    entities "^1.1.1"
+    inherits "^2.0.1"
+    readable-stream "^2.0.2"
+
 http-assert@^1.1.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.3.0.tgz#a31a5cf88c873ecbb5796907d4d6f132e8c01e4a"
@@ -2558,13 +2607,6 @@ koa-is-json@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14"
 
-koa-nunjucks-next@^1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/koa-nunjucks-next/-/koa-nunjucks-next-1.1.3.tgz#20ec177bb5790153beaefae77e4151db586c66df"
-  dependencies:
-    debug "^2.2.0"
-    nunjucks "^2.4.2"
-
 koa-router@^7.2.1:
   version "7.2.1"
   resolved "https://registry.yarnpkg.com/koa-router/-/koa-router-7.2.1.tgz#b40a4ab3c6adb4b40895debd00a9c640304e3039"
@@ -3116,14 +3158,6 @@ number-is-nan@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
 
-nunjucks@^2.4.2:
-  version "2.5.2"
-  resolved "https://registry.yarnpkg.com/nunjucks/-/nunjucks-2.5.2.tgz#ea7d346e785b8a4874666c3cca9e18c577fba22c"
-  dependencies:
-    asap "^2.0.3"
-    chokidar "^1.6.0"
-    yargs "^3.32.0"
-
 oauth-sign@~0.8.1:
   version "0.8.2"
   resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
@@ -3608,7 +3642,7 @@ read-pkg@^2.0.0:
     normalize-package-data "^2.3.2"
     path-type "^2.0.0"
 
-readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2:
+readable-stream@^2.0.0, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2:
   version "2.2.11"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.11.tgz#0796b31f8d7688007ff0b93a8088d34aa17c0f72"
   dependencies:
@@ -3620,6 +3654,18 @@ readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable
     string_decoder "~1.0.0"
     util-deprecate "~1.0.1"
 
+readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@~2.1.0:
+  version "2.1.5"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0"
+  dependencies:
+    buffer-shims "^1.0.0"
+    core-util-is "~1.0.0"
+    inherits "~2.0.1"
+    isarray "~1.0.0"
+    process-nextick-args "~1.0.6"
+    string_decoder "~0.10.x"
+    util-deprecate "~1.0.1"
+
 readable-stream@~2.0.5:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
@@ -3860,6 +3906,15 @@ restore-cursor@^2.0.0:
     onetime "^2.0.0"
     signal-exit "^3.0.2"
 
+rheo@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/rheo/-/rheo-2.2.0.tgz#614187095b12847f49f284e2f804ad59623ca243"
+  dependencies:
+    cssauron "^1.2.0"
+    double-ended-queue "^0.9.7"
+    htmlparser2 "^3.8.3"
+    void-elements "^2.0.1"
+
 rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1:
   version "2.6.1"
   resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
@@ -4043,6 +4098,12 @@ standard@^10.0.2:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
 
+stream-array@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/stream-array/-/stream-array-1.1.2.tgz#9e5f7345f2137c30ee3b498b9114e80b52bb7eb5"
+  dependencies:
+    readable-stream "~2.1.0"
+
 stream-to-observable@^0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe"
@@ -4225,7 +4286,7 @@ through2@^2.0.0:
     readable-stream "^2.1.5"
     xtend "~4.0.1"
 
-through@^2.3.6:
+through@X.X.X, through@^2.3.6:
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
 
@@ -4391,6 +4452,10 @@ verror@1.3.6:
   dependencies:
     extsprintf "1.0.2"
 
+void-elements@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
+
 which-module@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
@@ -4413,10 +4478,6 @@ widest-line@^1.0.0:
   dependencies:
     string-width "^1.0.1"
 
-window-size@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876"
-
 window-size@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
@@ -4484,7 +4545,7 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
 
-y18n@^3.2.0, y18n@^3.2.1:
+y18n@^3.2.1:
   version "3.2.1"
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
 
@@ -4516,15 +4577,3 @@ yargs@6.3.0:
     window-size "^0.2.0"
     y18n "^3.2.1"
     yargs-parser "^4.0.2"
-
-yargs@^3.32.0:
-  version "3.32.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"
-  dependencies:
-    camelcase "^2.0.1"
-    cliui "^3.0.3"
-    decamelize "^1.1.1"
-    os-locale "^1.4.0"
-    string-width "^1.0.1"
-    window-size "^0.1.4"
-    y18n "^3.2.0"