Coding on Orchestrate.io & Orchestrate.js & Orchestrate.NET

First context, then I’ll dive in.

Orchestrate

http://orchestrate.io/

Orchestrate is a service that provides a simple API to access a multitude of database types all in one location. Key value, graph or events, some of the database types I’ve been using, are but a few they’ve already made available. There are many more on the way. Having these databases available via an API instead of needing to go through the arduous process of setting up and maintaining each database for each type of data structure is a massive time saver! On top of having a clean API and solid database platform and infrastructure Orchestrate has a number of client drivers that provide easy to use wrappers. These client drivers are available for a number of languages. Below I’ve written about two of these that I’ve been involved with in some way over the last couple of months.

Orchestrate.NET

https://github.com/RobertSmith/Orchestrate.NET

This library I’m currently using for a demonstration application built against the Deconstructed.io services (follow us on twitter ya! @BeDeconstructed), a startup I’m co-founding. I’m not sure exactly what the app will be, but being .NET it’ll be something enterprisey. Because: .NET is Enterprise! For more on this project check out the Deconstructed.io Blog.

Some of the latest updates with this library.

But there’s still a bit of work to do for the library, so consider this a call out for anybody that has a cycle they’d like to throw in on the project, let us know. We’d happily take a few more pull requests!  The main two things we’d like to have done real soon are…

Orchestrate.js

https://github.com/orchestrate-io/orchestrate.js

With the latest fixes, additions and updates the orchestrate.js client driver is getting more feature rich by the day. In addition @housejester has created an orchestrate-brain project for Hubot that uses Orchestrate.js. If you’re not familiar with Hubot, but sure to check out the company robot that can dramatically improve and reduce employee efficiency! Keep an eye on that project for more great things, or create a Hubot to keep a robotic eye on the project.

Here are a few key things to note that have been added to help in day-to-day coding on the project.

  • The travis.yml file has been added for the Travis Continuous Integration build. This build runs against node.js v0.10 and v0.8.
  • Testing is done with mocha, expect.js and nock. To get the tests up and running, clone the repo and then build with the make file. The tests will run in tdd format.
  • Promises are provided via the kew library.

If you’re opening up the project in WebStorm, it’s great to setup the mocha tests with the integrated mocha testing as shown below. After you’ve cloned the project and run ‘npm install’ then follow these steps to add the Mocha testing to the project. We’ve already setup exclusions in the .gitignore for the .idea directory and files that WebStorm uses.

First add a configuration by clicking on Edit Configurations.

Edit Configurations

Edit Configurations

Next click on the + to add a new configuration to run. Select the Mocha option from the list of configurations.

Mocha & Other Configurations in WebStorm

Mocha & Other Configurations in WebStorm

On the next screen set a name for the configuration. Set the test directory to the path for the test directory in the project. Then finally set the User interface option for Mocha to TDD instead of the default BDD.

Edit Configuration Dialog

Edit Configuration Dialog

Last but not least run the tests and you’ll see the list of green lights light up the display with positive results.

Test Build

Test Build

Fixing Up Passport.js ‘passport-http’ for Express v4

Even though it isn’t in the primary trunk of code for the ‘passport-http’ Passport.js Strategy, I’ve upgraded the packages.json and app.js file for the basic username and passport authentication to Express.js v4. If you’re using Express.js and are looking to migrate to v4 from v3 or earlier a great starting place is to check out the “Migrating from 3.x to 4.x” wiki page. As for the passport-http strategy, here’s the updated example I put together in a commit here with my own fork here, with the code changes below.

First step was to bump to the latest Express.js v4 Module. I did this with a simple edit to the packages.json file. The original looked like this

{
  "name": "passport-http-examples-basic",
  "version": "0.0.0",
  "dependencies": {
    "express": ">= 0.0.0",
    "passport": ">= 0.0.0",
    "passport-http": ">= 0.0.0"
  }
}

which I changed the depedency from >= 0.0.0 to >= 4.0.0 so that it would require something above v4.

{
  "name": "passport-http-examples-basic",
  "version": "0.0.0",
  "dependencies": {
    "express": ">= 4.0.0",
    "passport": ">= 0.0.0",
    "passport-http": ">= 0.0.0"
  }
}

Technically the old file would have pulled the latest (which as of today I believe is 4.1.1) but it would also not do anything if you’d already pulled the example down. It just make sit more specific that the version is v4+ now.

