diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 770d5fa3e09791363d2fa76ea029a738fe9735a2..503bf6811394453e9e0291338a1da1cae7ccc4f8 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -137,7 +137,9 @@ window.FileList={
 
 		var download_url = null;
 		if (!param.download_url) {
-			download_url = OC.Router.generate('download', { file: $('#dir').val()+'/'+name });
+			download_url = OC.generateUrl(
+				'apps/files/download{file}',
+				{ file: $('#dir').val()+'/'+name });
 		} else {
 			download_url = param.download_url;
 		}
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 48e5771ae8a7d2369a253872beeedb0cd6d5b7ad..1186a72a44f4cab38544409f4b1c9b8998954e3d 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -783,9 +783,9 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
 
 		if ( $('#isPublic').length ) {
 			urlSpec.t = $('#dirToken').val();
-			previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec);
+			previewURL = OC.generateUrl('/publicpreview.png?') + $.param(urlSpec);
 		} else {
-			previewURL = OC.Router.generate('core_ajax_preview', urlSpec);
+			previewURL = OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
 		}
 		previewURL = previewURL.replace('(', '%28');
 		previewURL = previewURL.replace(')', '%29');
diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php
index 3469829b6f7dbc72bb34642edda9b8485ece5089..9417a6eeb899c2a96224ac879027c5590ee8acbc 100644
--- a/apps/files_sharing/appinfo/routes.php
+++ b/apps/files_sharing/appinfo/routes.php
@@ -1,4 +1,5 @@
 <?php
+/** @var $this OC_Router */
 $this->create('core_ajax_public_preview', '/publicpreview.png')->action(
 function() {
 	require_once __DIR__ . '/../ajax/publicpreview.php';
diff --git a/core/js/core.json b/core/js/core.json
index 4beab7cf796d27a0d4d8650b0aaabb0e167a664b..665e2485a9042e2a46aecda61b3f76a4d6012bc4 100644
--- a/core/js/core.json
+++ b/core/js/core.json
@@ -17,7 +17,6 @@
 		"eventsource.js",
 		"config.js",
 		"multiselect.js",
-		"router.js",
 		"oc-requesttoken.js"
 	]
 }
diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js
index 02a40c088b4f46866f0a448cdecb2b2aac69bb6e..381c42d9dbb5f816c0e0b8de992d481a603e72ce 100644
--- a/core/js/jquery.avatar.js
+++ b/core/js/jquery.avatar.js
@@ -75,31 +75,32 @@
 
 		var $div = this;
 
