Minimalist Node/Github Database-less Blogging System
Node/Github Database-less Markdown Blogging System
Use with discretion! The API is relatively stable but it is in flux so you'll need to keep on your toes if you want to use viperfish in production.
Viperfish is a simple blogging system that grabs content from a github repo.
It is currently in early alpha and, as such, its not particularly robust but if you follow the rules it'll work just fine, as demonstrated by the examples.
Follow the getting started instructions to see it in action (I warn you though, the vanilla version won't be pretty, see the customisation section).
To get started see the getting started section of course!
Install viperfish with npm,
npm install viperfish
Create a start script to spark up viperfish,
Stick this in your start script,
That's all you need to get started with viperfish!! Simple no?
To see it in action (remember what I said early about prettiness?), use node to fire up the server,
Then have a look at it with (default port is
curl -X GET
or point your browser to
Whilst this is all very functional the default content and theme is pretty boring, you'll be wanting to improve upon that with some customisations.
Viperfish works by grabbing content from a github repo, passing it through a theme to style it and displaying it in the browser. In order to make viperfish work for you you'll need to create some content and you'll need to create a theme to display that content.
When viperfish is started there are a number of steps that it will perform to transparently initialise itself:
If you followed through the Getting Started section then you probably noticed that viperfish threw this log at you,
No github credentials in environment vars --- Unauthorised access to github --- max rate limit of 60 reqs per hour
Basic github authorisation is not required for public repositories and the default repo that viperfish pulls dummy content from is public so it'll connect to github and get the content for you with no problems. However, basic authorisation is limited to 60 requests per hour.
In order to lift the 60 requests per hour limit you can register 2 environment variables that viperfish will use to authenticate properly with github.
GHusername - the owner of the content repo
GHpassword - the password of the repo owner
(For an example of setting environment variables have a look at how to setup a nodejitsu app)
The config file is an object that holds a number of different configuration options that Viperfish uses.
For the sake of completeness this is an example config file that sets all of the config options (these are actually the default options, any of these options can be omitted from your config file and viperfish will use the defaults),
You can see an example of a config file in the github repo.
The first line to require highlight.js is only required if you alter the markdown parser options later in the config file.
This object holds the options for setting up the viperfish module.
nav - Array of navigation menu options if, for some reason, you want your navigation menu to differ from the options
found in your content repository's main.json (see creating content).
port - The port to use when sparking up viperfish locally.
customPath - This is the directory that holds the theme files (such as css, js & templates).
favicon - The filename of the favicon to use, contained in the
logo - The logo that is associated with the website, some themes will require it, others not.
Viperfish uses the Express web application framework and supports templates to create it's themes.
path - This is the path location of the templates, found within
apiOpts - This contains the version of the api to wrap and a timer in milliseconds before the call to the api fails.
contentOpts - This is the primary means of pointing Viperfish to your content, enter the username and repository name and,
very importantly, leave
null (it'll be over-written anyway but, to be sure, leave it in the config for now).
Viperfish uses Marked to parse the raw markdown data because Marked is just so awesome!
There are various options and if you want to fiddle with them its best to read the info from the Marked github repo.
This is where customising Viperfish gets really interesting. Viperfish currently only supports hogan.js templates but hogan is a versatile and powerful templating engine, if you haven't used hogan yet then read the hogan docs for more info on how to use partials and the other features of the templating engine. Templating is powerful, get using it and get creative!
At the moment Viperfish isn't particularly sophisticated in it's template structure so when you create your own custom template folder you'll need to create (or copy) each template into the folder (unlike the config options, viperfish won't yet fall back to use default templates when it can't find one although this functionality is planned for the near future).
Viperfish requires 7 basic templates but the content of those templates is not static so you can define how each template
works how you like - be aware though that Vipefish will be making calls to the templates but it is mostly just including
them so you could use them in different ways. To see how they are included in Viperfish have a poke around in
I'll outline the basic functionality of each template in the default scheme, also check out the examples
to see how other themes use the template system.
The error template to display when an error occurs (usually this is an error collecting content from github but it will potentially be other things). It's due to be changed for a 404 template pretty soon.
This is the main template that is called when displaying the opening page or a category page. It is used to call in the
other partials - first the
header, then the main body of the category listing from
listpost and finally the
Sets up the opening HTML5
<html> tag, sorts out the
<head> section, calls the
nav template after opening the
Creates the main navigation menu.
This template loops through items contained within the content meta file (see the creating content section) and displays them.
Displays the footer.
The post template functions similarly to the main template in that it calls in partials for the
in between it displays the main content of the post/page that has been grabbed from Github and parsed using Marked.
Viperfish isn't limited to it's own favicon, place yours in the custom directory you set the filename in
and Viperfish will use that.
Whilst the delivery mechanism (i.e. Viperfish) and a well designed theme are all important to a successful blog, a blog is really all about the content that it uses. One of the main principles behind Viperfish is that it should be as simple to use as possible and allow writers to write. To that end the bulk of content that Viperfish uses should be written in Markdown with a few pieces of JSON holding it all together. At present this is not an automated process so you'll have to go through and carefully create the JSON meta along with your posts but they are pretty small at the moment and don't do a lot—an automated tool is in production that will take this step away and make it more user friendly.
Another key aspect of Viperfish is that it does not use a database. This simplifies the delivery mechanism which is already pretty lightning fast thanks to the power of Node's event loop. Viperfish makes delivery of your blog fast and that's good!
Viperfish currently only supports content coming directly from a github repository (other storage methods are planned) and an example of the directory structure can be found in the repository that Viperfish uses as it's default— also see the examples section. If you followed through the Getting Started instructions then it should be fairly easy to work out how the information in the content repository maps into Viperfish.
At the moment Viperfish won't validate your content so any errors will just cause it to blow up, however, if you follow the rules it's pretty simple to get it working for you.
The content structure for the dummy content repository looks like this,
This is just for your own reference in the repo - Viperfish will ignore this.
Main.json simply holds two objects.
nav contains a list of navigation menu items and
recent holds a list of the
posts you want to display on the front page.
nav items should correspond to the folders, which represent your different categories.
recent list is a list of post objects that hold various meta about each post that you want to display. Currently
there is no automated process for creating this file so you have to do it yourself but, for now, embrace the flexibility!!
It's fairly obvious to see how the meta maps on to the content - the important bit is the
Viperfish uses to control it's URLs and push content to the client. The
extract don't need to map
to the content and you could use what you like here.
Each sub-folder represents a category of posts. Currently Viperfish only supports one level of nesting. In the dummy
repo structure shown above those categories are
category.json file holds the meta for the category and is extremely similar to
main.json and functionally
fulfills the same purpose.
It is simply a list of
recent posts that you want to display. Note that there is no restriction that you put all of
the posts from a category into this file, you could, if you wanted, hide some posts from the category listing.
Again, the important point to note here is the
category that Viperfish uses to route its URLs.
page.json simply holds a tiny amount of meta and (as of v0.4.0) is just a placeholder—it is not currently
referenced by Viperfish.
The real meat is in the content markdown file.
Viperfish uses Marked to parse it's Markdown for presentation so any of the options there are valid for Viperfish and can be set in the config. This means you have access to Github Flavoured Markdown.
Any links, such as images, can be placed into a subfolder and referenced in the normal markdown style. In the dummy
ninja/dummy posts contain images.
To see Viperfish in action visit the veryfizzyjelly site. It's all public so if you want to root around in the custom theme then clone the repo on github, the content structure can also be found on github.
Copyright (c) 2013 Matt Styles
Licensed under the MIT license.