After changing that dependency I added Morgan. Morgan is a replacement middleware for the logger. The final packages.json file looked like this when I was done.

{
  "name": "passport-http-examples-basic",
  "version": "0.0.0",
  "dependencies": {
    "express": ">= 4.0.0",
    "passport": ">= 0.0.0",
    "passport-http": ">= 0.0.0",
    "morgan": "~1.0.0"
  }
}

Once that was done I nuked my node_modules directory and ran npm install to pull down the latest bits. Once I did that, starting with the app.js I made a few changes. Below is what the app.js file looked like when I started with.

var express = require('express')
  , passport = require('passport')
  , util = require('util')
  , BasicStrategy = require('passport-http').BasicStrategy;

var users = [
    { id: 1, username: 'bob', password: 'secret', email: 'bob@example.com' }
  , { id: 2, username: 'joe', password: 'birthday', email: 'joe@example.com' }
];

function findByUsername(username, fn) {
  for (var i = 0, len = users.length; i < len; i++) {
    var user = users[i];
    if (user.username === username) {
      return fn(null, user);
    }
  }
  return fn(null, null);
}

// Use the BasicStrategy within Passport.
//   Strategies in Passport require a `verify` function, which accept
//   credentials (in this case, a username and password), and invoke a callback
//   with a user object.
passport.use(new BasicStrategy({
  },
  function(username, password, done) {
    // asynchronous verification, for effect...
    process.nextTick(function () {
      
      // Find the user by username.  If there is no user with the given
      // username, or the password is not correct, set the user to `false` to
      // indicate failure.  Otherwise, return the authenticated `user`.
      findByUsername(username, function(err, user) {
        if (err) { return done(err); }
        if (!user) { return done(null, false); }
        if (user.password != password) { return done(null, false); }
        return done(null, user);
      })
    });
  }
));

var app = express.createServer();

