Giter Site home page Giter Site logo

rendr-app-template's Introduction

Note:

This repo has been deprecated in favor of the

rendr-examples repo, which is easier to keep up-to-date.


Rendr App Template

GitHub Browser

The purpose of this little app is to demonstrate one way of using Rendr to build a web app that runs on both the client and the server.

Screenshot

Running the example

First, make sure to have Node >= 0.8.0 installed on your system. Also, make sure to have grunt-cli installed globally.

$ npm install -g grunt-cli

If you see an error on startup that looks like this, then you may need to un-install a global copy of grunt:

$ npm uninstall -g grunt

Clone this repo to a local directory and run npm install to install dependencies:

$ git clone [email protected]:airbnb/rendr-app-template.git
$ cd rendr-app-template
$ npm install

Then, use grunt server to start up the web server. Grunt will recompile and restart the server when files change.

$ grunt server
Running "bgShell:runNode" (bgShell) task

Running "handlebars:compile" (handlebars) task
File "app/templates/compiledTemplates.js" created.

Running "rendr_stitch:compile" (rendr_stitch) task
4 Apr 09:58:02 - [nodemon] v0.7.2
4 Apr 09:58:02 - [nodemon] watching: /Users/spike1/code/rendr-app-template
4 Apr 09:58:02 - [nodemon] starting `node index.js`
4 Apr 09:58:02 - [nodemon] reading ignore list
File "public/mergedAssets.js" created.

Running "stylus:compile" (stylus) task
File public/styles.css created.
server pid 87338 listening on port 3030 in development mode

Running "watch" task
Waiting...

Now, pull up the app in your web browser. It defaults to port 3030.

$ open http://localhost:3030

You can choose a different port by passing the PORT environment variable:

$ PORT=80 grunt server

GitHub API rate limit

GitHub rate limits unauthenticated requests to its public API to 60 requests per hour per IP. This should be enough for just playing with the sample app, but if you pull it down and start developing off it you may run up against the rate limit.

If this happens to you, you can supply your GitHub creds for HTTP Basic Auth using the BASIC_AUTH environment variable. Be very, very careful with this! It means you will be typing your GitHub credentials in plain text, which will be saved to your Bash history and may be intercepted by other programs. If you do this, immediately change your password before and afterwards. This should only be necessary if you're developing on the app and need to keep refreshing the page.

$ BASIC_AUTH=githubusername:githubpassword grunt server

You've been warned. Your best bet may be to alter the project to read from your favorite RESTful API.

Getting Started With Rendr

It's worthwhile to read the first blog post, which has some background on Rendr and its raison d'être.

This basic Rendr app looks like a hybrid between a standard client-side MVC Backbone.js app and an Express app, with a little Rails convention thrown in.

Check out the directory structure:

|- app/
|--- collections/
|--- controllers/
|--- models/
|--- templates/
|--- views/
|--- app.js
|--- router.js
|--- routes.js
|- assets/
|- config/
|- public/
|- server/

Note: I want to stress that this is just one way to build an app using Rendr. I hope it can evolve to support a number of different app configurations, with the shared premise that the components should be able to run on either side of the wire. For example, the full-on client-side MVC model isn't appropriate for all types of apps. Sometimes it's more appropriate to load HTML fragments over the wire, also known as PJAX. Rendr apps should be able to support this as well.

CommonJS using Stitch

Node.js uses the CommonJS module pattern, and using a tool called Stitch, we can emulate it in the browser. This looks familiar in Node.js:

var User = require('app/models/user');

Using Stitch, we can use the same require() function in the browser. This allows us to focus on application logic, not packaging modules separately for client and server.

In Node.js, you can also use require() to load submodules within NPM models. For example, we could load Rendr's base view in order to extend it to create a view for our app.

var BaseView = require('rendr/shared/base/view');

Because of a trick in the way we do Stitch packaging, this module path works in the browser as well.

Routes file

// app/routes.js
module.exports = function(match) {
  match('',                   'home#index');
  match('repos',              'repos#index');
  match('repos/:owner/:name', 'repos#show');
  match('users'       ,       'users#index');
  match('users/:login',       'users#show');
};

Controllers

A controller is a simple JavaScript object, where each property is a controller action. Keep in mind that controllers are executed on both the client and the server. Thus, they are an abstraction whose sole responsibility is to specify which data is needed to render the view, and which view to render.

On the server, controllers are executed in response to a request to the Express server, and are used to render the initial page of HTML. On the client, controllers are executed in response to pushState events as the user navigates the app.

Here is a very simple controller:

// app/controllers/home_controller.js
module.exports = {
  index: function(params, callback) {
    callback(null, 'home_index_view');
  }
};

Every action gets called with two arguments: params and callback. The params object contains both route params and query string params. callback is called to kick off view rendering. It has this signature:

function(err, viewName, viewData) {}

err

Following the Node.js convention, the first argument to the callback is err. We'll pass null here because we're not fetching any data, but if we were, that's how we'd communicate a fetching error.

viewName

This is a string identifier of a view, used by the router to find the view class, i.e.:

require('app/views/' + viewName);

viewData (optional)

An object to pass to the view constructor. This is how we pass data to the view.

All our index action above really does is specify a view class. This is the simple case -- no data fetching, just synchronous view rendering.

It gets more interesting when we decide to fetch some data. Check out the repos_controller below:

// app/controllers/repos_controller.js
module.exports = {
  // ...

  show: function(params, callback) {
    var spec = {
      model: {model: 'Repo', params: params}
    };
    this.app.fetch(spec, function(err, result) {
      callback(err, 'repos_show_view', result);
    });
  }
};

You see here that we call this.app.fetch() to fetch our Repo model. Our controller actions are executed in the context of the router, so we have a few properties and methods available, one of which is this.app. This is the instance of our application's App context, which is a sublcass of rendr/base/app, which itself is a subclass of Backbone.Model. You'll see that we inject app into every model, view, collection, and controller; this is how we maintain app context throughout our app.

You see here that we call callback with the err that comes from this.app.fetch(), the view class name, and the result of the fetch. result in this case is an object with a single model property, which is our instance of the Repo model.

this.app.fetch() does a few nice things for us; it fetches models or collections in parallel, handles errors, does caching, and most importantly, provides a way to boostrap the data fetched on the server in a way that is accessible by the client-side on first render.

Views

A Rendr view is a subclass of Backbone.View with some additional methods added to support client-server rendering, plus methods that make it easier to manage the view lifecycle.

Creating your own view should look familiar if you've used Backbone:

// app/views/home_index_view.js
var BaseView = require('./base_view');

module.exports = BaseView.extend({
  className: 'home_index_view',

  events: {
    'click p': 'handleClick',
  },

  handleClick: function() {}
});
module.exports.id = 'HomeIndexView';

You can add className, tagName, events, and all of the other Backbone.View properties you know and love.

We set the property id on the view constructor to aid in the view hydration process. More on that later.

Our views, just like all of the code in the app/ directory, are executed in both the client and the server, but of course certain behaviors are only relevant in the client. The events hash is ignored by the server, as well as any DOM-related event handlers.

Notice there's no render() method or template property specified in the view. The philosophy here is that sensible defaults and convention over configuration should allow you to skip all the typical boilerplate when creating views. The render() method should be the same for all your views; all it does is mash up the template with some data to generate HTML, and insert that HTML into the DOM element.

Now, because we're not using a DOM to render our views, we must make sure that the view returns all its HTML as a string. On the server, view.getHtml() is called, which returns the view's outer HTML, including wrapper element. This is then handed to Express, which wraps the page with a layout and sends the full HTML page to the client. Behind the scenes, view.getHtml() calls view.getInnerHtml() for the inner HTML of the view, not including wrapping element, and then constructs the wrapping element based on the tagName, className, etc. properties, and the key-value pairs of HTML attributes returned by view.getAttributes(), which allows you to pass custom attributes to the outer element.

