wit-cms v5.0.3
wit-cms
wit-cms is a flat-file, "blog aware", publishing platform for Express.
It's designed for those who want WordPress-like functionality without the heft
and attack-surface of a WordPress installation. It emphasizes simplicity,
security, and performance.
Overview
Page and post content is declared by creating markdown files within the
appropriate directories. wit-cms will generate everything else automatically,
including:
- express routes (both sync and async)
- a "home" page
- "pages" and "posts" (with "read more" links and pagination)
- "tag" and "category" taxonomies
- blog search and archive
- a
sitemap.xml - an RSS feed
- syntax-highlighting on all content via highlight.js.
On application start, wit-cms loads all site content into an in-memory
object, making it possible to serve content without reading a disk. This makes
it faster than traditional database-backed content-management systems.
wit-cms seeks to offer a compromise between the full-featuredness of
WordPress and the ultra-minimalism of Jekyll, and strives to be a viable
alternative to those who may be dissatisfied with either.
Quick Start
To install only the wit-cms module, run:
npm install wit-cms
To spare yourself the tedium of having to write boilerplate templating,
however, it may be preferable to clone the wit-cms-bootstrap repository and
modify from there. This is the recommended approach for using wit-cms:
https://github.com/chrisallenlane/wit-cms-bootstrap
Creating Content
In order to create a "post" (a blog entry) or a "page" (content that exists
outside of the blog context), simply create a markdown file of the appropriate
name, and in the appropriate location. By default, markdown files that source
page content live in <webroot>/pages/, and markdown files that source blog
posts live in <webroot>/posts/.
Page and post urls will be generated based off of the filename of the
corresponding markdown file. For example, the source markdown for a "Hello
World" blog post should be saved to <webroot>/posts/hello-world.md, and its
URL would be /blog/post/hello-world.
Front-matter
As with Jekyll, wit reads page and post metadata (title, date, author,
categories, tags, etc.) out of front-matter embedded within each post or page
via the json-front-matter module.
For example, all posts should contain a header like the following:
{{{
"title" : "Hello World (of node blogging)",
"description" : "The post description."
"author" : "John Doe",
"categories" : [ "node", "blogging" ],
"tags" : [ "javascript", "express" ],
"date" : "2012-09-15"
}}}Pages will have a similar, but sparser, header:
{{{
"title" : "About Me",
"description" : "The page description."
"url" : /about-me,
"searchable" : true
}}}The url property provides a mechanism to specify the URL at which the page
should be published. This parameter is optional, and defaults to the name of
the corresponding markdown file. (Example: about-me.md will publish by
default to /about-me.)
The searchable property provides a mechanism for excluding pages from
appearing in search results. The searchable parameter is optional, and
defaults to true.
Beyond the above, any additional properties specified in front-matter will be made available to the corresponding rendered views as page locals.
Routes
wit-cms automatically generates the following routes:
Synchronous
//:page/page/search/blog//blog/post/:name/blog/category/:category/blog/tag/:tag/blog/archive/:year/:month?/:day?/blog/search/search/feed/feed.xml/sitemap.xml
Asynchronous
/async/pages/async/pages/search/async/pages/:page/async/blog//async/blog/post/:name/async/blog/category/:category/async/blog/tag/:tag/async/blog/archive/:year/:month?/:day?/async/blog/search/async/tags/async/categories/async/params
The asyncronous routes return JSON responses.
Objects
wit-cms buffers all site content in a wit object. Here is an example of its
structure:
wit {
pages: {
"about" : aPageObject,
"contact" : aPageObject,
"portfolio" : aPageObject,
},
posts: {
"website-redesign" : aPostObject,
"blogging-in-node" : aPostObject,
"wit-vs-wordpress" : aPostObject,
},
tags: [
'the-first-tag',
'the-second-tag',
'the-third-tag',
'etc',
],
categories: [
'the-first-category',
'the-second-category',
'the-third-category',
'etc',
],
index: {
page: aLunrIndex,
post: aLunrIndex,
},
params: {
// arbitrary params specified on initialization
},
}Whereby a post object takes the following shape:
{
title : 'The Post Name',
name : 'the-post-name',
url : '/blog/post/the-post-name',
author : 'John Doe',
categories : [ 'foo', 'bar' ],
tags : [ 'alpha', 'bravo', 'charlie' ],
date: {
datetime : '2012-09-12T00:00:00-04:00',
day : '02',
month : '04',
pretty : '2 April 2014', // configurable
unix : '1396411200',
year : '2014',
excerpt: '<p>Content before the break.</p>',
content: '<p>The page content.</p>',
}And a page object takes the following shape:
{
title : 'The Page Name',
name : 'the-page-name',
url : '/the-page-name',
author : 'John Doe',
description : 'A descripton for the page.',
content : '<p>The full page content.</p>'
}Initializing
The wit-cms module will export a single function that will decorate an
initialized Express app. Upon invokation, the function will also return a wit
object that contains the entirety of the wit data.
const express = require('express');
const path = require('path');
const Wit = require('wit-cms');
var app = express();
// express configs
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// wit configs
var config = {
// template params
params: {
author : 'John Doe',
fqdn : 'https://example.com',
name : 'Example Website',
tagLine : 'An example site made using wit-cms',
},
// 302 redirect '/' to this page
pages: {
home: '/about-me'
},
};
// initialize the wit instance
const wit = Wit(app, config);Note that arbitrary properties may be attached to config.params. These
properties will be made available to page templates via the returned wit
object as wit.params.
Searching
wit-cms provides for searching among pages and blog posts via the
lunr module.
Commenting
Because wit-cms stores its content in flat files instead of a database, it
does not and can not natively support a reader commeting system. If you'd like
to enable commenting on your blog, consider using Disqus or isso.
Security
wit-cms neither implements administrative access controls, nor requires a
database back-end. As such, it is immune to many classes of attacks to which
other content-management systems may be vulnerable.
It is not "hack proof", however. Its attack-surface consists (at least) of:
- Inputs that write to the DOM (search boxes, URLs, etc.)
- The attack-surface of Express
- The attack-surface of nodejs
As a defense against Cross-Site Scripting attacks, wit-cms
internally relies on the xss module to sanitize user inputs that may
be written back to the DOM. Regardless, it is still prudent to use a
templating engine (ejs, hogan, etc.) when authoring views.
Lastly - though this should go without saying - the node application should
never be run as root.
Upgrading
wit-cms@v5.0.0 is backwards-incompatible with prior versions. See the
wiki for upgrading instructions.
License
wit-cms is released under the MIT license. See LICENSE.txt for details.
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
11 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago