Poet

write your code love poem

What is Poet?

Poet is a blog generator in node.js to generate routing, render markdown/jade/whatever posts, and get a blog up and running fast. Poet may not make you blog-famous, and it may give you one less excuse for not having a blog, but just imagine the insane hipster cred you get for having node power your blog. "Cool blog, is this Wordpress or something?" your square friend asks. "Nah dude, this is in node," you respond, while skateboarding off into the sunset, doing mad flips and stuff. Little do they know you just used Poet's autoroute generation to get your content in, like, seconds, up on that internet.

Getting Started

First thing first, throw Poet into your express app's package.json, or just install it locally with:

npm install poet

Once you have the Poet module in your app, just instantiate an instance with your Express app and options, and call the init method:

var
  express = require('express'),
  app = express(),
  Poet = require('poet');

var poet = Poet(app, {
  posts: './_posts/',
  postsPerPage: 5,
  metaFormat: 'json'
});

poet.init().then(function () {
  // ready to go!
});

/* set up the rest of the express app */

Posts

Posts are constructed in markdown/jade/whatever-you-want, prefixed by front matter via YAML or JSON. All attributes are stored in the posts object. An example of a blog post formatted with JSON Front Matter is below:

{{{
  "title": "Hello World!",
  "tags": ["blog", "fun"],
  "category": "javascript",
  "date": "7-5-2013"
}}}

Here goes the content that belongs to the post...

Post Previews

There are several ways of specifying the text of your post preview. Poet checks several properties and the first valid option is used. The order and ways to accomplish this are below.

Options

Methods

Poet::init([callback])

The init method traverses the directory of posts and stores all the information in memory, sets up the internal structures for retrieval and returns a promise resolving to the instance upon completion. An optional callback may be provided for a node style callback with err and poet arguments passed in, called upon completion. This is used when initializing the application, or if reconstructing the internal storage is needed.

Poet::watch([callback])

Sets up the Poet instance to watch the posts directory for changes (a new post, updated post, etc.) and reinitializes the engine and storage. An optional callback may be provided to signify the completion of the reinitialization.

For an example of using watch, check out the watcher example

Poet::clearCache()

Used internally, this clears the Poet instance's internal cache, allowing it to be rebuilt on it's next use. This should not be used in most cases. Returns the Poet instance.

Poet::addTemplate(data)

Poet comes with two templating engines by default (jade and markdown). To specify your own templating language, the addTemplate method may be used, taking a data object with two keys: ext and fn. ext may be a string or an array of strings, specifiying which extensions should use this templating engine, and fn does the rendering, where it is a function that passes a string parameter of text to be formatted and returns the formatted string. Here's an example of using your own YAML formatter:

var
  express = require('express'),
  app = express(),
  yaml = require('yaml'),
  Poet = require('poet');

var poet = Poet(app);

poet.addTemplate({
  ext: 'yaml',
  fn : function (s) { return yaml.eval(s); }
}).init();

This runs any post with the file extension yaml (ex: my_post.yaml) through the fn specified (by calling the yaml module's eval method.

Poet::addRoute(route, handler)

addRoute allows you to specify the handler for a specific route type. Accepting a route string (ex: '/myposts/:post') and a function handler, the route is parsed based off of parameter name (:post for example in the route /myposts/:post), and the previously stored route for that route type (post) is replaced.

The below example uses all default routes except for the post route, and gives full control over how the request is handled. Obviously extra code is needed to specify this, but we can add arbitrary code here, for example, to do some sort of logging:

var
  express = require('express'),
  app = express(),
  Poet = require('poet');

var poet = Poet(app);

poet.addRoute('/myposts/:post', function (req, res, next) {
  var post = poet.helpers.getPost(req.params.post);
  if (post) {
    // Do some fancy logging here
    res.render('post', { post: post });
  } else {
    res.send(404);
  }
}).init();

For more examples on custom routing, check out the examples in the repository.

Routing

The default configuration uses the default routes with the view names below:

For example, if your site root is http://mysite.com, going to the page http://mysite.com/post/hello-world will call the 'post' view in your view directory and render the appropriate post. The options passed into the instantiation of the Poet instance can have a routes key, with an object containing key/value pairs of strings mapping a route to a view. Based off of the paramter in the route (ex: :post in /post/:post), the previous route will be replaced.

For an example of customizing your route names and views, view the example in the repository. To override the default handlers of, check out the Poet::addRoute(route, handler) method.

Helpers

Built in helper methods are stored on the Poet instance's helper property. Used internally, and in the view locals, they can be used outside of Poet as well.

Locals

In addition to all of the helpers being available to each view, there are additional variables accessible inside specific views.

Post Locals

Page Locals

Tag Locals

Category Locals

Additional Examples

Be sure to check out the examples in the repository

Get Bloggin'!

Time to start writing your sweet, beautiful words. For more development information, check out the repository, or scope out the examples in there to get a better idea. If you have any comments, questions, or suggestions, hit me up @jsantell!

Fork me on GitHub