// configure Express
app.configure(function() {
  app.use(express.logger());
  // Initialize Passport!  Note: no need to use session middleware when each
  // request carries authentication credentials, as is the case with HTTP Basic.
  app.use(passport.initialize());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

// curl -v -I http://127.0.0.1:3000/
// curl -v -I --user bob:secret http://127.0.0.1:3000/
app.get('/',
  // Authenticate using HTTP Basic credentials, with session support disabled.
  passport.authenticate('basic', { session: false }),
  function(req, res){
   res.json({ username: req.user.username, email: req.user.email });
  });

app.listen(3000);

First changes, add some requires, remove some requires.

var express = require('express')
  , passport = require('passport')
  , util = require('util')
  , BasicStrategy = require('passport-http').BasicStrategy;

and changed it to

var express = require('express')
  , passport = require('passport')
  , util = require('util')
  , BasicStrategy = require('passport-http').BasicStrategy
  , morgan  = require('morgan')
  , app     = express();

Then I deleted the entire section shown below.

var app = express.createServer();

// configure Express
app.configure(function() {
  app.use(express.logger());
  // Initialize Passport!  Note: no need to use session middleware when each
  // request carries authentication credentials, as is the case with HTTP Basic.
  app.use(passport.initialize());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

I replace that with a nicely cleaned up Express.js v4 section of code and the replacement for logger, the morgan() library. Initializing passport however is still done in the same ole’ trusty way with initialize().

app.use(morgan());
app.use(passport.initialize());

Ordering of code has changed a bit for express.js, which meant I needed to have the app.use commands before the following section, which I moved right up underneath the two app.use statements.

// curl -v -I http://127.0.0.1:3000/
// curl -v -I --user bob:secret http://127.0.0.1:3000/
app.get('/',
    // Authenticate using HTTP Basic credentials, with session support disabled.
    passport.authenticate('basic', { session: false }),
    function(req, res){
        res.json({ username: req.user.username, email: req.user.email });
    });

Finished app.js File

After those changes the app.js file should look like this.

var express = require('express')
  , passport = require('passport')
  , util = require('util')
  , BasicStrategy = require('passport-http').BasicStrategy
  , morgan  = require('morgan')
  , app     = express();


app.use(morgan());
app.use(passport.initialize());

// curl -v -I http://127.0.0.1:3000/
// curl -v -I --user bob:secret http://127.0.0.1:3000/
app.get('/',
    // Authenticate using HTTP Basic credentials, with session support disabled.
    passport.authenticate('basic', { session: false }),
    function(req, res){
        res.json({ username: req.user.username, email: req.user.email });
    });


var users = [
    { id: 1, username: 'bob', password: 'secret', email: 'bob@example.com' }
  , { id: 2, username: 'joe', password: 'birthday', email: 'joe@example.com' }
];

function findByUsername(username, fn) {
  for (var i = 0, len = users.length; i < len; i++) {
    var user = users[i];
    if (user.username === username) {
      return fn(null, user);
    }
  }
  return fn(null, null);
}

// Use the BasicStrategy within Passport.
//   Strategies in Passport require a `verify` function, which accept
//   credentials (in this case, a username and password), and invoke a callback
//   with a user object.
passport.use(new BasicStrategy({
  },
  function(username, password, done) {
    // asynchronous verification, for effect...
    process.nextTick(function () {
      
      // Find the user by username.  If there is no user with the given
      // username, or the password is not correct, set the user to `false` to
      // indicate failure.  Otherwise, return the authenticated `user`.
      findByUsername(username, function(err, user) {
        if (err) { return done(err); }
        if (!user) { return done(null, false); }
        if (user.password != password) { return done(null, false); }
        return done(null, user);
      })
    });
  }
));

app.listen(3000);

If you execute either of the curl commands shown in the comments in the app.js code you should see the respective response when running the application.

curl -v -I http://127.0.0.1:3000/
curl -v -I --user bob:secret http://127.0.0.1:3000/

…and that should get you running with Passport.js and Express.js v4.

Configuring Node.js Web Applications… Manually || Convict.js

There’s more than a few ways to configure node.js applications. I’ll discuss a few of them in this blog entry, so without mincing work, to configuring apps!

Solution #1: Build Your Own Configuration

Often this is a super easy solution when an application just needs a single simple configuration. Here’s an example I found that’s pretty clean that Noli posted on Stackoverflow to the question “How to store Node.js deployment settings/configuration files?“.

var config = {}

config.twitter = {};
config.redis = {};
config.web = {};

config.default_stuff =  ['red','green','blue','apple','yellow','orange','politics'];
config.twitter.user_name = process.env.TWITTER_USER || 'username';
config.twitter.password=  process.env.TWITTER_PASSWORD || 'password';
config.redis.uri = process.env.DUOSTACK_DB_REDIS;
config.redis.host = 'hostname';
config.redis.port = 6379;
config.web.port = process.env.WEB_PORT || 9980;

module.exports = config;

…then load that in with a require…

var config = require('./config')

The disadvantage is when the application gets a little bigger the configuration can become unwieldy without very specific, strictly enforced guidelines.

Solution #2: Use a Library/Framework Like Convict.js

The use of a library provides some baseline in which to structure configuration. In the case of convict.js it uses a baseline schema that then can be used to extend or override based on configurations needed for alternate environments. A first steps in setting up convict.js for the fueler project looks like this.

Setup a convict.js file:

var convict = require('convict');

// Schema
var conf = convict({
    env: {
        doc: "The App Environment.",
        format: ["production", "development", "test"],
        default: "development",
        env: "NODE_ENV"
    },
    port: {
        doc: "The port to bind.",
        format: "port",
        default: 3000,
        env: "PORT"
    },
    database: {
        host: {
            default: "someplace:cool",
            env: "DB_HOST"
        }
    }
});

// perform validation
conf.validate();

module.exports = conf;

The main two configuration values are the environment and port values. Others will be added as more of the application is put together, but immediately I just wanted something to put in the project to insure it works.

Next get the convict.js library in the project.

npm install convict --save

The save gets it put into the package.json file as a dependency. Once this is installed I opened up the app.js file of the project and added a require at the top of the file after the path require and before the express() call.

var path = require('path');
var config = require('./config');

var app = express();

In the app.set line for the port I changed the setting of the port to be the configuration parameter.

app.set('port', process.env.PORT || config.get('port'));

Now when I run the application, the port will be derived from the config.js file setting.

Now What Did I Do?

I’ll write more about this in the near future, but for now I’ve run into something not being setup right. I’m still working through various parts of customizing my setup. In the instructions for convict.js, which aren’t very thorough beyond the most basic use, is how to insure that the other environments are setup with *.json files. What I mean by this is…

I’ve setup a directory with three json files. It looks like this.

My Config Directory

My Config Directory

Each of these files (or at least one of the files) I would think, based on the instructions, get loaded and merged into configuration based on the code in my app.js as shown below.

var env = conf.get('env');
conf.loadFile('./config/' + env + '.json');

The order of override for the configuration values starts with the base config.js, then any *.json files override those config.js settings and any environment variables override the *.json set configuration variables. Based on that, unless of course I’ve missed something for this snippet of code, I should be getting the configuration settings from the *.json files.

My config file data looks like this. Since it is using cjson I went ahead and stuck comments in there too.

/**
 * Created by adron on 3/14/14.
 * Description: Adding test configuration for the project.
 */

{
    "port": {
        "doc": "The port to bind.",
        "format": "port",
        "default": 1337,
        "env": "PORT"
    }
}

Until later, happy coding, I’m going to dive into this and figure out what my issue is. In my next blog entry I’ll be sure to post an update to what the problem is.

Oh, and that fueler project. Feel free to ping me and jump into it.

WebStorm JavaScripting & Noding Workflow Webinar Recording

Today the JetBrains team wrapping up final processing for my webinar from last week. You can check out the webinar via their JetBrains Youtube Channel:

JavaScriptFor even more information be sure to check out the questions and answers on the JetBrain WebStorm IDE blog entry. Some of the questions include:

  • Q: How to enable Node.js support in PhpStorm (PyCharm, IntelliJ IDEA, RubyMine)?
  • Q:How to enable autocompletion for Express, Mocha and other libraries?
  • Q: Is it possible to debug a Node.js application that runs remotely? Is it possible to debug when your node and the rest of the dependencies (database, etc.) are running in a VM environment like Vagrant?
  • Q: Does the debugger support cluster mode?

…and others all here.

Working in -34c, Wintersmith Customization & Github Hosting

Getting Wintersmith customized, building and deployed to Github and a domain name pointed takes a few extra steps. So let’s roll…

Step #1

Setup Wintersmith. See my previous blog entry “Wintersmith Creating Documentation” for this information.

Step #2

Now it’s time to get things deployed to Github. This takes a few interesting, non-intuitive steps, but once done things work extremely well. To get the appropriate git branch setup I worked with an existing git repo. This repo is the same repo that I’ve used for the public facing Deconstructed Site. The code repo is located @ Deconstructed Github Repo. I added a github pages branch to this repository, for more information on how to do this check out my Jekyll how-to “Bringing to Life an Open Source Project via Github & Jekyll – Part 1” which I detail at the beginning how to get a Github Pages site running.

Once the site is up and running I switched over to it and cleared out that path. I kept a few things I’d need like the .gitignore, README.md and a few other files. I then put the repo directory that I detailed in “Wintersmith Creates Documentation” right here in the gh-pages branch. With that in place I then just committed and pushed this code to the gh-pages repository. That gave me the initial baseline for the site.

Step #3

Get the customizations done and site domain/subdomain redirected. The steps to get the domain setup to have a custom domain pointed at your gh-pages github site is as follows:

  1. Create a file named CNAME in the root of your gh-pages branch and in that CNAME file add one line with the domain that is being directed to this gh-pages site. My CNAME file looks simply like this:
    docs.deconstructed.io
  2. Next setup either an DNS A record or cname record. The cname will give you the advantage of having Github manage which IPs are in use in their system, so if there is any failover, DDOS or IP changes then you’re protected from that. To setup an A record add the A record to point to 204.232.175.78 or setup a cname to point to your github .io account, which in my case is http://adron.github.io/. The following is what the record looked like in my Route 53 settings.
  3. Last but not least the configuration settings that need to be made in Wintersmith.
    1. First set the locals url setting to the appropriate domain or subdomain. In my case that meant changing the value from http://localhost:8080/ to http://docs.deconstructed.io/.
      "locals": {
       "url": "http://docs.deconstructed.io",
       "name": "Deconstructed Docs",
       "owner": "Adron Hall",
       "description": "This site provides the documentation around the Deconstructed API Services."
      }
      
    2. In the root of the project (where the Wintersmith build ends up) add a .nojekyll file so that Jekyll won’t be used unnecessarily to try and build the Wintersmith project.

…and with that, I’ve covered the bases for getting a Wintersmith site (blog or whatever you’re like to use it for) up and running. Feel free to ask any questions in the comments and I’ll help work through any issues you’ve encountered. Cheers!

Wintersmith Creating Documentation

I set out a few days ago to put together a documentation site. I had a few criteria for this site:

  1. A static site that I could push to Github to use with their github pages feature.
  2. The static site is generated from markdown.
  3. It just works. It’s easy to get it into a workflow without breaking the tool or breaking a solid workflow.

That was it, what I’d consider some pretty straight forward criteria. However it wasn’t that easy, until it was. Here’s a few of the issues I ran through on the way to getting a solid tool with a solid workflow working together. Beware however if you have fickle reading eyes, the following is a rant about what does and does not work.

[rant on]

Middleman Broken Ruby and Broken Gems

I have a Mac Book Pro Retina 15″. The machine runs OS-X Mavericks. I’ve had zero issue with this OS. It comes with Ruby 2 and some version of gems. My first attempt was to take a stab with middleman, the same static site builder used by many companies including Basho. Even though I ran into problems which I detailed in “Basho – First Week Coding & Research Adventures…” and “Un-breaking OS-X Mountain Lion” eventually middleman mostly worked.

Well, I didn’t get to a working app very fast. Immediately Ruby 2 had issues and gemsets puked middleman everywhere. I then ran into some confusing permissions errors. About 15 minutes into this process of troubleshooting middleman I had flashbacks of the first few days at Basho and thought, “this is bullshit, something has to work better than this catastrofuck of software version conflicts“. So I dropped middleman dead.

Assemble, Assemble, Assemble…    ??!?#@$%! WTF!

I attempted assemble next for the node.js stack. It looked to have a lot of promise. It uses grunt.js and a bunch of other tools to manage a static site generating, bootstrap using stack. The more I looked at it however it seemed busy. Busy as in “I’m going to do more than three things so I’ll maybe do none of them right“.

Reading about assemble I turned to another hacker slinging some code at the bar I sat at. She looked at the project and asked, “what’s it supposed to do exactly? I get that it’s a framework of tools but it doesn’t’ exactly lay out what it is supposed to be doing besides arbitrarily managing some parts of the stack.” That seemed reasonable to me.

Before I just tossed assemble.io to the trash heap of options I wanted to ask at least one more person. So the next day I asked my good friend and super genius Troy Howard. It was a short verdict, “drop that shit”.

That was enough for me, assemble was officially dead for this project.

Slate, This Seems Slick But…

I then took a stab at Slate. Orchestrate.io just created some excellent documentation using the Slate solution. So I dove into this, getting a test site up and running rapidly. It seemed like a mostly viable solution until I started running into issues with how and where I wanted things displayed for the code samples and other material. It appeared, if I were going to use Slate, I’d be using it almost exactly as is. I might borrow pieces of it in the future, even the layout to some degree, but for now I wanted something else that I could incorporate my themes as needed. Alas, I was super happy with Slate, it just wasn’t a great fit for now.

Where The Hell Are My Options, Jekyll?

At this point I was getting a little frustrated. I then went to a tried and true solution in jekyll. Jekyll is a pretty solid solution, with some bugs and oddball issues but nothing major. I started working with it and even transitioning a jekyll project into my theme. Hacking a jekyll blog into a reasonable documentation solution this seemed like the way to go.

But then I got a wild urge to see if there was anything else in Node.js land that I was missing. I really didn’t want to sling a Ruby project if I didn’t have to. I’d rather keep all the stacks around JavaScript for this particular set of projects. No reason to diverge when I’m just dealing with such simple straight forward web projects. I’ll diverge when something truly validate diverging, like doing some real math with a real functional language or something. Trading Node.js for one single project to go with a pseudo Ruby project for static site generation just didn’t seem appealing. So I started looking around one more time.

Made in -34°C

Yup, -34 Celsius. That's about as cold as it gets. Click for the full size chart!

Yup, -34 Celsius. That’s about as cold as it gets. Click for the full size chart!

The next solution I tried was Wintersmith. This solution appeared to have everything that I’d been looking for feature wise. It was a node.js project, it generated static content, could generate blogs but other things too, was simple, had plugins, was straight forward and more. I was a little paranoid after the solutions I’d fought my way through earlier so I went to the only place that would insure that I’d have a solution I could be confident in. I went straight to the source!

I’ll admit I took a peak at the package.json file before going head long into the source. A quick perusal of the dependencies list looked ok.

  dependencies: {
    marked: ~0.3.0,
    coffee-script: ~1.6.3,
    async: ~0.2.9,
    highlight.js: ~8.0.0,
    jade: ~1.1.5,
    ncp: ~0.5.0,
    rimraf: ~2.2.6,
    winston: ~0.7.2,
    colors: ~0.6.2,
    optimist: ~0.6.0,
    minimatch: ~0.2.14,
    mime: ~1.2.11,
    js-yaml: ~3.0.1,
    mkdirp: ~0.3.5,
    chokidar: ~0.8.1,
    server-destroy: ~1.0.0,
    npm: ~1.3.24,
    slugg: ~0.1.2
  },
  devDependencies: {
    shelljs: 0.1.x
  }

I immediately took note of a few things. The first was that there was actually a breakout of dev dependencies versus actual project dependencies. That’s a good first sign. The second thing I just went through the list and checked the various library dependencies, there were a few that I’ve played around with before that I trusted; highlight.js, coffee-script, async, js-yaml and npm were all cool by me. It didn’t seem to crazy out of whack. With that I went forth into the code with zero expectations…

The first files I dug into were the config.coffee file, which pointed out a few things I’d want to possibly tweak a little later such as the port number and other things the wintersmith server would use when running the preview server.

class Config
  ### The configuration object ###

  @defaults =
    # path to the directory containing content's to be scanned
    contents: './contents'
    # list of glob patterns to ignore
    ignore: []
    # context variables, passed to views/templates
    locals: {}
    # list of modules/files to load as plugins
    plugins: []
    # modules/files loaded and added to locals, name: module
    require: {}
    # path to the directory containing the templates
    templates: './templates'
    # directory to load custom views from
    views: null
    # built product goes here
    output: './build'
    # base url that site lives on, e.g. '/blog/'
    baseUrl: '/'
    # preview server settings
    hostname: null # INADDR_ANY
    port: 8080
    # options prefixed with _ are undocumented and should generally not be modified
    _fileLimit: 40 # max files to keep open at once
    _restartOnConfChange: true # restart preview server on config change

Second code file that looked interesting, the renderer.coffee code file.

fs = require 'fs'
util = require 'util'
async = require 'async'
path = require 'path'
mkdirp = require 'mkdirp'
{Stream} = require 'stream'

{ContentTree} = require './content'
{pump, extend} = require './utils'

if not setImmediate?
  setImmediate = process.nextTick

renderView = (env, content, locals, contents, templates, callback) -&gt;
  setImmediate -&gt;
    # add env and contents to view locals
    _locals = {env, contents}
    extend _locals, locals

    # lookup view function if needed
    view = content.view
    if typeof view is 'string'
      name = view
      view = env.views[view]
      if not view?
        callback new Error &quot;content '#{ content.filename }' specifies unknown view '#{ name }'&quot;
        return

    # run view
    view.call content, env, _locals, contents, templates, (error, result) -&gt;
      error.message = &quot;#{ content.filename }: #{ error.message }&quot; if error?
      callback error, result

render = (env, outputDir, contents, templates, locals, callback) -&gt;
  ### Render *contents* and *templates* using environment *env* to *outputDir*.
      The output directory will be created if it does not exist. ###

  env.logger.info &quot;rendering tree:\n#{ ContentTree.inspect(contents, 1) }\n&quot;
  env.logger.verbose &quot;render output directory: #{ outputDir }&quot;

  renderPlugin = (content, callback) -&gt;
    ### render *content* plugin, calls *callback* with true if a file is written; otherwise false. ###
    renderView env, content, locals, contents, templates, (error, result) -&gt;
      if error
        callback error
      else if result instanceof Stream or result instanceof Buffer
        destination = path.join outputDir, content.filename
        env.logger.verbose &quot;writing content #{ content.url } to #{ destination }&quot;
        mkdirp.sync path.dirname destination
        writeStream = fs.createWriteStream destination
        if result instanceof Stream
          pump result, writeStream, callback
        else
          writeStream.end result, callback
      else
        env.logger.verbose &quot;skipping #{ content.url }&quot;
        callback()

  items = ContentTree.flatten contents
  async.forEachLimit items, env.config._fileLimit, renderPlugin, callback

module.exports = {render, renderView}

Fairly straight forward code. Puts together the rendered content and I noted a few key things. There was a solid process order that was repeated; env, content, locals, contents, templates, callback. Because of this it looked like local variables were set to statically set certain things based on configuration instead of dynamic location. This could bite me, but with this quick glance, at least I knew where and what was happening with the order of generation.

I then did a scan of the templates.coffee and a few other code files. Having gotten a fair idea of where and what was being done, I went looking for a quick start. Things looked pretty good, so I crossed my fingers and my rant ends here…

[/rant off]

So now that the rant mode was over, here’s what I did to make wintersmith my documentation solution. Most of this is in a state of flux as I automate and put more into the project to simplify the workflow.

Here’s how I got started super fast.

Step #1 Get Wintersmith running.

npm install wintersmith -g

Note that you’ll need to install it globally (thus the -g) and may need to install Wintersmith with sudo prepended to that command.

The next thing that I did was create a directory that I’d use to build the static generated contents. This material I’d put into a git repository on github (namely the deconstructed gh-pages repo). I’ll call this generically the root directory.

mkdir rootDirectory

After that I navigated into the rootDirectory and created a new Wintersmith Application.

wintersmith new myAppName

That now gives me a directory structure like this

  • rootDirectory
    • myAppName

Now that I have this, the app content, markdown, views and related templates are in myAppName. To view the app, I changed directories into myAppName and ran wintersmith preview like this

wintersmith preview

Opening up a browser I can navigate to http://localhost:8080 and see the fully rendered site. To publish the site however one needs to run wintersmith build, however there’s one problem. I want the site to publish to the rootDirectory where the application content currently sites. To do this I have to edit the config.json file. Just above the locals code settings shown below…

{
  locals: {
    url: http://localhost:8080,
    name: The Wintersmith's blog,
    owner: Someone,
    description: Ramblings of an immor(t)al demigod
}

I added an output key value property to the file as shown. It merely takes the results and shifts them back a directory so they end up in the rootDirectory.

{
  output:../,
  locals: {
    url: http://docs.deconstructed.io,
    name: Deconstructed Docs,
    owner: Adron Hall,
    description: This site provides the documentation around the Deconstructed API Services.
  },
  plugins: [
    ./plugins/paginator.coffee
  ],
  require: {
    moment: moment,
    _: underscore,
    typogr: typogr
  },
  jade: {
    pretty: true
  },
  markdown: {
    smartLists: true,
    smartypants: true
  },
  paginator: {
    perPage: 6
  }
}

I also changed the perPage setting to 6, just so I could get a little more content on the main page eventually. There is also the change for the domain name and a few other parameters that I’ll catch up on with the next blog entry.

Summary

In my next blog entry I’ll cover a quick how-to on how to setup the CNAME in github pages to get the static wintersmith site up at a subdomain/domain name. I’ll also dive into setup with AWS Route 53, which generically applies to setting a gh-pages site up with any DNS provider. So subscribe and I’ll have that post in the next 1-2 days.

I’ve Got a JavaScript & Node.js Webinar, Webstorm Tutorial Videos, Work & Flow With JavaScript Development and More…

Webinar: Node.js Development Workflow in WebStorm

This coming week I’m doing an intro to work and flow with Node.js JavaScript Programming that I’m working with JetBrains on. In the webinar I’ll be covering the following key topics in the webinar:

  • Open an existing project & getting WebStorm configured for running, testing and related working tasks.
  • A quick tour of other IDE features that help with daily work. Some in pretty huge ways.
  • Running WebStorm & debugging Node.js JavaScript applications.
  • Checking out Mocha, how it works and what it gives WebStorm the power to do. Then we’ll write a few tests & implement that code too.

All this will include Q & A throughout and at the end of the webinar. Be sure to register soon!

WebStorm Tutorials: Learning Shortcuts, Customizing Layout and Others

These WebStorm Tutorials have been put together by John Lindquist @johnlindquist for JetBrains. There solid, quick snippets of useful WebStorm usage. Two that I’ve found really useful I’ve included here:

John also has a lot of other great totally kick ass material out there. So check out his blog @ http://johnlindquist.com/ and follow his youtube channel too.

Coming Up in the Near Future, The Work & Flow of JavaScript Development

I have a new course I’m working on right now for Pluralsight, that will take these basic precepts and dive even deeper into the daily workflow of the JavaScript Developer. Whether it’s client side hacking or server side coding, I’ll be diving into a whole lot of JavaScript goodness. If you’d like me to ping you when the course is done, hit me up on Twitter @adron and just let me know. In the meantime get a Pluralsight subscription (free to sign up and at least give it a try) and check out these courses by myself and others.