On the client, view.render() is called, which updates the view's DOM element with the HTML returned from view.getInnerHtml(). By default, Backbone will create the wrapper DOM element on its own. We make sure to also set any custom HTML attributes in view.getAttributes() on the element.

The view lifecycle

A common need is to run some initialization code that touches the DOM after render, for things like jQuery sliders, special event handling, etc. Rather than overriding the render() method, use postRender(). The postRender() method is executed for every view once after rending, including after initial pageload.

// app/views/home_index_view.js
var BaseView = require('./base_view');

module.exports = BaseView.extend({
  className: 'home_index_view',

  postRender: function() {
    this.$('.slider').slider();
  }
});
module.exports.id = 'HomeIndexView';

If you have a need to customize the way your views generate HTML, there are a few specific methods you can override.

getTemplateName()

By default, getTemplateName() returns the underscored version of the view constructor's id property; so in our case, home_index_view. It will also look for options.template_name, which is useful for initialing views to use a certain template. The view will look in app/templates for the value returned by this function.

getTemplate()

If getTemplateName() isn't enough, you can override getTemplate() to return a function that takes a single data argument and returns HTML:

function(data) {
  ...
  return html;
}

This HTML is used to populate the view's inner HTML; that is, not including the wrapper element, which you can specify on the view itself using tagName, className, and id.

getInnerHtml()

If you're building some sort of composite view that doesn't utilize a simple template, override getInnerHtml(). This is useful for tabbed views, collection views, etc.

getHtml()

You probably shouldn't ever need to override this; by default it just combines the HTML returned by getInnerHtml() and the HTML attributes returned by getAttributes() to produce an outer HTML string.

The view hierarchy

Rendr provides a Handlebars helper {{view}} that allows you to declaratively nest your views, creating a view hierarchy that you can traverse in your JavaScript. Check out app/templates/users/show.hbs and app/views/users/show.js for an example:

<!-- app/templates/users/show.hbs -->
...

<div class="span6">
  {{view "user_repos_view" collection=repos}}
</div>

<div class="span6">
  ...
</div>

You see that we use the {{view}} helper with an argument that indicates which view to be rendered. We can pass data into the view using Handlebars' hash arguments. Anything you pass as hash arguments will be pass to the subview's constructor and be accessible as this.options within the subview. There are a few special options you can pass to a view: model or collection can be used to directly pass a model or collection instance to a subview. The options model_name + model_id or collection_name + collection_params can be used in conjunction with lazy="true" to lazily fetch models or collections; more on that later.

Now, from within the users/show view, we can access any child views using the this.childViews array. A good way to debug and get a feel for this in the browser is to drill down into the global App property, which is your instance of BaseApp. From App you can access other parts of your application. App.router is your instance of ClientRouter, and it has a number of properties that you can inspect. One of these is App.router.currentView, which will always point to the current main view for a page. For example, if you are viewing wycats' page in our app, http://localhost:3030/users/wycats, currentView will be an instance of users/show:

App.router.currentView
=> child {render: function, cid: "view434", model: child, options: Object, $el: p.fn.p.init[1]…}

From there, we can find our child user_repos_view view:

App.router.currentView.childViews
=> [child]

App.router.currentView.childViews[0]
=> child {render: function, cid: "view436", options: Object, $el: p.fn.p.init[1], el: div.user_repos_view…}

Check out its collection property, which is the instance of Repos which we fetched in the controller and passed down in the {{view}} helper:

App.router.currentView.childViews[0].collection
=> child {options: Object, app: child, params: Object, meta: Object, length: 30…}

You can nest subviews ad infinitum. Our user_repos_view has an empty childViews array now, but we could add some subviews if we found it useful for organizing our codebase, or keeping things DRY.

App.router.currentView.childViews[0].childViews
=> []

Views also have a parentView property, which will be non-null unless they are a top-level view.

App.router.currentView.childViews[0].parentView === App.router.currentView
=> true

App.router.currentView.parentView
=> null

Lazy-loading data for views

So far, our users#show action pulls down both a User model and a Repos collection for that model. If we were to navigate from users#index to users#show, we already have that user model cached in memory (because we fetched it in order to render the list), but we have to make a roundtrip to the server to fetch the Repos, which aren't part of the User attributes. This means that instead of immediately rendering the users/show view, we wait for the Repos API call to finish. But what if instead we want to lazy-load the Repos so we can render that view immediately for a better user experience?

We can achieve this by lazy-loading models or collections in our subviews. Check out the users#show_lazy action, which demonstrates this approach:

// app/controllers/users_controller.js
module.exports = {
  // ...

  show_lazy: function(params, callback) {
    var spec = {
      model: {model: 'User', params: params}
    };
    this.app.fetch(spec, function(err, result) {
      if (err) return callback(err);
      // Extend the hash of options we pass to the view's constructor
      // to include the `template_name` option, which will be used
      // to look up the template file. This is a convenience so we
      // don't have to create a separate view class.
      _.extend(result, {
        template_name: 'users/show_lazy'
      });
      callback(err, 'users/show', result);
    });
  }
}

The first thing to notice is that in our fetch spec, we only specify the User model, leaving out the Repos collection. Then, we tell the view to use a different template than the default. We do this by passing in a template_name property to the view's options, which is passed to its constructor. We extend the result object to have this; the third argument to our callback is an object that's passed to the view's constructor. We could have also created a separate view class in JavaScript for this, to match our new template.

Here's the users/show_lazy template, abbreviated:

<!-- app/templates/users/show_lazy.hbs -->
...

<div class="span6">
  {{view "user_repos_view" collection_name="Repos" param_name="login" param_value=login lazy="true"}}
</div>

<div class="span6">
  ...
</div>

So, the only difference to our original users/show template is that instead of passing collection=repos to our user_repos_view subview, we pass collection_name="Repos" param_name="login" param_value=login lazy="true". When fetching collections, we specify params, which are used to fetch and cache the models for that collection. We quote all of these arguments except for param_value=login; quoted arguments are passed in as string literals, and unquoted arguments are references to variables that are available in the current Handlebars scope. login is one of the attributes of a User model, which gets passed into the template. The lazy="true" tells the view that it needs to fetch (or find a cached version of) the specified model or collection.

We can see this at play in our app if we add a route in our app/routes.js file that routes users_lazy/:login to users#show_lazy, and change our app/templates/users_index_view.hbs to link to /users_lazy/{{login}}.

Now, if we click from the list of users on users#index, you'll see the page gets rendered immediately, and the repos are rendered once the API call finishes. If you click back and forward in your browser, you see it's cached.

Templates

So far, Rendr just supports Handlebars templates, but it should be possible to make this interchangeable. For now, place your templates in app/templates with a name that matches the underscorized view's identifier and file extension of .hbs. So, the view with an identifier of HomeIndexView will look for a template at app/templates/home_index_view.hbs.

Interacting with a RESTful API

Assets

In this example we use Grunt to manage asset compilation. We compile JavaScripts using Stitch and stylesheets using Stylus. Check out Gruntfile.js in the root directory of this repo for details.

License

MIT

rendr-app-template's People

Contributors

aflanagan avatar barrettcook avatar c089 avatar foxyblocks avatar hurrymaplelad avatar iamnirav avatar neojp avatar spikebrehm avatar takashi avatar timhudson avatar zmian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rendr-app-template's Issues

apiProxy should handle status code 204 properly

An API server may return "204 No Content" for PUT or DELETE request, but apiProxy ignores it and returns "200 OK" on the server side.

      // Pass through statusCode, but not if it's an i.e. 304.
      status = response.statusCode;
      if (utils.isErrorStatus(status)) {
        res.status(status);
      }
      res.json(body);

