routes-framework

1.1.114 • Public • Published

Routes Framework

Provides:

  • Framework for structuring file system.
  • Unified development in client and server scripts.
  • Modular node based development with separate runtime contexts.
  • Secure public file serving through rewritten url scheme.
  • Single page web apps.
  • Localization system.
  • Web page transitions.
  • Asynchronous resource loading.
  • Resource caching and compilation.
  • SASS built in.

Installation

In order for Routes to run in development mode you need to have the Routes CLI installed on your computer. You can then initialize Routes in your project directory. When your project is running in development mode the project will auto recompile with every new request.

npm install routes-cli -g
routes init

To install Routes Framework in an existing Routes project run:

npm install routes-framework --save

To run your project in development mode:

routes develop

Read the Routes CLI documentation for more information on CLI functions.

File System

nodes    # Stores all nodes
    node 	
        public
            assets      # Node public assets
            cache       # Node public caches
        private
            assets      # Node private assets
            cache       # Node private caches
        translations
            en-US.json  # Node translation file
            ...
        client.js       # Node client controller
        server.js       # Node server controller
        view.html       # Node view
        style.scss      # Node stylesheet
        compile.js      # Node compiler controller (WIP)
    node
    node
    ...
public
    assets      # Global public assets
    cache       # Global private caches
private			
    assets      # Global private assets
    cache       # Global private caches
translations    # Global translations
    en-US.json  # Global translation file
    ...
index.js        # App entry point
main.js         # App controller
compile.js      # Compiler controller
info.json       # App info
package.json    # NPM Package

Usage

When a new request is made to a Routes app the url of the request is mapped as a pathway through your graph tree. The developer can listen for new requests using the Routes.on("METHOD", callback); in the main.js file to run logic and define a base node for the request to route from.

// Request url: "https://training.mysite.com/tutorials/beginner"
Routes.on("GET", function(data, get){
    var subdomain = data.request.subdomains[0];

    switch(subdomain){
        case "training":
            get("Training");
            break;
        default:
            get("Website");
            break;
    }
});

The above example will start routing from a node named Training on the file system. In Training's info.json file you would find a connections object linking the slug tutorials to another node on the file system, for this example lets call that node training_tutorials. In training_tutorials's info.json you could find a key called variables set to 1, this would tell Routes to map the next slug in the url as a variable for the node. In this example training_tutorials would recieve 1 variable from the url called beginner.

All these mappings and options are defined in each node's info.json file. These can edited manually, via the Routes CLI or from the Routes UI application.

Runtime

Routes follows the same initialization pattern with nearly identical clases for new requests coming into the server and when the Routes framework is initialized on the client's device.

Request

This provides unified development in client and server scripts. Each Node runs in it's own context on the server and client. Using events such as load and unload developers can control their scripts per node.

In the following example, lets assume are currently looking at the training_tutorials node mentioned in our previous example. When the node is loaded we want to make a request to an api to get a list of training videos.

// The "this" variable refers to the current node instance.

this.on("load", function(done){
    // Because we told this node to recieve 1 variable from url
    // we can now access the variables from the variables object
    // on the current instance.
    var type = this.variables[0];

    $.post( "/api/getTrainingVideos", {
        type : type
    }, function(data){
        $(".result").html(data);
    });
});

The great part about Routes is that this code can run in your node's server.js or client.js identically, assuming you are using jquery on either one.

Template Engine

Routes uses of a custom built simple to use templating engine while compiling caches and rendering html. The templating engine is used during 2 separate passes; the compiler pass and the runtime pass.

The template engine functions similar to php. You can use this to run any javascript code, do loops, logic and write content to the document. The context of any tag is always the current node.

Compiler Pass <$ ... $>

During compilation compiler tags can be used in any node's view.html, client.js, server.js and style.scss to perform logic and write content to the cached document. This is great for hard coding translations into your document. Routes' translation system will write a version of each file for every language specified in your project's info.json.

<body>
    <div>
        <$- this.translate('help_prompt'); $>
    </div>