-		OC.Router.registerLoadedCallback(function() {
-			var url = OC.Router.generate('core_avatar_get', {user: user, size: size})+'?requesttoken='+oc_requesttoken;
-			$.get(url, function(result) {
-				if (typeof(result) === 'object') {
-					if (!hidedefault) {
-						if (result.data && result.data.displayname) {
-							$div.imageplaceholder(user, result.data.displayname);
-						} else {
-							$div.imageplaceholder(user);
-						}
+		var url = OC.generateUrl(
+			'/avatar/{user}/{size}?requesttoken={requesttoken}',
+			{user: user, size: size, requesttoken: oc_requesttoken});
+
+		$.get(url, function(result) {
+			if (typeof(result) === 'object') {
+				if (!hidedefault) {
+					if (result.data && result.data.displayname) {
+						$div.imageplaceholder(user, result.data.displayname);
 					} else {
-						$div.hide();
+						$div.imageplaceholder(user);
 					}
 				} else {
-					$div.show();
-					if (ie8fix === true) {
-						$div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">');
-					} else {
-						$div.html('<img src="'+url+'">');
-					}
+					$div.hide();
 				}
-				if(typeof callback === 'function') {
-					callback();
+			} else {
+				$div.show();
+				if (ie8fix === true) {
+					$div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">');
+				} else {
+					$div.html('<img src="'+url+'">');
 				}
-			});
+			}
+			if(typeof callback === 'function') {
+				callback();
+			}
 		});
 	};
 }(jQuery));
diff --git a/core/js/js.js b/core/js/js.js
index 21ccee0f1d54b6fc3af37d68bcc928aec75a1d16..77aadd23e03f59bd82da9e16fea5b400d8cd80a0 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -194,6 +194,30 @@ var OC={
 	linkToRemoteBase:function(service) {
 		return OC.webroot + '/remote.php/' + service;
 	},
+
+	/**
+	 * Generates the absolute url for the given relative url, which can contain parameters.
+	 *
+	 * @returns {string}
+	 * @param {string} url
+	 * @param params
+	 */
+	generateUrl: function(url, params) {
+		var _build = function (text, vars) {
+			return text.replace(/{([^{}]*)}/g,
+				function (a, b) {
+					var r = vars[b];
+					return typeof r === 'string' || typeof r === 'number' ? r : a;
+				}
+			);
+		};
+		if (url.charAt(0) !== '/') {
+			url = '/' + url;
+
+		}
+		return OC.webroot + '/index.php' + _build(url, params);
+	},
+
 	/**
 	 * @brief Creates an absolute url for remote use
 	 * @param string $service id
@@ -791,12 +815,10 @@ function initCore() {
 		if (interval < 60) {
 			interval = 60;
 		}
-		OC.Router.registerLoadedCallback(function(){
-			var url = OC.Router.generate('heartbeat');
-			setInterval(function(){
-				$.post(url);
-			}, interval * 1000);
-		});
+		var url = OC.generateUrl('/heartbeat');
+		setInterval(function(){
+			$.post(url);
+		}, interval * 1000);
 	}
 
 	// session heartbeat (defaults to enabled)
diff --git a/core/js/router.js b/core/js/router.js
deleted file mode 100644
index e764783ca84b3c16101848893fb5d208e1b608a3..0000000000000000000000000000000000000000
--- a/core/js/router.js
+++ /dev/null
@@ -1,81 +0,0 @@
-OC.router_base_url = OC.webroot + '/index.php';
-OC.Router = {
-	// register your ajax requests to load after the loading of the routes
-	// has finished. otherwise you face problems with race conditions
-	registerLoadedCallback: function(callback){
-		if (!this.routes_request){
-			return;
-		}
-		this.routes_request.done(callback);
-	},
-	routes_request: !window.TESTING && $.ajax(OC.router_base_url + '/core/routes.json', {
-		dataType: 'json',
-		success: function(jsondata) {
-			if (jsondata.status === 'success') {
-				OC.Router.routes = jsondata.data;
-			}
-		}
-	}),
-	generate:function(name, opt_params) {
-		if (!('routes' in this)) {
-			if(this.routes_request.state() != 'resolved') {
-				console.warn('To avoid race conditions, please register a callback');// wait
-			}
-		}
-		if (!(name in this.routes)) {
-			throw new Error('The route "' + name + '" does not exist.');
-		}
-		var route = this.routes[name];
-		var params = opt_params || {};
-		var unusedParams = $.extend(true, {}, params);
-		var url = '';
-		var optional = true;
-		$(route.tokens).each(function(i, token) {
-			if ('text' === token[0]) {
-				url = token[1] + url;
-				optional = false;
-
-				return;
-			}
-
-			if ('variable' === token[0]) {
-				if (false === optional || !(token[3] in route.defaults)
-					|| ((token[3] in params) && params[token[3]] != route.defaults[token[3]])) {
-				var value;
-				if (token[3] in params) {
-					value = params[token[3]];
-					delete unusedParams[token[3]];
-				} else if (token[3] in route.defaults) {
-					value = route.defaults[token[3]];
-				} else if (optional) {
-					return;
-				} else {
-					throw new Error('The route "' + name + '" requires the parameter "' + token[3] + '".');
-				}
-
-				var empty = true === value || false === value || '' === value;
-
-				if (!empty || !optional) {
-					url = token[1] + encodeURIComponent(value).replace(/%2F/g, '/') + url;
-				}
-
-				optional = false;
-				}
-
-				return;
-			}
-
-			throw new Error('The token type "' + token[0] + '" is not supported.');
-		});
-		if (url === '') {
-			url = '/';
-		}
-
-		unusedParams = $.param(unusedParams);
-		if (unusedParams.length > 0) {
-			url += '?'+unusedParams;
-		}
-
-		return OC.router_base_url + url;
-	}
-}
diff --git a/core/js/tags.js b/core/js/tags.js
index bc6d7b4e0710936ea7a560d9ee7dcc8506c99876..bc2b42bf5ff58f4dbbf5c102c7a6ecc602ec87e4 100644
--- a/core/js/tags.js
+++ b/core/js/tags.js
@@ -69,7 +69,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_ids_for_tag', {type: type});
+			url = OC.generateUrl('/tags/{type}/ids', {type: type});
 		$.getJSON(url, {tag: tag}, function(response) {
 			if(response.status === 'success') {
 				defer.resolve(response.ids);
@@ -90,7 +90,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_favorites', {type: type});
+			url = OC.generateUrl('/tags/{type}/favorites', {type: type});
 		$.getJSON(url, function(response) {
 			if(response.status === 'success') {
 				defer.resolve(response.ids);
@@ -111,7 +111,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_tags', {type: type});
+			url = OC.generateUrl('/tags/{type}', {type: type});
 		$.getJSON(url, function(response) {
 			if(response.status === 'success') {
 				defer.resolve(response.tags);
@@ -133,7 +133,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_tag', {type: type, id: id});
+			url = OC.generateUrl('/tags/{type}/tag/{id}/', {type: type, id: id});
 		$.post(url, {tag: tag}, function(response) {
 			if(response.status === 'success') {
 				defer.resolve(response);
@@ -157,7 +157,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_untag', {type: type, id: id});
+			url = OC.generateUrl('/tags/{type}/untag/{id}/', {type: type, id: id});
 		$.post(url, {tag: tag}, function(response) {
 			if(response.status === 'success') {
 				defer.resolve(response);
@@ -181,7 +181,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_favorite', {type: type, id: id});
+			url = OC.generateUrl('/tags/{type}/favorite/{id}/', {type: type, id: id});
 		$.post(url, function(response) {
 			if(response.status === 'success') {
 				defer.resolve(response);
@@ -205,7 +205,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_unfavorite', {type: type, id: id});
+			url = OC.generateUrl('/tags/{type}/unfavorite/{id}/', {type: type, id: id});
 		$.post(url, function(response) {
 			if(response.status === 'success') {
 				defer.resolve();
@@ -229,7 +229,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_add', {type: type});
+			url = OC.generateUrl('/tags/{type}/add', {type: type});
 		$.post(url,{tag:tag}, function(response) {
 			if(typeof cb == 'function') {
 				cb(response);
@@ -256,7 +256,7 @@ OC.Tags= {
 		type = type ? type : this.type;
 		var defer = $.Deferred(),
 			self = this,
-			url = OC.Router.generate('core_tags_delete', {type: type});
+			url = OC.generateUrl('/tags/{type}/delete', {type: type});
 		if(!tags || !tags.length) {
 			throw new Error(t('core', 'No tags selected for deletion.'));
 		}
diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js
index b11932405806a10aae40ca8fea84090e4e7deb34..3ed4cb6c3b4e3e91ec3374aae9e90ee6abb5f4ff 100644
--- a/core/js/tests/specHelper.js
+++ b/core/js/tests/specHelper.js
@@ -86,18 +86,9 @@ window.oc_defaults = {};
 		// make it globally available, so that other tests can define
 		// custom responses
 		window.fakeServer = fakeServer;
-
-		OC.Router.routes = [];
-		OC.Router.routes_request = {
-			state: sinon.stub().returns('resolved'),
-			done: sinon.stub()
-		};
 	});
 
 	afterEach(function() {
-		OC.Router.routes_request.state.reset();
-		OC.Router.routes_request.done.reset();
-
 		// uncomment this to log requests
 		// console.log(window.fakeServer.requests);
 		fakeServer.restore();
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 478505e928767fb7fd2aa190a76451b8b7e54848..bb43810ef164d1bfa1b4b96ecab5bc744c885064 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -179,7 +179,7 @@ describe('Core base tests', function() {
 		});
 		it('Encodes special characters', function() {
 			expect(OC.buildQueryString({
-				unicode: '汉字',
+				unicode: '汉字'
 			})).toEqual('unicode=%E6%B1%89%E5%AD%97');
 			expect(OC.buildQueryString({
 			   	b: 'spaace value',
@@ -199,22 +199,20 @@ describe('Core base tests', function() {
 				'booleantrue': true
 			})).toEqual('booleanfalse=false&booleantrue=true');
 			expect(OC.buildQueryString({
-			   	'number': 123,
+			   	'number': 123
 			})).toEqual('number=123');
 		});
 	});
 	describe('Session heartbeat', function() {
 		var clock,
 			oldConfig,
-			loadedStub,
 			routeStub,
 			counter;
 
 		beforeEach(function() {
 			clock = sinon.useFakeTimers();
 			oldConfig = window.oc_config;
-			loadedStub = sinon.stub(OC.Router, 'registerLoadedCallback');
-			routeStub = sinon.stub(OC.Router, 'generate').returns('/heartbeat');
+			routeStub = sinon.stub(OC, 'generateUrl').returns('/heartbeat');
 			counter = 0;
 
 			fakeServer.autoRespond = true;
@@ -227,7 +225,6 @@ describe('Core base tests', function() {
 		afterEach(function() {
 			clock.restore();
 			window.oc_config = oldConfig;
-			loadedStub.restore();
 			routeStub.restore();
 		});
 		it('sends heartbeat half the session lifetime when heartbeat enabled', function() {
@@ -236,9 +233,7 @@ describe('Core base tests', function() {
 				session_lifetime: 300
 			};
 			window.initCore();
-			expect(loadedStub.calledOnce).toEqual(true);
-			loadedStub.yield();
-			expect(routeStub.calledWith('heartbeat')).toEqual(true);
+			expect(routeStub.calledWith('/heartbeat')).toEqual(true);
 
 			expect(counter).toEqual(0);
 
@@ -264,7 +259,6 @@ describe('Core base tests', function() {
 				session_lifetime: 300
 			};
 			window.initCore();
-			expect(loadedStub.notCalled).toEqual(true);
 			expect(routeStub.notCalled).toEqual(true);
 
 			expect(counter).toEqual(0);
diff --git a/core/routes.php b/core/routes.php
index aea788bdc6b1788c0262601c0698dc8534aa4ec7..76cf03c36733404d6b2d32c7a4c0db559ad0047b 100644
--- a/core/routes.php
+++ b/core/routes.php
@@ -65,8 +65,6 @@ $this->create('core_tags_delete', '/tags/{type}/delete')
 $this->create('js_config', '/core/js/oc.js')
 	->actionInclude('core/js/config.php');
 // Routing
-$this->create('core_ajax_routes', '/core/routes.json')
-	->action('OC_Router', 'JSRoutes');
 $this->create('core_ajax_preview', '/core/preview.png')
 	->actionInclude('core/ajax/preview.php');
 $this->create('core_lostpassword_index', '/lostpassword/')
diff --git a/lib/base.php b/lib/base.php
index 351b91b7dfa2d145fdffbb364a2785e9710db068..a44db8fd4db136e16b1899b058079391484ec588 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -316,7 +316,6 @@ class OC {
 		OC_Util::addScript("config");
 		//OC_Util::addScript( "multiselect" );
 		OC_Util::addScript('search', 'result');
-		OC_Util::addScript('router');
 		OC_Util::addScript("oc-requesttoken");
 
 		// avatars
diff --git a/lib/private/router.php b/lib/private/router.php
index 19c1e4473ecaeccc560ca46df5212292dd779a4c..918e3b13206d3236ff04b624158089aa299217ed 100644
--- a/lib/private/router.php
+++ b/lib/private/router.php
@@ -158,28 +158,4 @@ class OC_Router {
 		return $this->getGenerator()->generate($name, $parameters, $absolute);
 	}
 
-	/**
-	 * Generate JSON response for routing in javascript
-	 */
-	public static function JSRoutes()
-	{
-		$router = OC::getRouter();
-
-		$etag = $router->getCacheKey();
-		OC_Response::enableCaching();
-		OC_Response::setETagHeader($etag);
-
-		$root = $router->getCollection('root');
-		$routes = array();
-		foreach($root->all() as $name => $route) {
-			$compiled_route = $route->compile();
-			$defaults = $route->getDefaults();
-			unset($defaults['action']);
-			$routes[$name] = array(
-				'tokens' => $compiled_route->getTokens(),
-				'defaults' => $defaults,
-			);
-		}
-		OCP\JSON::success ( array( 'data' => $routes ) );
-	}
 }
diff --git a/settings/js/admin.js b/settings/js/admin.js
index 684822f18342aa892b18cab448ca0f544c592619..c04c0505deb3d602f91680aa81e838e6d41424cd 100644
--- a/settings/js/admin.js
+++ b/settings/js/admin.js
@@ -64,15 +64,15 @@ $(document).ready(function(){
 	$('#mail_settings').change(function(){
 		OC.msg.startSaving('#mail_settings_msg');
 		var post = $( "#mail_settings" ).serialize();
-		$.post(OC.Router.generate('settings_mail_settings'), post, function(data){
-			OC.msg.finishedSaving('#mail_settings_msg', data);
+		$.post(OC.generateUrl('/settings/admin/mailsettings'), post, function(data){
+			OC.msg.finishedSaving('#mail_settings .msg', data);
 		});
 	});
 
 	$('#sendtestemail').click(function(){
 		OC.msg.startAction('#sendtestmail_msg', t('settings', 'Sending...'));
 		var post = $( "#sendtestemail" ).serialize();
-		$.post(OC.Router.generate('settings_admin_mail_test'), post, function(data){
+		$.post(OC.generateUrl('/settings/admin/mailtest'), post, function(data){
 			OC.msg.finishedAction('#sendtestmail_msg', data);
 		});
 	});
diff --git a/settings/js/personal.js b/settings/js/personal.js
index 98bfe7132d488014ee2583a855edf5370ed6347e..7a4257f1c973002aea90eb2815383b3003f45a25 100644
--- a/settings/js/personal.js
+++ b/settings/js/personal.js
@@ -67,7 +67,7 @@ function showAvatarCropper() {
 	$cropper.prepend("<img>");
 	$cropperImage = $('#cropper img');
 
-	$cropperImage.attr('src', OC.Router.generate('core_avatar_get_tmp')+'?requesttoken='+oc_requesttoken+'#'+Math.floor(Math.random()*1000));
+	$cropperImage.attr('src', OC.generateUrl('/avatar/tmp')+'?requesttoken='+oc_requesttoken+'#'+Math.floor(Math.random()*1000));
 
 	// Looks weird, but on('load', ...) doesn't work in IE8
 	$cropperImage.ready(function(){
@@ -95,7 +95,7 @@ function sendCropData() {
 		w: cropperdata.w,
 		h: cropperdata.h
 	};
-	$.post(OC.Router.generate('core_avatar_post_cropped'), {crop: data}, avatarResponseHandler);
+	$.post(OC.generateUrl('/avatar/cropped'), {crop: data}, avatarResponseHandler);
 }
 
 function saveCoords(c) {
@@ -132,7 +132,7 @@ $(document).ready(function(){
 			$('#passwordchanged').hide();
 			$('#passworderror').hide();
 			// Ajax foo
-			$.post(OC.Router.generate('settings_personal_changepassword'), post, function(data){
+			$.post(OC.generateUrl('/settings/personal/changepassword'), post, function(data){
 				if( data.status === "success" ){
 					$('#pass1').val('');
 					$('#pass2').val('');
@@ -243,7 +243,7 @@ $(document).ready(function(){
 		OC.dialogs.filepicker(
 			t('settings', "Select a profile picture"),
 			function(path){
-				$.post(OC.Router.generate('core_avatar_post'), {path: path}, avatarResponseHandler);
+				$.post(OC.generateUrl('/avatar/'), {path: path}, avatarResponseHandler);
 			},
 			false,
 			["image/png", "image/jpeg"]
@@ -253,7 +253,7 @@ $(document).ready(function(){
 	$('#removeavatar').click(function(){
 		$.ajax({
 			type:	'DELETE',
-			url:	OC.Router.generate('core_avatar_delete'),
+			url:	OC.generateUrl('/avatar/'),
 			success: function(msg) {
 				updateAvatar(true);
 			}
diff --git a/settings/js/users.js b/settings/js/users.js
index 160d0a8d9d2891a68614824964299d01d2183e9a..284976d3bad565c57c3d464b466a2381d18e88e2 100644
--- a/settings/js/users.js
+++ b/settings/js/users.js
@@ -225,7 +225,8 @@ var UserList = {
 		}
 		$('table+.loading').css('visibility', 'visible');
 		UserList.updating = true;
-		$.get(OC.Router.generate('settings_ajax_userlist', { offset: UserList.offset, limit: UserList.usersToLoad }), function (result) {
+		var query = $.param({ offset: UserList.offset, limit: UserList.usersToLoad });
+		$.get(OC.generateUrl('/settings/ajax/userlist') + query, function (result) {
 			var loadedUsers = 0;
 			var trs = [];
 			if (result.status === 'success') {
@@ -371,9 +372,7 @@ $(document).ready(function () {
 
 	UserList.doSort();
 	UserList.availableGroups = $('#content table').data('groups');
-	OC.Router.registerLoadedCallback(function() {
-		$(window).scroll(function(e) {UserList._onScroll(e);});
-	});
+	$(window).scroll(function(e) {UserList._onScroll(e);});
 	$('table').after($('<div class="loading" style="height: 200px; visibility: hidden;"></div>'));
 
 	$('select[multiple]').each(function (index, element) {
@@ -401,7 +400,7 @@ $(document).ready(function () {
 				if ($(this).val().length > 0) {
 					var recoveryPasswordVal = $('input:password[id="recoveryPassword"]').val();
 					$.post(
-						OC.Router.generate('settings_users_changepassword'),
+						OC.generateUrl('/settings/users/changepassword'),
 						{username: uid, password: $(this).val(), recoveryPassword: recoveryPasswordVal},
 						function (result) {
 							if (result.status != 'success') {
diff --git a/settings/routes.php b/settings/routes.php
index a0d54dea1e7df581a49508fe974800f9cf2bc4f7..6954bd3823d68573c8249a3b096ea110c8301dad 100644
--- a/settings/routes.php
+++ b/settings/routes.php
@@ -6,6 +6,8 @@
  * See the COPYING-README file.
  */
 
+/** @var $this OC_Router */
+
 // Settings pages
 $this->create('settings_help', '/settings/help')
 	->actionInclude('settings/help.php');