Escape your CMS and be free: JS pre-rendering, GitHub and Heroku.
# Install
npm install
# For local development with static pages rebuilding on changes
npm run dev
# For deployments
npm run build && npm start
# To clean up all built files
npm run clean- EJS for layouts
- Marked for Markdown to HTML conversion for pages
- ExpressJS for a very simple server
- JS-YAML to parse YAML into JS
Create a folder /pages and put .md markdown files in it, each one can have YAML front-matter at the top, like this:
---
layout: blog
title: This is the page title
some-variable: Have whatever variables you want
---... then below your YAML front-matter, put the markdown for the page, like this:
## This will become an H2 element
This will be **be bold** and _italic_.
We can have [a link](/path/to).You can use any depth of sub-folders, and if you have a folder called blah rather than making blah.md put a file called _index.md in the folder blah instead.
Create a folder /layouts and put .ejs files in it. Pages will always use _master.ejs and [layout].ejs, where layout is from the layout: blah YAML front-matter variable in the page .md file. Common components can be included like this: <%- include('partial/header') %>.
The layout can access variables set in the page's YAML, such as page.title.
Files in /data should contain YAML and will be added to site.data[file-name]. So:
# config.yml
default-title: Default page title
some-variable: Yes please... will result in site.data.config being { 'default-title': 'Default page title', 'some-variable': 'Yes please' }. You can access these variables within .ejs layouts or .md page files.
These are accessible within your layout .ejs files. Create a file /server-js/helpers.js with something like this:
module.exports = {
readTime: (page) => Math.ceil(page.rawLength / 1300)
}... now access within your layout .ejs file like this: Read time: <%- helpers.readTime(page) %> minutes.
These are for use in your page .md files. Create a file /server-js/tags.js with something like this:
const { tagRegister } = require('../no-cms/tags.js')
tagRegister('youtube', (args) => {
const youtubeId = args[0] || ''
return `
<iframe class="youtube-video" width="560" height="315" src="https://www.youtube.com/embed/${youtubeId}?rel=0" frameborder="0" allowfullscreen=""></iframe>
`
})
tagRegister('prominent', (args, content) => {
return `
<div class="prominent">
${content}
</div>
`
}, { ends: true })... you can then use these like this:
To insert a Youtube video:
{% youtube josdf793934 %}
To add some content within a `div.prominent`:
{% prominent %}
Markdown **allowed here**.
{% endprominent %}... this saves you from having to have HTML in your .md page files (but you still can if you want).
-
Can't imagine it being too hard to change from eg using EJS to using server-side Vue/React (even isomorphic rendering) or other alternatives instead.
-
Just hack away at the files - there's less than 500 lines of JS in total.
-
Make
npm run devcleverer in terms of when to rebuild watched files.