/* appjet:version 0.1 */ /* appjet:library */ // Copyright (c) 2009, Herbert Vojčík // Licensed by MIT license (http://www.opensource.org/licenses/mit-license.php) /** Decoded segments of full path */ request.fullPathSegments = request.path.split('/').map(decodeURIComponent); /** Decoded full path */ request.fullPath = request.fullPathSegments.join('/'); /**@ignore*/ request.fullPathSegments.of = request.fullPath; /** *

Enhanced dispatcher function. Dispatches according to request.fullPath. Allows for:

* */ function dispatchPlus(arg1, arg2, etc) { _rejuvenateFullPathSegments(); var selectorSegments = request.fullPathSegments.map(function(x) { return [x.replace(/[\W]/g,'$$'), "_"]; }); selectorSegments.push([selectorSegments.pop()[0] || "main"]); var handler, handlerSegments, selector = arguments.callee[request.method] || request.method.toLowerCase(); selectorSegments.forEach(function(segment, index) { selector += segment.join(''); var candidate = appjet._internal.global[selector]; if (typeof candidate === "function") { handler = candidate; handlerSegments = index + 1; } }); if (handler) { request.pagePathSegments = request.fullPathSegments.slice(0, handlerSegments); request.pathTailSegments = request.fullPathSegments.slice(handlerSegments); request.pagePath = request.pagePathSegments.join('/'); request.pathTail = request.fullPath.substring(request.pagePath.length); } (handler || arguments.callee.f404).apply(null, arguments); } /** The 404 (page not found) handler. You can replace it with your own. */ dispatchPlus.f404 = function() { response.setStatusCode(404); printp("Path not found: ", request.fullPath); print(request); response.stop(); }; /** The prefix for GET method dispatcher functions. Default is "get", you can change it. */ dispatchPlus.GET = "get"; /** The prefix for HEAD method dispatcher functions. Default is "get", you can change it. */ dispatchPlus.HEAD = "get"; /** The prefix for POST method dispatcher functions. Default is "post", you can change it. */ dispatchPlus.POST = "post"; /** The prefix for CRON method dispatcher functions. Default is "cron", you can change it. */ dispatchPlus.CRON = "cron"; function _rejuvenateFullPathSegments() { if (request.fullPathSegments.of === request.fullPath) return; request.fullPathSegments = request.fullPath.split('/'); request.fullPathSegments.of = request.fullPath; } /* appjet:server */ import("lib-app/dispatch-plus"); /**@ignore*/ function printRequest() { printp({ pagePath: request.pagePath, pagePathSegments: request.pagePathSegments, fullPath: request.fullPath, fullPathSegments: request.fullPathSegments, pathTail: request.pathTail, pathTailSegments: request.pathTailSegments }); }; /**@ignore*/ function get_(arg) { printp("Serviced by ", CODE(arguments.callee)); printp("Try these links:"); print(UL( LI(A({href:"/long/path/here.2"}, "/long/path/here.2")), LI(A({href:"/papľuh/path-ing/"}, "/papľuh/path-ing/")) )); printp("Hello, ", arg, "!"); printRequest(); } /**@ignore*/ function get_papľuh_(arg) { printp("Serviced by ", CODE(arguments.callee)); printp("Hello, ", arg, "!"); printRequest(); } /**@ignore*/ var get_papľuh_path$ing = "This is not a function"; /**@ignore*/ function get_long_path_() { throw new Error("This should not be called."); } /**@ignore*/ function get_long_path_here$2(arg) { printp("Serviced by ", CODE(arguments.callee)); printp("Hello, ", arg, "!"); printRequest(); } /**@ignore*/ function get_long_path_here$2_() { throw new Error("This should not be called."); } /**@ignore*/ function get_long_path_here$2_main() { throw new Error("This should not be called."); } printp("Features of extended dispatcher:"); print(UL( LI("Any nonalphanumeric characters (except the slash, of course) are replaced by '$' (dollar sign). Now you can serve /robots.txt by get_robots$txt function."), LI("You can put a handler only to a beginning part of the path, if you use name like get_beginning_. This serves all paths in the form /beginning/... The path is broken to request.pagePath (the first part) and request.pathTail (the rest)."), LI("If you end function with _main, it will not serve subpaths (it only matches to full path ending with / (a slash)."), LI("If there are more subpath handlers and full path handlers, the most specific (the one that matches the longest part of the path) is chosen. If case of get_path_ and get_path_main, the latter will be chosen to service /path/, but the former to service /path/some/more."), LI("404 is handled other way: you specify your 404 handler by assigning it to dispatchPlus.f404 before placing a call."), LI("Any arguments you put in dispatchPlus call, gets copied into your handler function.") )); printp("The statments issued in this minitest is ", CODE('dispatchPlus("world")')); dispatchPlus("world");