Skip to content
This repository
Browse code

Add Ni.addRoute(source, dest [, method]);

  • Loading branch information...
commit 015e664300c4c1962930708c98c98088abc86dbc 1 parent da1d014
Moritz Peters authored November 30, 2010

Showing 1 changed file with 77 additions and 2 deletions. Show diff stats Hide diff stats

  1. 79  lib/ni.js
79  lib/ni.js
@@ -60,6 +60,9 @@ var Ni = function() {
60 60
     // default view directory name
61 61
     this.config('view_dir', 'views');
62 62
     
  63
+    // default view directory name
  64
+    this.config('custom_routes', []);
  65
+    
63 66
     /*
64 67
      *  Loads controllers, models, views, templates and helpers from the root
65 68
      *  directory, and makes them all available to the Ni object.
@@ -105,11 +108,15 @@ var Ni = function() {
105 108
     this.router = function(req, res, next) {
106 109
 
107 110
         var parsedUrl = require('url').parse(req.url, true),
108  
-        pathArr = parsedUrl.pathname.split('/'),
109  
-        args = pathArr.slice(3), 
  111
+        pathArr,
  112
+        args, 
110 113
         controller,
111 114
         fn;
112 115
         
  116
+        parsedUrl = Ni.checkCustomRoutes(parsedUrl.pathname, req.method);
  117
+        pathArr = parsedUrl.split('/');
  118
+        args = pathArr.slice(3);
  119
+        
113 120
         res.Ni = { view: Ni.config('automatic_views') };
114 121
         
115 122
         args.unshift(next);
@@ -169,6 +176,74 @@ var Ni = function() {
169 176
 
170 177
     }
171 178
     
  179
+    /*
  180
+     *  Add a custom route with a source (can be string, regex or function) and destination (string).
  181
+     *
  182
+     *  If a route matches, the path is rewritten to the specified destination.
  183
+     *
  184
+     *  A string route matches if it is exactly the same as the path. It rewrites to exactly the given destination.
  185
+     *  A regex route matches if it matches the path. It rewrites to path.replace(source, destination).
  186
+     *  A function matches if - given the path and custom route object - it returns a non-falsy value. It rewrites to the return of the function if that is a string or to the given destination.
  187
+     */
  188
+    this.addRoute = function (src, dest, method) {
  189
+        if (arguments.length < 2) {
  190
+            throw new Error('Ni.addRoute expects 2 arguments - '+arguments.length+' given.');
  191
+        }
  192
+        var routes = Ni.config('custom_routes') || [];
  193
+        routes.push({
  194
+            src: src,
  195
+            dest: dest,
  196
+            method: method || false
  197
+        });
  198
+        Ni.config('custom_routes', routes);
  199
+    }
  200
+    
  201
+    /*
  202
+     *  Checks the given url for the first matching custom route.
  203
+     */
  204
+    this.checkCustomRoutes = function (path, method) {
  205
+        var routes = Ni.config('custom_routes');
  206
+        if (!Array.isArray(routes) || routes.length === 0)
  207
+            return path;
  208
+        for (var i = 0, len = routes.length; i < len; i++) {
  209
+            var route = routes[i]
  210
+            , type = typeof(route.src),
  211
+            methodMatch = !route.method; // if no method is specified in the route, automatically set to matched
  212
+	        
  213
+	        if (!methodMatch && Array.isArray(route.method)) {
  214
+	            for (var n = 0, lenn = route.method.length; n < lenn; n++) {
  215
+	                if (route.method[n].toUpperCase() === method)
  216
+	                    methodMatch = true; 
  217
+	            }
  218
+	        } else if (!methodMatch) {
  219
+	            methodMatch = route.method === method;
  220
+	        }
  221
+            if (methodMatch && type !== 'undefined') {
  222
+                switch(type) {
  223
+                    case 'string':
  224
+                        if (path === route.src) {
  225
+                            return route.dest;
  226
+                        }
  227
+                    break;
  228
+                    case 'function':
  229
+                        if (typeof(route.src.exec) !== 'undefined') {
  230
+                            // regex
  231
+                            if (route.src.exec(path)) {
  232
+                                return path.replace(route.src, route.dest);
  233
+                            }
  234
+                        } else {
  235
+                            // function
  236
+                            var result = route.src(path, route);
  237
+                            if (result) {
  238
+                                return typeof(result) === 'string' ? result : route.dest;
  239
+                            }
  240
+                        }
  241
+                }
  242
+            }
  243
+        }
  244
+        return path;
  245
+    }
  246
+    
172 247
     this.renderView = function (renderer) {
173 248
 
174 249
         if (typeof(renderer) === 'function') {

0 notes on commit 015e664

Please sign in to comment.
Something went wrong with that request. Please try again.