</body>

Using a "-" after any tags delimiter will automatically output the result of that tag, the equivilant can be done with the echo function.

<body>
    <div>
        <$ echo(this.translate('help_prompt')); $>

        <$ for(var i=1; i<=5; i++){ $>
            Count: <$- i; $><br/>
        <$ } $>

        <!-- The above loop would compile to the following -->
        Do you need help?

        Count: 1<br/>
        Count: 2<br/>
        Count: 3<br/>
        Count: 4<br/>
        Count: 5<br/>
    </div>
</body>

Runtime Pass <% ... %>

Runtime tags function identically to compiler tags but can only be used in a node's view.html. Runtime tags are compiled to the document when a node is rendered during a request.

It's good to notice that view.html files are compiled to view.js in the cache directory. Routes precompiles runtime tags during compilation to prevent unnessesary strain on a production server.

In this example we are assuming that the developer has gotten a user's details in the server.js file and is storing it in the node's data object. The node's data object has some special functionality which you can see in the Node class documentation.

<%
    var moment = require(moment);
%>
<body>
    <div>
        Welcome <%- this.data.first_name; %> to our website!
        You were born <%- moment(this.data.birthday).fromNow(); %>.
    </div>
</body>

Classes

EventEmitter

All classes inherit the Routes EventEmitter class, which provides a dynamic and standardized event system on the client and server. All methods support supplying single, multiple and namespaced events as arguments.

this._id

A unique identified for the object. Useful in creating event names that don't clash.

this.on( event string , callback([arg1, arg2, ...], event) function )

Attach an event listener to the object and pass optional arguments to the callback. The event name can also contain a namespace specified by a "." character. this.on("event.namespace", function(){});

this.once( event string , callback([arg1, arg2, ...], event) function )

Functions identically to the on method but the event will only fire once and will be removed. this.on("event.namespace, event2", function(){});

this.off( event string )

Removes an event listener for the specified event. The event name can also contain a namespace specified by a "." character. this.off("event1");

this.fire( event string [, arg1, arg2, ...] )

Fires an event. You can pass optional arguments to the callback. If a namespace is passed to the event name only the event with the namespace will be fired, otherwise all events regardless of namespace will be fired. this.fire("event.namespace");

this.fireAsync( event string [, arg1, arg2, ...], callback(error, results) function )

Fires events asynchronously.

this.on("event.namespace2", function([arg1, arg2, ...,] callback, event){
    ...
    callback([error, result]);
});

this.on("event.namespace", function([arg1, arg2, ...,] callback, event){
    ...
    callback([error, result]);
});

this.fireAsync("event", function(){
    // This function is fired when all events have called the callback or
    // when one calls with an error.
});

this.hasEvents( event string )

Returns true or false if the object has any events. This also supports namespaces.

this.getEvents( event string )

Returns an array of events.

event

The event object:

{
    name : "event",
    namespace : "namespace",
    once : true || false,
    remove : function(){...},
    callback : function(){...}
}

Handler

Used to initiate the route and stores valuable information such as base router and request details. Handlers are only available during runtime.

this.router

The base router for the request.

this.request Server only

The request object from express.

this.response Server only

The response object from express.

this.head Server only

An object used to render head information during render. See Node.getHead();

this.foot Server only

An object used to render foot information during render. See Node.getFoot();

Router

Stores a route of Nodes and can be rerouted. Routers are only available during runtime.

this.path

Current request's url path with query strings removed

this.query

Current request's query string parsed as an object

this.base

Current Router's base node.

this.load( callback function )

Used to load the Router.

this.unload( callback function )

Used to unload the Router.

this.reroute( options object ) Currently client only, server implementation planned.

Used to reroute the current state of the Router.

options : {
    url    : "/tutorials/advanced",
    ready  : function(){...}
    done   : function(){...}
}

this.pushState( url string ) Client only

Push a history state onto the Router.

this.replaceState( url string ) Client only

Replace the current history state on the Router.