Then, on the client side, jQuery detects "parseerror" because the response has no body.
Actually, this error occurs from "304 Not Modified" too. So, I'm not sure of this comment, but workaround is here.

      // Pass through statusCode, but not if it's an i.e. 304.
      status = response.statusCode;
      if (utils.isErrorStatus(status) || +status === 204) {

However, I believe apiProxy always should pass through status code and also end-to-end headers.

Failed to install grunt-contrib-handlebars

I tried modifying the line git://github.com/spikebrehm/grunt-contrib-handlebars#d61e7457c6551965f88de46ad207fd67d18ddd4a in package.json to git://github.com/spikebrehm/grunt-contrib-handlebars, but it didn't work.
Here's the npm log:

201 error Error: `git "clone" "--mirror" "git://github.com/spikebrehm/grunt-contrib-handlebars" "/home/chun-yi/.npm/_git-remotes/git-github-com-spikebrehm-grunt-contrib-handlebars-683221c7"` failed with 128
201 error     at ChildProcess.<anonymous> (/home/chun-yi/.nvm/v0.8.20/lib/node_modules/npm/lib/utils/exec.js:56:20)
201 error     at ChildProcess.EventEmitter.emit (events.js:99:17)
201 error     at maybeClose (child_process.js:638:16)
201 error     at Process._handle.onexit (child_process.js:680:5)
202 error If you need help, you may report this log at:
202 error     <http://github.com/isaacs/npm/issues>
202 error or email it to:
202 error     <[email protected]>
203 error System Linux 2.6.32-45-generic
204 error command "/home/chun-yi/.nvm/v0.8.20/bin/node" "/home/chun-yi/.nvm/v0.8.20/bin/npm" "install"
205 error cwd /home/chun-yi/rendr-app-template
206 error node -v v0.8.20
207 error npm -v 1.2.11
208 verbose exit [ 1, true ]

And my grunt version:

grunt-cli v0.1.7
grunt v0.4.1

clientSync is used on a request when trying to create the server different from the index.js file

I'd like to use visionmedia/supertest to test our rendr app, but have a problem: Supertest takes the express app function and creates a server itself, which is convenient:

   if ('function' == typeof app) app = http.createServer(app);

So, I thought I could test the rendr app like this:

        var supertest = require('supertest'),
            server = require('../../server/server');
        //...
        server.init(function (err) {
            supertest(server.app)
                .get('/products/1')
                .end(function (err, response) {
                    // assertions on response here
                    done(err);
                });
        });

This works as long as I only call urls which go to views which do not use models to fetch data. As soon as a fetch is done, it bails because backbone does not have $ and in the stacktrace we see that clientSync is used:

TypeError: Cannot read property 'ajax' of undefined
at Object.Backbone.ajax (/Users/cnr/Documents/dev/lusini/1up-mario/node_modules/rendr/node_modules/backbone/backbone.js:1202:22)
at Object.Backbone.sync (/Users/cnr/Documents/dev/lusini/1up-mario/node_modules/rendr/node_modules/backbone/backbone.js:1185:38)
at clientSync [as sync] (/Users/cnr/Documents/dev/lusini/1up-mario/node_modules/rendr/shared/syncer.js:33:19)
at _.extend.fetch (/Users/cnr/Documents/dev/lusini/1up-mario/node_modules/rendr/node_modules/backbone/backbone.js:442:19)
at Fetcher.fetchFromApi (/Users/cnr/Documents/dev/lusini/1up-mario/node_modules/rendr/shared/fetcher.js:220:9)
at Fetcher.<anonymous> (/Users/cnr/Documents/dev/lusini/1up-mario/node_modules/rendr/shared/fetcher.js:146:14)
at /Users/cnr/Documents/dev/lusini/1up-mario/node_modules/rendr/node_modules/async/lib/async.js:467:25

The only difference between starting the server through index.js and this approach of requiring the server and using server.initServer is that server.start is not called, but I don't understand where this makes a difference:

exports.start = function start(options) {
  options = options || {};
  var port = options.port || 3030;
  app.listen(port);
  console.log("server pid " + process.pid + " listening on port " + port + " in " + app.settings.env + " mode");
}

grunt server fails on Windows 7

Guys, have tried to invoke grunt server on TWO different Windows 7 machines but seem to come up against the same issue:

Running "bgShell:runNode" (bgShell) task

Running "handlebars:compile" (handlebars) task
File "app/templates/compiledTemplates.js" created.

Running "rendr_stitch:compile" (rendr_stitch) task
>> '.' is not recognized as an internal or external command,
>> operable program or batch file.
>> Error: Command failed: '.' is not recognized as an internal or external command,
>> operable program or batch file.
Warning: F:\rendr-app-template\node_modules\grunt-rendr-stitch\tmp\bundle\app\app.js isn't in the require path 
Use --force to continue.

Works fine on the MAC.

Some thoughts on the README

While the README generally did a good job on getting us started on exploring the app-template, there were a few things we were confused by while reading the documentation:

We set the property identifier on the view constructor to aid in the view hydration process. More on that later.

However, there is no mention of "hydration" further down in the README... We are still wondering why it is required to have this property on View constructors, but not e.g. on the Controller constructor.

We also think the following statement

Because of a trick in the way we do Stitch packaging, this module path works in the browser as well.

justifies more explanation, at least a pointer to where that "trick" is implemented so we can understand what's going on.

Please let us know if this it the right place to place to ask this kind of question. We'd also like to aid in the documentation process so I'll keep opening pull requests even for typos or when we try to make things clearer while we explore and evaluate rendr for our needs - unless you don't like that kind of micro-improvement :)

Thanks for the great project!

Error when hitting reload on sub-pages (repos or users)

Hello,

I was able to get the rendr-app-template app up and running and everything works as expected until I hit the refresh button in the browser on the repos or users sub-pages.

Not sure if I'm the only one having this problem but decided to post the error anyways:

Express
500 TypeError: Cannot call method 'makeRequest' of null

at serverSync [as sync] (/Users/myuser/node/rendr-app-template/node_modules/rendr/shared/syncer.coffee:51:31)
at _.extend.fetch (/Users/myuser/node/rendr-app-template/node_modules/rendr/node_modules/backbone/backbone.js:860:19)
at module.exports.Base.fetch (/Users/myuser/node/rendr-app-template/node_modules/rendr/shared/base/collection.coffee:67:35)
at fetchFromApi (/Users/myuser/node/rendr-app-template/node_modules/rendr/shared/fetcher.coffee:146:18)
at Object._.each.batchedRequests.(anonymous function) [as collection] (/Users/myuser/node/rendr-app-template/node_modules/rendr/shared/fetcher.coffee:92:18)
at async.parallel (/Users/myuser/node/rendr-app-template/node_modules/rendr/node_modules/async/lib/async.js:467:25)
at async.forEach (/Users/myuser/node/rendr-app-template/node_modules/rendr/node_modules/async/lib/async.js:86:13)
at Array.forEach (native)
at _forEach (/Users/myuser/node/rendr-app-template/node_modules/rendr/node_modules/async/lib/async.js:26:24)
at Object.async.forEach (/Users/myuser/node/rendr-app-template/node_modules/rendr/node_modules/async/lib/async.js:85:9)
at Object.async.parallel (/Users/myuser/node/rendr-app-template/node_modules/rendr/node_modules/async/lib/async.js:466:19)
at retrieve (/Users/myuser/node/rendr-app-template/node_modules/rendr/shared/fetcher.coffee:121:18)
at Object.fetcher.fetch (/Users/myuser/node/rendr-app-template/node_modules/rendr/shared/fetcher.coffee:268:12)
at module.exports.App.fetch (/Users/myuser/node/rendr-app-template/node_modules/rendr/shared/app.coffee:40:27)
at Object.module.exports.index (/Users/myuser/node/rendr-app-template/app/controllers/repos_controller.js:6:14)
at module.exports.ServerRouter.getHandler (/Users/myuser/Node/rendr-app-template/node_modules/rendr/server/router.coffee:50:23)
at callbacks (/Users/myuser/Node/rendr-app-template/node_modules/express/lib/router/index.js:161:37)
at module.exports (/Users/myuser/Node/rendr-app-template/node_modules/rendr/server/middleware/initApp.coffee:12:14)
at callbacks (/Users/myuser/Node/rendr-app-template/node_modules/express/lib/router/index.js:161:37)
at param (/Users/myuser/Node/rendr-app-template/node_modules/express/lib/router/index.js:135:11)
at pass (/Users/myuser/Node/rendr-app-template/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/Users/myuser/Node/rendr-app-template/node_modules/express/lib/router/index.js:170:5)
at Object.router (/Users/myuser/Node/rendr-app-template/node_modules/express/lib/router/index.js:33:10)
at next (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at multipart (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/multipart.js:64:37)
at module.exports (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:57:9)
at urlencoded (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js:51:37)
at module.exports (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:55:7)
at json (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/json.js:53:37)
at Object.bodyParser [as handle] (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:53:5)
at next (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at Object.logger (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/logger.js:156:5)
at next (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at resume (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/static.js:60:7)
at SendStream.error (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/connect/lib/middleware/static.js:73:37)
at SendStream.EventEmitter.emit (events.js:115:20)
at SendStream.error (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/send/lib/send.js:147:51)
at SendStream.onStatError (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/send/lib/send.js:248:48)
at SendStream.pipe (/Users/myuser/Node/rendr-app-template/node_modules/express/node_modules/send/lib/send.js:320:26)
at Object.oncomplete (fs.js:297:15) 

QUICK NOTE: Also had to have coffee-script & grunt pre-installed globally with -g to be able to run the app, maybe worth mentioning under "running the example" in the readme.

npm install errors (ubuntu 12.04)

I get the following errors when I run npm install:

vagrant@precise32:/home/website/nodejs/rendr-try2/rendr-app-template$ npm install
npm http GET https://registry.npmjs.org/grunt-contrib-stylus
npm http GET https://registry.npmjs.org/express
npm http GET https://registry.npmjs.org/rendr-handlebars/0.0.5
npm http GET https://registry.npmjs.org/js-yaml
npm http GET https://registry.npmjs.org/grunt
npm http GET https://registry.npmjs.org/nodemon
npm http GET https://registry.npmjs.org/grunt-rendr-stitch
npm http GET https://registry.npmjs.org/mocha
npm http 200 https://registry.npmjs.org/rendr-handlebars/0.0.5
npm http GET https://registry.npmjs.org/rendr-handlebars/-/rendr-handlebars-0.0.5.tgz
npm http 200 https://registry.npmjs.org/grunt-contrib-stylus
npm http 200 https://registry.npmjs.org/js-yaml
npm http 200 https://registry.npmjs.org/grunt
npm http 200 https://registry.npmjs.org/grunt-rendr-stitch
npm http 200 https://registry.npmjs.org/nodemon
npm http 200 https://registry.npmjs.org/mocha
npm http 200 https://registry.npmjs.org/express
npm http GET https://registry.npmjs.org/grunt-contrib-stylus/-/grunt-contrib-stylus-0.5.1.tgz
npm http GET https://registry.npmjs.org/js-yaml/-/js-yaml-2.1.3.tgz
npm http GET https://registry.npmjs.org/grunt/-/grunt-0.4.1.tgz
npm http GET https://registry.npmjs.org/grunt-rendr-stitch/-/grunt-rendr-stitch-0.0.8.tgz
npm http GET https://registry.npmjs.org/nodemon/-/nodemon-0.7.10.tgz
npm http GET https://registry.npmjs.org/mocha/-/mocha-1.9.0.tgz
npm http GET https://registry.npmjs.org/express/-/express-3.4.3.tgz
npm http 200 https://registry.npmjs.org/rendr-handlebars/-/rendr-handlebars-0.0.5.tgz
npm http 200 https://registry.npmjs.org/nodemon/-/nodemon-0.7.10.tgz
npm http 200 https://registry.npmjs.org/grunt-contrib-stylus/-/grunt-contrib-stylus-0.5.1.tgz
npm http 200 https://registry.npmjs.org/grunt/-/grunt-0.4.1.tgz
npm http 200 https://registry.npmjs.org/mocha/-/mocha-1.9.0.tgz
npm http 200 https://registry.npmjs.org/grunt-rendr-stitch/-/grunt-rendr-stitch-0.0.8.tgz
npm http 200 https://registry.npmjs.org/js-yaml/-/js-yaml-2.1.3.tgz
npm http 200 https://registry.npmjs.org/express/-/express-3.4.3.tgz
npm http GET https://registry.npmjs.org/rendr
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/async
npm http 200 https://registry.npmjs.org/rendr
npm http GET https://registry.npmjs.org/rendr/-/rendr-0.4.10.tgz
npm http 200 https://registry.npmjs.org/coffee-script
npm http 200 https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.3.tgz
npm http 200 https://registry.npmjs.org/rendr/-/rendr-0.4.10.tgz
npm http GET https://registry.npmjs.org/async/-/async-0.2.9.tgz
npm http 200 https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.3.tgz
npm http 200 https://registry.npmjs.org/async/-/async-0.2.9.tgz
npm http GET https://registry.npmjs.org/mkdirp/0.3.5
npm http GET https://registry.npmjs.org/buffer-crc32/0.2.1
npm http GET https://registry.npmjs.org/cookie/0.1.0
npm http GET https://registry.npmjs.org/fresh/0.2.0
npm http GET https://registry.npmjs.org/methods/0.0.1
npm http GET https://registry.npmjs.org/send/0.1.4
npm http GET https://registry.npmjs.org/cookie-signature/1.0.1
npm http GET https://registry.npmjs.org/connect/2.10.1
npm http GET https://registry.npmjs.org/commander/1.3.2
npm http GET https://registry.npmjs.org/range-parser/0.0.4
npm http GET https://registry.npmjs.org/stylus
npm http GET https://registry.npmjs.org/nib
npm http 200 https://registry.npmjs.org/methods/0.0.1
npm http 200 https://registry.npmjs.org/buffer-crc32/0.2.1
npm http 200 https://registry.npmjs.org/mkdirp/0.3.5
npm http 200 https://registry.npmjs.org/send/0.1.4
npm http 200 https://registry.npmjs.org/fresh/0.2.0
npm http 200 https://registry.npmjs.org/cookie/0.1.0
npm http 200 https://registry.npmjs.org/cookie-signature/1.0.1
npm http GET https://registry.npmjs.org/methods/-/methods-0.0.1.tgz
npm http 200 https://registry.npmjs.org/range-parser/0.0.4
npm http 200 https://registry.npmjs.org/commander/1.3.2
npm http 200 https://registry.npmjs.org/connect/2.10.1
npm http GET https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz
npm http 200 https://registry.npmjs.org/nib
npm http GET https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz
npm http GET https://registry.npmjs.org/send/-/send-0.1.4.tgz
npm http GET https://registry.npmjs.org/fresh/-/fresh-0.2.0.tgz
npm http 200 https://registry.npmjs.org/stylus
npm http GET https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz
npm http GET https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.1.tgz
npm http GET https://registry.npmjs.org/range-parser/-/range-parser-0.0.4.tgz
npm http GET https://registry.npmjs.org/commander/-/commander-1.3.2.tgz
npm http GET https://registry.npmjs.org/connect/-/connect-2.10.1.tgz
npm http GET https://registry.npmjs.org/nib/-/nib-0.9.2.tgz
npm http GET https://registry.npmjs.org/stylus/-/stylus-0.32.1.tgz
npm http GET https://registry.npmjs.org/grunt-lib-contrib
npm http 200 https://registry.npmjs.org/methods/-/methods-0.0.1.tgz
npm http 200 https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz
npm http 200 https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.1.tgz
npm http 200 https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz
npm http 200 https://registry.npmjs.org/range-parser/-/range-parser-0.0.4.tgz
npm http 200 https://registry.npmjs.org/commander/-/commander-1.3.2.tgz
npm http 200 https://registry.npmjs.org/fresh/-/fresh-0.2.0.tgz
npm http 200 https://registry.npmjs.org/send/-/send-0.1.4.tgz
npm http 200 https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz
npm http 200 https://registry.npmjs.org/nib/-/nib-0.9.2.tgz
npm http 200 https://registry.npmjs.org/connect/-/connect-2.10.1.tgz
npm http 200 https://registry.npmjs.org/stylus/-/stylus-0.32.1.tgz
npm http 200 https://registry.npmjs.org/grunt-lib-contrib
npm WARN excluding symbolic link test/fixtures/link -> default
npm http GET https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.5.3.tgz
npm http GET https://registry.npmjs.org/argparse
npm http GET https://registry.npmjs.org/esprima
npm http 200 https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.5.3.tgz
npm http 200 https://registry.npmjs.org/esprima
npm http 200 https://registry.npmjs.org/argparse
npm http GET https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz
npm http GET https://registry.npmjs.org/argparse/-/argparse-0.1.15.tgz
npm http 200 https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz
npm http 200 https://registry.npmjs.org/argparse/-/argparse-0.1.15.tgz
npm http GET https://registry.npmjs.org/mkdirp/0.3.3
npm http GET https://registry.npmjs.org/ms/0.3.0
npm http GET https://registry.npmjs.org/commander/0.6.1
npm http GET https://registry.npmjs.org/growl
npm http GET https://registry.npmjs.org/jade/0.26.3
npm http GET https://registry.npmjs.org/diff/1.0.2
npm http 200 https://registry.npmjs.org/mkdirp/0.3.3
npm http GET https://registry.npmjs.org/dateformat/1.0.2-1.2.3
npm http GET https://registry.npmjs.org/eventemitter2
npm http GET https://registry.npmjs.org/nopt
npm http GET https://registry.npmjs.org/findup-sync
npm http GET https://registry.npmjs.org/rimraf
npm http GET https://registry.npmjs.org/glob
npm http GET https://registry.npmjs.org/lodash
npm http GET https://registry.npmjs.org/hooker
npm http GET https://registry.npmjs.org/iconv-lite
npm http GET https://registry.npmjs.org/minimatch
npm http GET https://registry.npmjs.org/underscore.string
npm http GET https://registry.npmjs.org/which
npm http GET https://registry.npmjs.org/colors
npm http 200 https://registry.npmjs.org/ms/0.3.0
npm http 200 https://registry.npmjs.org/growl
npm http 200 https://registry.npmjs.org/diff/1.0.2
npm http 200 https://registry.npmjs.org/commander/0.6.1
npm http 200 https://registry.npmjs.org/jade/0.26.3
npm http GET https://registry.npmjs.org/js-yaml
npm http GET https://registry.npmjs.org/coffee-script
npm http 200 https://registry.npmjs.org/dateformat/1.0.2-1.2.3
npm http GET https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.3.tgz
npm http 200 https://registry.npmjs.org/findup-sync
npm http 200 https://registry.npmjs.org/rimraf
npm http 200 https://registry.npmjs.org/nopt
npm http 200 https://registry.npmjs.org/eventemitter2
npm http GET https://registry.npmjs.org/commander/-/commander-0.6.1.tgz
npm http 200 https://registry.npmjs.org/hooker
npm http GET https://registry.npmjs.org/growl/-/growl-1.7.0.tgz
npm http GET https://registry.npmjs.org/ms/-/ms-0.3.0.tgz
npm http GET https://registry.npmjs.org/diff/-/diff-1.0.2.tgz
npm http GET https://registry.npmjs.org/jade/-/jade-0.26.3.tgz
npm http 200 https://registry.npmjs.org/minimatch
npm http 200 https://registry.npmjs.org/iconv-lite
npm http 200 https://registry.npmjs.org/glob
npm http 200 https://registry.npmjs.org/lodash
npm http 200 https://registry.npmjs.org/underscore.string
npm http 200 https://registry.npmjs.org/which
npm http 200 https://registry.npmjs.org/colors
npm http 304 https://registry.npmjs.org/js-yaml
npm http 304 https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz
npm http GET https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.2.tgz
npm http GET https://registry.npmjs.org/rimraf/-/rimraf-2.0.3.tgz
npm http GET https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz
npm http GET https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz
npm http GET https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz
npm http GET https://registry.npmjs.org/minimatch/-/minimatch-0.2.12.tgz
npm http GET https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz
npm http GET https://registry.npmjs.org/glob/-/glob-3.1.21.tgz
npm http 200 https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.3.tgz
npm http GET https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz
npm http GET https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz
npm http GET https://registry.npmjs.org/which/-/which-1.0.5.tgz
npm http GET https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz
npm http GET https://registry.npmjs.org/colors/-/colors-0.6.2.tgz
npm http GET https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz
npm http 200 https://registry.npmjs.org/commander/-/commander-0.6.1.tgz
npm http 200 https://registry.npmjs.org/jade/-/jade-0.26.3.tgz
npm http 200 https://registry.npmjs.org/growl/-/growl-1.7.0.tgz
npm http 200 https://registry.npmjs.org/ms/-/ms-0.3.0.tgz
npm http 200 https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz
npm http 200 https://registry.npmjs.org/diff/-/diff-1.0.2.tgz
npm http 200 https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.2.tgz
npm http 200 https://registry.npmjs.org/rimraf/-/rimraf-2.0.3.tgz
npm http 200 https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz
npm http 200 https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz
npm http 200 https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz
npm http 200 https://registry.npmjs.org/minimatch/-/minimatch-0.2.12.tgz
npm http 200 https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz
npm http 200 https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz
npm http 200 https://registry.npmjs.org/glob/-/glob-3.1.21.tgz
npm http 200 https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz
npm http 200 https://registry.npmjs.org/which/-/which-1.0.5.tgz
npm http 200 https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz
npm http 200 https://registry.npmjs.org/colors/-/colors-0.6.2.tgz
npm http 200 https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz
npm http GET https://registry.npmjs.org/zlib-browserify/0.0.1
npm http 200 https://registry.npmjs.org/zlib-browserify/0.0.1
npm http GET https://registry.npmjs.org/zlib-browserify/-/zlib-browserify-0.0.1.tgz
npm http 200 https://registry.npmjs.org/zlib-browserify/-/zlib-browserify-0.0.1.tgz
npm http GET https://registry.npmjs.org/optimist
npm http GET https://registry.npmjs.org/uglify-js
npm http GET https://registry.npmjs.org/npm/1.3.4
npm http GET https://registry.npmjs.org/backbone/1.0.0
npm http GET https://registry.npmjs.org/qs/0.5.1
npm http GET https://registry.npmjs.org/rendr-handlebars/0.0.6
npm http GET https://registry.npmjs.org/validator/0.4.21
npm http GET https://registry.npmjs.org/express
npm http 200 https://registry.npmjs.org/optimist
npm http 200 https://registry.npmjs.org/rendr-handlebars/0.0.6
npm http GET https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz
npm http GET https://registry.npmjs.org/rendr-handlebars/-/rendr-handlebars-0.0.6.tgz
npm http 200 https://registry.npmjs.org/validator/0.4.21
npm http 200 https://registry.npmjs.org/uglify-js
npm http 304 https://registry.npmjs.org/express
npm http 200 https://registry.npmjs.org/qs/0.5.1
npm http 200 https://registry.npmjs.org/backbone/1.0.0
npm http 200 https://registry.npmjs.org/npm/1.3.4
npm http GET https://registry.npmjs.org/validator/-/validator-0.4.21.tgz
npm http GET https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz
npm http GET https://registry.npmjs.org/express/-/express-3.0.6.tgz
npm http GET https://registry.npmjs.org/qs/-/qs-0.5.1.tgz
npm http GET https://registry.npmjs.org/backbone/-/backbone-1.0.0.tgz
npm http GET https://registry.npmjs.org/npm/-/npm-1.3.4.tgz
npm http 200 https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz
npm http 200 https://registry.npmjs.org/rendr-handlebars/-/rendr-handlebars-0.0.6.tgz
npm http 200 https://registry.npmjs.org/qs/-/qs-0.5.1.tgz
npm http 200 https://registry.npmjs.org/backbone/-/backbone-1.0.0.tgz
npm http 200 https://registry.npmjs.org/npm/-/npm-1.3.4.tgz
npm http 200 https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz
npm http 200 https://registry.npmjs.org/validator/-/validator-0.4.21.tgz
npm http 200 https://registry.npmjs.org/express/-/express-3.0.6.tgz
npm http GET https://registry.npmjs.org/stylus
npm http 304 https://registry.npmjs.org/stylus
npm http GET https://registry.npmjs.org/stylus/-/stylus-0.31.0.tgz
npm http 200 https://registry.npmjs.org/stylus/-/stylus-0.31.0.tgz
npm ERR! Error: UNKNOWN, symlink '../coffee-script/bin/coffee'
npm ERR! If you need help, you may report this log at:
npm ERR! http://github.com/isaacs/npm/issues
npm ERR! or email it to:
npm ERR! [email protected]

npm ERR! System Linux 3.2.0-23-generic-pae
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! cwd /home/website/nodejs/rendr-try2/rendr-app-template
npm ERR! node -v v0.10.21
npm ERR! npm -v 1.3.11
npm ERR! path ../coffee-script/bin/coffee
npm ERR! code UNKNOWN
npm ERR! errno -1
npm http GET https://registry.npmjs.org/mime
npm http GET https://registry.npmjs.org/keypress
npm http 200 https://registry.npmjs.org/mime
npm http GET https://registry.npmjs.org/mime/-/mime-1.2.11.tgz
npm http 200 https://registry.npmjs.org/keypress
npm http GET https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz
npm http GET https://registry.npmjs.org/mkdirp/0.3.0
npm http GET https://registry.npmjs.org/cssom
npm http GET https://registry.npmjs.org/mkdirp
npm http 200 https://registry.npmjs.org/mime/-/mime-1.2.11.tgz
npm http 200 https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz
npm http 200 https://registry.npmjs.org/mkdirp/0.3.0
npm http GET https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz
npm http 200 https://registry.npmjs.org/mkdirp
npm http 200 https://registry.npmjs.org/cssom
npm http GET https://registry.npmjs.org/cssom/-/cssom-0.2.5.tgz
npm http 200 https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz
npm http 200 https://registry.npmjs.org/cssom/-/cssom-0.2.5.tgz
npm http GET https://registry.npmjs.org/multiparty/2.2.0
npm http GET https://registry.npmjs.org/pause/0.0.1
npm http GET https://registry.npmjs.org/bytes/0.2.0
npm http GET https://registry.npmjs.org/qs/0.6.5
npm http GET https://registry.npmjs.org/uid2/0.0.2
npm http GET https://registry.npmjs.org/raw-body/0.0.3
npm http GET https://registry.npmjs.org/negotiator/0.2.8
npm http 200 https://registry.npmjs.org/uid2/0.0.2
npm http 200 https://registry.npmjs.org/multiparty/2.2.0
npm http 200 https://registry.npmjs.org/pause/0.0.1
npm http 200 https://registry.npmjs.org/raw-body/0.0.3
npm http 200 https://registry.npmjs.org/qs/0.6.5
npm http 200 https://registry.npmjs.org/negotiator/0.2.8
npm http 200 https://registry.npmjs.org/bytes/0.2.0
npm http GET https://registry.npmjs.org/uid2/-/uid2-0.0.2.tgz
npm http GET https://registry.npmjs.org/multiparty/-/multiparty-2.2.0.tgz
npm http GET https://registry.npmjs.org/qs/-/qs-0.6.5.tgz
npm http GET https://registry.npmjs.org/pause/-/pause-0.0.1.tgz
npm http GET https://registry.npmjs.org/raw-body/-/raw-body-0.0.3.tgz
npm http GET https://registry.npmjs.org/negotiator/-/negotiator-0.2.8.tgz
npm http GET https://registry.npmjs.org/bytes/-/bytes-0.2.0.tgz
npm ERR! error rolling back Error: UNKNOWN, unlink '/home/website/nodejs/rendr-try2/rendr-app-template/node_modules/grunt/node_modules/lodash/lod
ash.js'
npm ERR! error rolling back [email protected] { [Error: UNKNOWN, unlink '/home/website/nodejs/rendr-try2/rendr-app-template/node_modules/grunt/node_mo
dules/lodash/lodash.js']
npm ERR! error rolling back errno: -1,
npm ERR! error rolling back code: 'UNKNOWN',
npm ERR! error rolling back path: '/home/website/nodejs/rendr-try2/rendr-app-template/node_modules/grunt/node_modules/lodash/lodash.js' }
npm http 200 https://registry.npmjs.org/uid2/-/uid2-0.0.2.tgz
npm http 200 https://registry.npmjs.org/qs/-/qs-0.6.5.tgz
npm http 200 https://registry.npmjs.org/multiparty/-/multiparty-2.2.0.tgz
npm http 200 https://registry.npmjs.org/negotiator/-/negotiator-0.2.8.tgz
npm http 200 https://registry.npmjs.org/bytes/-/bytes-0.2.0.tgz
npm http 200 https://registry.npmjs.org/raw-body/-/raw-body-0.0.3.tgz
npm http 200 https://registry.npmjs.org/pause/-/pause-0.0.1.tgz
npm http GET https://registry.npmjs.org/graceful-fs
npm http GET https://registry.npmjs.org/abbrev
npm http 200 https://registry.npmjs.org/graceful-fs
npm http 200 https://registry.npmjs.org/abbrev
npm http GET https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.1.14.tgz
npm http GET https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz
npm http 200 https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.1.14.tgz
npm http 200 https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz
npm http GET https://registry.npmjs.org/wordwrap
npm http 200 https://registry.npmjs.org/wordwrap
npm http GET https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
npm http 200 https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
npm http GET https://registry.npmjs.org/underscore.string
npm http 304 https://registry.npmjs.org/underscore.string
npm http GET https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz
npm http GET https://registry.npmjs.org/source-map
npm http GET https://registry.npmjs.org/async
npm http 200 https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz
npm http 304 https://registry.npmjs.org/async
npm http 200 https://registry.npmjs.org/source-map
npm http GET https://registry.npmjs.org/source-map/-/source-map-0.1.30.tgz
npm http 200 https://registry.npmjs.org/source-map/-/source-map-0.1.30.tgz
npm http GET https://registry.npmjs.org/cssom
npm http GET https://registry.npmjs.org/mkdirp
npm http 304 https://registry.npmjs.org/mkdirp
npm http 304 https://registry.npmjs.org/cssom
npm http GET https://registry.npmjs.org/amdefine
npm http 200 https://registry.npmjs.org/amdefine
npm http GET https://registry.npmjs.org/amdefine/-/amdefine-0.1.0.tgz
npm http 200 https://registry.npmjs.org/amdefine/-/amdefine-0.1.0.tgz
npm http GET https://registry.npmjs.org/readable-stream
npm http GET https://registry.npmjs.org/stream-counter
npm http 200 https://registry.npmjs.org/stream-counter
npm http GET https://registry.npmjs.org/stream-counter/-/stream-counter-0.2.0.tgz
npm http 200 https://registry.npmjs.org/readable-stream
npm http GET https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.9.tgz
npm http 200 https://registry.npmjs.org/stream-counter/-/stream-counter-0.2.0.tgz
npm http 200 https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.9.tgz
npm http GET https://registry.npmjs.org/core-util-is
npm http GET https://registry.npmjs.org/debuglog/0.0.2
npm http 200 https://registry.npmjs.org/core-util-is
npm http 200 https://registry.npmjs.org/debuglog/0.0.2
npm http GET https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.0.tgz
npm http GET https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz
npm http 200 https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.0.tgz
npm http 200 https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz
npm http GET https://registry.npmjs.org/send/0.1.0
npm http GET https://registry.npmjs.org/cookie/0.0.5
npm http GET https://registry.npmjs.org/cookie-signature/0.0.1
npm http GET https://registry.npmjs.org/buffer-crc32/0.1.1
npm http GET https://registry.npmjs.org/fresh/0.1.0
npm http GET https://registry.npmjs.org/connect/2.7.2
npm http GET https://registry.npmjs.org/commander/0.6.1
npm http GET https://registry.npmjs.org/methods/0.0.1
npm http GET https://registry.npmjs.org/range-parser/0.0.4
npm http GET https://registry.npmjs.org/mkdirp/0.3.3
npm http 200 https://registry.npmjs.org/cookie/0.0.5
npm http 200 https://registry.npmjs.org/fresh/0.1.0
npm http 200 https://registry.npmjs.org/send/0.1.0
npm http 200 https://registry.npmjs.org/buffer-crc32/0.1.1
npm http 200 https://registry.npmjs.org/cookie-signature/0.0.1
npm http GET https://registry.npmjs.org/cookie/-/cookie-0.0.5.tgz
npm http GET https://registry.npmjs.org/fresh/-/fresh-0.1.0.tgz
npm http GET https://registry.npmjs.org/send/-/send-0.1.0.tgz
npm http GET https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.1.1.tgz
npm http GET https://registry.npmjs.org/cookie-signature/-/cookie-signature-0.0.1.tgz
npm http 304 https://registry.npmjs.org/commander/0.6.1
npm http 304 https://registry.npmjs.org/methods/0.0.1
npm http 304 https://registry.npmjs.org/range-parser/0.0.4
npm http 304 https://registry.npmjs.org/mkdirp/0.3.3
npm http 200 https://registry.npmjs.org/connect/2.7.2
npm http GET https://registry.npmjs.org/connect/-/connect-2.7.2.tgz
npm http 200 https://registry.npmjs.org/cookie/-/cookie-0.0.5.tgz
npm http 200 https://registry.npmjs.org/send/-/send-0.1.0.tgz
npm http 200 https://registry.npmjs.org/fresh/-/fresh-0.1.0.tgz
npm http 200 https://registry.npmjs.org/connect/-/connect-2.7.2.tgz
npm http 200 https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.1.1.tgz
npm http 200 https://registry.npmjs.org/cookie-signature/-/cookie-signature-0.0.1.tgz
npm http GET https://registry.npmjs.org/mime/1.2.6
npm http 200 https://registry.npmjs.org/mime/1.2.6
npm http GET https://registry.npmjs.org/mime/-/mime-1.2.6.tgz
npm http 200 https://registry.npmjs.org/mime/-/mime-1.2.6.tgz
npm http GET https://registry.npmjs.org/formidable/1.0.11
npm http GET https://registry.npmjs.org/bytes/0.1.0
npm http GET https://registry.npmjs.org/pause/0.0.1
npm http 304 https://registry.npmjs.org/pause/0.0.1
npm http 200 https://registry.npmjs.org/formidable/1.0.11
npm http GET https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz
npm http 200 https://registry.npmjs.org/bytes/0.1.0
npm http GET https://registry.npmjs.org/bytes/-/bytes-0.1.0.tgz
npm http 200 https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz
npm http 200 https://registry.npmjs.org/bytes/-/bytes-0.1.0.tgz
npm ERR! Error: UNKNOWN, mkdir '/home/website/nodejs/rendr-try2/rendr-app-template/node_modules/rendr-handlebars/node_modules/rendr/node_modules/
express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename'
npm ERR! If you need help, you may report this log at:
npm ERR! http://github.com/isaacs/npm/issues
npm ERR! or email it to:
npm ERR! [email protected]

npm ERR! System Linux 3.2.0-23-generic-pae
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! cwd /home/website/nodejs/rendr-try2/rendr-app-template
npm ERR! node -v v0.10.21
npm ERR! npm -v 1.3.11
npm ERR! path /home/website/nodejs/rendr-try2/rendr-app-template/node_modules/rendr-handlebars/node_modules/rendr/node_modules/express/node_modul
es/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename
npm ERR! fstream_path /home/website/nodejs/rendr-try2/rendr-app-template/node_modules/rendr-handlebars/node_modules/rendr/node_modules/express/no
de_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md
npm ERR! fstream_type File
npm ERR! fstream_class FileWriter
npm ERR! code UNKNOWN
npm ERR! errno -1
npm ERR! fstream_stack /usr/lib/node_modules/npm/node_modules/fstream/lib/writer.js:171:23
npm ERR! fstream_stack /usr/lib/node_modules/npm/node_modules/mkdirp/index.js:37:53
npm ERR! fstream_stack Object.oncomplete (fs.js:107:15)
npm ERR! Error: EPERM, open '/home/website/nodejs/rendr-try2/rendr-app-template/node_modules/rendr-handlebars/node_modules/rendr/node_modules/npm
/node_modules/read-package-json/node_modules/normalize-package-data/test/fixtures/node-module_exist.json'
npm ERR! { [Error: EPERM, open '/home/website/nodejs/rendr-try2/rendr-app-template/node_modules/rendr-handlebars/node_modules/rendr/node_modules
/npm/node_modules/read-package-json/node_modules/normalize-package-data/test/fixtures/node-module_exist.json']
npm ERR! errno: 50,
npm ERR! code: 'EPERM',
npm ERR! path: '/home/website/nodejs/rendr-try2/rendr-app-template/node_modules/rendr-handlebars/node_modules/rendr/node_modules/npm/node_modul
es/read-package-json/node_modules/normalize-package-data/test/fixtures/node-module_exist.json' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

npm ERR! System Linux 3.2.0-23-generic-pae
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! cwd /home/website/nodejs/rendr-try2/rendr-app-template
npm ERR! node -v v0.10.21
npm ERR! npm -v 1.3.11
npm ERR! path /home/website/nodejs/rendr-try2/rendr-app-template/node_modules/rendr-handlebars/node_modules/rendr/node_modules/npm/node_modules/r
ead-package-json/node_modules/normalize-package-data/test/fixtures/node-module_exist.json
npm ERR! code EPERM
npm ERR! errno 50
npm ERR! stack Error: EPERM, open '/home/website/nodejs/rendr-try2/rendr-app-template/node_modules/rendr-handlebars/node_modules/rendr/node_modul
es/npm/node_modules/read-package-json/node_modules/normalize-package-data/test/fixtures/node-module_exist.json'
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/website/nodejs/rendr-try2/rendr-app-template/npm-debug.log
npm ERR! not ok code 0
vagrant@precise32:/home/website/nodejs/rendr-try2/rendr-app-template$

Anyone have any ideas what's going on here ?

Handlebars precompiled versioning error

I get this error when attempting to connect for the first time:

500 Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version (>= 1.0.0) or downgrade your runtime to an older version (== 1.0.0-rc.3).

Can I can resolve this without hacking about the different NPM modules? Thanks.

Injecting data coming from an asynchronous call into __layout.hbs

Is there a way to inject data from an asynchronous call into __layout.hbs? For example the data.logged_in below. Basically what I want to do is show the Login/Logout user state in the __layout.hbs so I make an asynchronous call to check if the user is logged in or not. I do this in the base view so that I have access to this.app to get the cookies info, and also so that all the views can share the data.

BaseView.postInitialize = function() {
  if (global.isServer) {
    var that = this;
    var url = 'http://localhost:5000/api/authentication/is_logged_in';
    var superagent = require('superagent');
    var http = superagent.agent();
    var handler = http.get(url);
    var request = handler.set('Cookie', this.app.req.headers.cookie); // Need to pull data from this.app
    var callback = function(res) {
      var data = JSON.parse(res.text);
      console.log(data.logged_in); // Make data.logged_in global to __layout.hbs
    };
    request.end(callback);
  }
};

does not run on Windows

Two issues (on Windows 8, x64, GitShell terminal, node v0.10.5, npm 1.2.9)

  1. 'npm install' does not complete successfully. Fails installing rendr
  2. 'grunt server' does not run bgShell:runNode - fails complaining '.' not a valid command.

Modularization of the site

Hey spike + others;

We were working off this for our mobile app. For deployment we thought it would make sense to have two modules:

  • The first module is the website itself; it would be compirsed of what is now in site/, moving all the grunt files and dependencies to the root directory.
  • The other module would be responsible for the work that 'grunt' does and it would have the first website module as a depedency

We thought that would be nice for deployment, pushing work to npm and also allowing us to use grunt for devtasks like linking githooks etc.

I am having issues doing this though, it looks like rendr.entryPath works for the server but breaks down on the client side. So far I've:

  • created a second package.json and index.js to require the site and run the start method (which is now exported)
  • updated all the gruntfile.js configs to use site/, things are mostly built in the same place.
  • Moved config to the root directory and point paths: entryPath at the site directory (using an absolute directory for now). Similar for viewsPath.
  • I've had to update rendr/shared/global.js's line to set global.rendr.entryPath = 'site/' (hardcoded)

Now clearly the last thing was just a hack and we're still running into issues and things aren't working correctly. I can give better details, but my questions are a little higher level:

Is this a wacky idea in general am I fighting against node/the framework? Or is this just not a well tested use case?

Unable to start server in Windows 7

I did the entire process correctly on my mac laptop, however when I try to follow the instructions on my windows 7 machine I get an error when running grunt. What am I doing wrong?

image

Error prevents app from starting

I keep getting the same cryptic error when trying to start the app. I've tried installing by cloning the repo, installing dependencies and running npm start as specified in the readme. I tried installing grunt globally, running index.js with nodemon or just plain node, all with the same result.

~/dev/lab/temp/rendr-app-template (master) $ npm start

> [email protected] start /Users/ng/dev/lab/temp/rendr-app-template
> DEBUG=app:* node index.js


/Users/ng/dev/lab/temp/rendr-app-template/index.js:29
  if (err) throw err;
                 ^
Error: grunt exited with code:127
    at ChildProcess.compileAssets (/Users/ng/dev/lab/temp/rendr-app-template/index.js:22:13)
    at ChildProcess.EventEmitter.emit (events.js:91:17)
    at Process._handle.onexit (child_process.js:674:10)
npm ERR! [email protected] start: `DEBUG=app:* node index.js`
npm ERR! `sh "-c" "DEBUG=app:* node index.js"` failed with 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is most likely a problem with the rendr-app-template package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     DEBUG=app:* node index.js
npm ERR! You can get their info via:
npm ERR!     npm owner ls rendr-app-template
npm ERR! There is likely additional logging output above.

npm ERR! System Darwin 11.4.2
npm ERR! command "node" "/usr/local/bin/npm" "start"
npm ERR! cwd /Users/ng/dev/lab/temp/rendr-app-template
npm ERR! node -v v0.8.2
npm ERR! npm -v 1.1.46
npm ERR! code ELIFECYCLE
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     /Users/ng/dev/lab/temp/rendr-app-template/npm-debug.log
npm ERR! not ok code 0

Grunt keeps exiting with an error code of 127. Not much other debug info available.

Here's my npm-debug.log:

0 info it worked if it ends with ok
1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose config file /Users/ng/.npmrc
5 verbose config file /usr/local/etc/npmrc
6 verbose config file /usr/local/lib/node_modules/npm/npmrc
7 verbose read json /Users/ng/dev/lab/temp/rendr-app-template/package.json
8 verbose run-script [ 'prestart', 'start', 'poststart' ]
9 info prestart [email protected]
10 info start [email protected]
11 verbose unsafe-perm in lifecycle true
12 silly exec sh "-c" "DEBUG=app:* node index.js"
13 silly sh,-c,DEBUG=app:* node index.js,/Users/ng/dev/lab/temp/rendr-app-template spawning
14 info [email protected] Failed to exec start script
15 error [email protected] start: `DEBUG=app:* node index.js`
15 error `sh "-c" "DEBUG=app:* node index.js"` failed with 1
16 error Failed at the [email protected] start script.
16 error This is most likely a problem with the rendr-app-template package,
16 error not with npm itself.
16 error Tell the author that this fails on your system:
16 error     DEBUG=app:* node index.js
16 error You can get their info via:
16 error     npm owner ls rendr-app-template
16 error There is likely additional logging output above.
17 error System Darwin 11.4.2
18 error command "node" "/usr/local/bin/npm" "start"
19 error cwd /Users/ng/dev/lab/temp/rendr-app-template
20 error node -v v0.8.2
21 error npm -v 1.1.46
22 error code ELIFECYCLE
23 verbose exit [ 1, true ]

Any idea what might be causing this?

Error: npm install rendr-app-template

npm ERR! command "C:\Program Files\nodejs\node.exe" "C:\Program Files\nod
ejs\node_modules\npm\bin\npm-cli.js" "install" "rendr-app-template"

i am working on windows 7
i try "run as administrator"
but still not work .... please help me

__layout.hbs

How are different layouts created and referenced?

Server side call

I was looking at the network requests monitoring bot on Node-inspector and Chrome debugger. It seems it makes 2 requests to server. Isn't it is delivered to client only client sync will get called?
Wanted to understand about the 2 calls to git for same service.

initialize model returns error

hey guys,

first of all: great stuff, thank you very much for opensourcing this. hope this is the right place to post this issue.

I've updated to repo's head and my initialize function in a model stopped working giving 500 TypeError: Cannot read property 'req' of undefined

the model works correctly setting default values without defining the initialize function, express starts giving errors as soon as iniitialize is defined, even if empty. any suggestion appreciated

Template precompile

Ive tried with two Mac OSX 10.8.0 & 10.8.2 to install the app, and recieved the same issue from express.

500 Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version (>= 1.0.0-rc.4).

We swap out the hack with the version listed above, in the rendr node_module package.json and then Handlbars does not get included correctly so i get this error.

Uncaught TypeError: Object #<Object> has no method 'registerHelper'

Thanks in advance

Need to add "npm install" step to README

Hi Spike,

For those who are Node noobs like me, it may be useful to add a step that indicates to run "npm install" inside the rendr-app-template folder right before running grunt server to install all the projects requirements. Also, I think a step for "npm install grunt --save-dev" is probably needed too? I had to use both of those steps. Great work btw!

Error on startup

Getting a Cannot read property 'handle' of undefined when starting. Not sure what's going on.

Running "runNode" task

Running "handlebars:compile" (handlebars) task
26 Sep 21:16:40 - [nodemon] v0.7.10
26 Sep 21:16:40 - [nodemon] to restart at any time, enter `rs`
26 Sep 21:16:40 - [nodemon] watching: /root/rendr-app-template
26 Sep 21:16:40 - [nodemon] starting `node --debug index.js`
File "app/templates/compiledTemplates.js" created.

Running "rendr_stitch:compile" (rendr_stitch) task
debugger listening on port 5858
26 Sep 21:16:40 - [nodemon] reading ignore list
File "public/mergedAssets.js" created.

Running "stylus:compile" (stylus) task

/root/rendr-app-template/node_modules/express/lib/application.js:113
  if (fn.handle && fn.set) app = fn;
        ^
TypeError: Cannot read property 'handle' of undefined
    at Function.app.use (/root/rendr-app-template/node_modules/express/lib/application.js:113:9)
    at initMiddleware (/root/rendr-app-template/index.js:27:7)
    at Object.<anonymous> (/root/rendr-app-template/index.js:68:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.