yolo-server

Webframework that powers Heythere

npm install yolo-server
107 downloads in the last month

NPM version

Yolo

Yolo is MVC webframework written in Nodejs heavily inspired by ruby on rails. It powers our Heythere servers.

Install

Yolo requires nodejs, couchdb and redis to run

$ npm install yolo-server

Scaffolding

Scaffolding for app structure, models and controllers is available via the yolo-cli.

Start

Your app needs a special structure in order to get yolo running for you:

app/
    models/
    controllers/
    views/
    public/
config/
    production.js
    development.js
    routes.js

Require yolo where ever you want and pass the those folders to the run method like so:

var Yolo = require('yolo-server'),
    server = new Yolo();

server.run({
    app : 'app/',
    config : 'config/'
});

After calling run Yolo will boot up and look up all models files in /app/models and all controllers in /app/controllers. It will bind all routes configured in the /config/routes.js file for you. Be Aware that Yolo can be used in libary fashion but its a framework and it will register a global variable named "Yolo".

Models

Yolo.Model is basiclly a Backbone.Model extended with validation and a couchdb layer. Models go into app/models and are loaded automaticlly if Yolo boots. Note for now we only support couchdb as database.

You define a model by extending the Yolo.Model:

module.exports = Yolo.Model.extend({         
    //…
});

Attributes

You can define attributes for each model with default values and validation rules:

attributes : {
        firstName : {
            required : true
        },
        lastName : {
            required : true,
        },
        email : {
            pattern : 'email',
        },
        password : {
            required : true,
            minLength : 5,
            sanitize : false
        },
        bio : {
            required : false,
            maxLength : 180
        },
        lastLogin : {
            "default" : new Date()
        },
        friends : {
            "default" : [],
        }
    }

Default values will be set if the attribute is not set with a value and validators will be checked before the model is saved to db or manual via .isValid().

Full list of available validations: https://github.com/thedersen/backbone.validation#required

Views

Views are the couchdb way to query the database. Views consists of a map and a reduce function. However, views for each attribute will be autogenerated while booting. For example if your model has a attribute firstName we generate Model.findByFirstName for you. You can define additional views with the 'views' property which will be callable after booting:

views : {
    myCustomView : {
        map : function(doc){
            // for eg emit(doc)
        },
        reduce : function(){

        }
    }
}

This view would then be callabble via Model.myCustomView. The views will be saved as design document to couchdb.

Working with Models

get

Use Model.get(key) to get attributes from a model:

var user = new User();
user.get('firstName');

set

Use Model.set(key, value) or Model.set({ key1: value1}) to set attributes to the model:

var user = new User();
user.set('firstName');

If you initialize a new model you can pass an object of keys and values which will be set, to the constructor:

var user = new User({
    name : params.name,
    email : params.email
});
user.get('name');

save

Save a model with save(options) to the database like so:

var user = new User({
    name : params.name,
    email : params.email
});

user.save({
    success : function(){
        console.log("saved");
    },
    error : function(){
        console.log("save failed");
    }
});

Note: Only valid models will be saved to database. You should call Model.isValid() before to check that.

isValid

To check if a model is valid:

if( ! user.isValid() ){
    console.log(model.validationError)
}

attach(name, mimeType, buffer)

You can attach files to models which will be stored as attachments to couchdb via:

user.attach('profile', 'image/jpeg', imgBuffer);

After saving this to database you can get those attachments, for example in a template via:

user.attachments('profile').url

Controllers

Controllers take the main part in handling incoming requests and processing them.

A controller consists of a group of methods which handle one type of request defined in the route. Example:

module.exports = Yolo.Controller.extend({
    index : function(params){
        this.renderHTML("dashboard/index", {user : user });
    }
});

The params object passed to each method contains every parameter that might be passed to the server. In the methods you have access to the following methods:

this.renderHTML(path, options = {})

Renders and returns a Html Template at path. Everything into the options object will be available as variable in the template.

this.html(path, options {});

Shortcut for this.renderHTML. This Method is chainable.

this.renderJSON(data = {})

Returns a JSON Object containing the options.

this.json(data = {})

Shortcut for this.renderJSON. This Method is chainable.

this.status(code)

Sets the HTTP Status for that request. For Exmaple this.status(200). This Method is chainable.

this.redirect(path)

Redirects the Request to path

this.error(code [, message])

Returns an http error with the given code and optional with the message.

this.authorize(data = {})

authorizes/logins the request. data will be saved associated with the session.

this.deAuthorize(cb)

deAuthorizes and destroys the session and deletes the associated data. cb gets called after the destory has finished.

Routes

The routes file in the config directory contains all the individual routes to the controllers. A route consists of a key and a value. The key is the string we pass as "path" variable to express the path can also contain dynamic parts - read more about more here http://expressjs.com/api.html#app.VERB .

The value is either a object or an array of objects if the path should match different http methods.

Example:

"user/:id" : {     
    //routes to the controller named 'User' and the method named 'set'
    to : 'User.set',

    //the http method the route should match. can be either get, post, put or delete
    via : 'post',

    //set false if the request dont have to be authorized
    authorized : false
}

You can even match two routes to the same path but with different http methods like so:

'user/register' : [{
    to : 'Users.registerForm',
    via : 'get',
},
{
    to : 'Users.register',
    via : 'post',

}]

Note: Each route will be checked while booting Yolo if the to parameters matches a controller.

Templates

We use the ejs Template Engine extend with ejs-locals. Ejs lets you write javascript code into Templates like so:

<% if (currentUser) { %>
    <h2><%= currentUser.get("name") %></h2>
<% } %>

Unbuffered code for conditionals etc <% code %> Escapes html by default with <%= code %> Unescaped buffering with <%- code %>

Documentation can be found here: https://github.com/visionmedia/ejs and here: https://github.com/publicclass/express-partials

npm loves you