this.back() Client only

Go to the previous history state.

this.forward() Client only

Go to the next history state.

this.clearHistory() Client only

Clears all the history from the Router.

Node

Stores the information about the Node and is the context of all scripts. The Nodes are where majority of a developers time is spent. Nodes are used during compilation and runtime.

this.name

Current Node's name.

this.info

Current Node's info.json file.

this.language

Current Node's language.

this.index

Current Node's index in the Router.

this.assets

Assets for the current Node's language; view.html, client.js, server.js, style.css

this.data Runtime only

The data object is json data that is syncronized between client and server. Any json data you set in server.js for the Node will also appear in data in client.js.

this.temp Runtime, server only

Temporary unsyncronized data container.

this.directory Compiler, runtime server only

The file system directory of the current Node.

this.handler Runtime only

The Handler for the current request.

this.parent Runtime only

Current Node's parent. This could be either another Node or Router.

this.router Runtime only

Current Node's Router.

this.includes Runtime only

Current Node's included Nodes and Routers

this.translations Compiler only

Stores all the Nodes translations for the current language being compiled.

this.url( asset string , options object )

Returns a mapped url to an asset in the Node's public assets directory.

options : {
    global : true | false // Return the url to an asset in the global public assets folder.
}

this.path( asset string , options object ) Compiler, runtime server only.

Returns the absolute path to an asset in the Node's public assets directory.

options : {
    global : true || false // Return the absolute path to an asset in the global public assets folder.
    private : true || false // Return the path to the asset in the private folder.
}

this.translate( key string ) Compiler only

Returns the translation for the value matching the key in the translation json file. If no translation is matched the global translation file will be searched. If no translation is found the key will be returned.

this.load() Runtime only

Loads the node.

this.unload() Runtime only

Unloads the node.

this.render() Runtime only

Renders the node as a string.

this.next() Runtime only

Returns the next node in the Router.

this.prev() Runtime only

Returns the previous node in the Router.

this.route() Runtime, server only

This function is only used during runtime and thus can only be used in the view.html. It is the most important function in Routes as it tells Routes where to insert any sub routes into the final rendered document. The result should be returned or echoed out.

<body>
    <%- this.route(); %>
</body>

this.getHead() Runtime, server only

Returns all the head elements from the handler as a string. It's important to call this once in the <head><%- this.getHead(); %></head> of your document to load the base node and Routes stylesheets in the final rendered document. You can add your own head items such as meta data to the head object on the handler.

this.handler.head["og:title"] = '<meta property="og:title" content="My Routes Website" />';

this.getFoot() Runtime, server only

Similarly to getHead it returns all the foot elements from the handler as a string. It's important to call this once at the bottom of your document to load the Routes client side framework in the final rendered document.

<head>
    ...
    <%- this.getHead(); %>
</head>
<body>
    ...
    <%- this.getFoot(); %>
</body>

this.get( options object , callback function ) Runtime only

Gets a Node or Router Currenly server only, client implementation planned. The fetched Node or Router is returned as the second argument in the callback.

options : {
    name    : "tutorial_item_template",
    url     : "" // If a url is given this will cause get to return a Router.
}

this.include( options object , callback function ) Runtime, server only

Functions identical to get but will add the instance to the Nodes includes object. Any instances of Node or Router in the includes object will be loaded on the client side.

options : {
    name    : "tutorial_item_template",
    url     : "" // If a url is given this will cause get to return a Router.
}

On the server Nodes and Routers fetched using get or include can be echoed directly to the document in view.html.

<body>
    <%- this.get({
        name : "tutorial_item_template"
    }); %>

    <%- this.includes["module_help"]; %>
</body>

Node Events

load Asynchronous

unload Asynchronous

in Asynchronous

out Asynchronous

render Synchronous

update Synchronous

Readme

Keywords

none

Package Sidebar

Install

npm i routes-framework

Weekly Downloads

127

Version

1.1.114

License

ISC

Last publish

Collaborators

  • routes.rocks