viperfish
Node/Github Database-less Markdown Blogging System
Alpha v0.4.0
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!
Getting Started
Install viperfish with npm,
npm install viperfish
Create a start script to spark up viperfish,
touch index.js
Stick this in your start script,
start;
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,
node index
Then have a look at it with (default port is 3001
),
curl -X GET http://localhost:3001
or point your browser to
localhost:3001
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.
Customisation
How Viperfish Works
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:
Github Authorisation
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)
Custom Configuration File
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),
var hljs = ;moduleexports = // Module Options moduleOpts: nav : port : 3001 customPath : '/public/' favicon : 'favicon.png' logo : 'logo.png' // Template Options tmplOpts: engine : 'hogan' path : './default/' // GithubApi Config Options githubapi : apiOpts : version : '3.0.0' timeout : 5000 contentOpts : user : 'mattstyles' repo : 'vpf-def' path : null // Marked Config Options markedOpts : gfm : true tables : true breaks : false pedantic : false sanitize : false smartLists : true langPrefix : 'language-' { // Javascript highlighting if lang === 'javascript' return hljsvalue; return code; } ;
You can see an example of a config file in the github repo.
highlight.js
The first line to require highlight.js is only required if you alter the markdown parser options later in the config file.
Module Options
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 /customPath/
.
logo
- The logo that is associated with the website, some themes will require it, others not.
Template Options
Viperfish uses the Express web application framework and supports templates to create it's themes.
engine
- The templating engine to use, currently only hogan.js
is supported. Behind the scenes viperfish uses consolidate.js
to push templates to the express view engine.
path
- This is the path location of the templates, found within moduleOpts.customPath/templates/
.
GithubApi Options
To grab content from github repositories to use as content Viperfish uses node-github as a wrapper around the Github API v3.
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 path
as null
(it'll be over-written anyway but, to be sure, leave it in the config for now).
Marked Options
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.
Custom Templates
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 lib/routes
.
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.
error.hjs
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.
main.hjs
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 footer
.
header.hjs
Sets up the opening HTML5 <html>
tag, sorts out the <head>
section, calls the nav
template after opening the <body>
.
nav.hjs
Creates the main navigation menu.
listpost.hjs
This template loops through items contained within the content meta file (see the creating content section) and displays them.
footer.hjs
Displays the footer.
post.hjs
The post template functions similarly to the main template in that it calls in partials for the header
and footer
but
in between it displays the main content of the post/page that has been grabbed from Github and parsed using Marked.
Custom Static Files
The other half of customising Viperfish - those lovingly crafted CSS files that define the look and feel of your project should be included in here. Any images that your theme uses can also be included here, as should any javascript that you want to use in your theme.
Custom Favicon
Viperfish isn't limited to it's own favicon, place yours in the custom directory you set the filename in config.moduleOpts
and Viperfish will use that.
Creating Content
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!
Content Structure
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,
README.md
This is just for your own reference in the repo - Viperfish will ignore this.
main.json
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.
The nav
items should correspond to the folders, which represent your different categories.
The 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 loc
and category
which
Viperfish uses to control it's URLs and push content to the client. The title
, date
& extract
don't need to map
to the content and you could use what you like here.
Categories & category.json
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 ninja
and flex
.
The 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 loc
and category
that Viperfish uses to route its URLs.
Posts - content.md & page.json
The 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
repo both ninja/post
and ninja/dummy
posts contain images.
Usage Examples
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.
Using Nodejitsu
(Coming soon)
Documentation
(Coming soon)
Release History
v0.4.0
- Minimal custom theme support
- Content delivery via github
- Markdown support via Marked - including Github Flavoured Markdown!
- Usage examples - working example using Nodejitsu
- Custom configuration options
- Install via npm
- Templating via Hogan and Consolidate
- System runs on the Express framework
License
Copyright (c) 2013 Matt Styles
Licensed under the MIT license.