diff --git a/UnitTests/Makefile.unittests b/UnitTests/Makefile.unittests index 685ae9e8e9..32b443d691 100755 --- a/UnitTests/Makefile.unittests +++ b/UnitTests/Makefile.unittests @@ -317,6 +317,7 @@ SHELL_SERVER_ONLY = \ @top_srcdir@/js/common/tests/shell-foxx-repository.js \ @top_srcdir@/js/common/tests/shell-foxx-model.js \ @top_srcdir@/js/common/tests/shell-foxx-base-middleware.js \ + @top_srcdir@/js/common/tests/shell-foxx-template-middleware.js \ @top_srcdir@/js/common/tests/shell-graph-traversal.js \ @top_srcdir@/js/common/tests/shell-graph-algorithms.js \ @top_srcdir@/js/common/tests/shell-graph-measurement.js \ diff --git a/js/common/tests/shell-foxx-base-middleware.js b/js/common/tests/shell-foxx-base-middleware.js index c4e41d6fe4..070dd4306c 100644 --- a/js/common/tests/shell-foxx-base-middleware.js +++ b/js/common/tests/shell-foxx-base-middleware.js @@ -4,7 +4,7 @@ var jsunity = require("jsunity"), arangodb = require("org/arangodb"), db = arangodb.db; -function BaseMiddlewareWithoutTemplateSpec () { +function BaseMiddlewareSpec () { var BaseMiddleware, request, response, options, next; return { @@ -110,85 +110,6 @@ function BaseMiddlewareWithoutTemplateSpec () { }; } -function BaseMiddlewareWithTemplateSpec () { - var BaseMiddleware, request, response, options, next; - - return { - setUp: function () { - request = {}; - response = {}; - options = {}; - next = function () {}; - BaseMiddleware = require("org/arangodb/foxx/base_middleware").BaseMiddleware; - }, - - testRenderingATemplate: function () { - var myCollection, middleware; - - db._drop("templateTest"); - myCollection = db._create("templateTest"); - - myCollection.save({ - path: "simple/path", - content: "hello <%= username %>", - contentType: "text/plain", - templateLanguage: "underscore" - }); - - middleware = new BaseMiddleware(myCollection).functionRepresentation; - middleware(request, response, options, next); - - response.render("simple/path", { username: "moonglum" }); - assertEqual(response.body, "hello moonglum"); - assertEqual(response.contentType, "text/plain"); - }, - - testRenderingATemplateWithAnUnknownTemplateEngine: function () { - var myCollection, error, middleware; - - db._drop("templateTest"); - myCollection = db._create("templateTest"); - - myCollection.save({ - path: "simple/path", - content: "hello <%= username %>", - contentType: "text/plain", - templateLanguage: "pirateEngine" - }); - - middleware = new BaseMiddleware(myCollection).functionRepresentation; - middleware(request, response, options, next); - - try { - response.render("simple/path", { username: "moonglum" }); - } catch(e) { - error = e; - } - - assertEqual(error, new Error("Unknown template language 'pirateEngine'")); - }, - - testRenderingATemplateWithAnNotExistingTemplate: function () { - var myCollection, error, middleware; - - db._drop("templateTest"); - myCollection = db._create("templateTest"); - - middleware = new BaseMiddleware(myCollection).functionRepresentation; - middleware(request, response, options, next); - - try { - response.render("simple/path", { username: "moonglum" }); - } catch(e) { - error = e; - } - - assertEqual(error, new Error("Template 'simple/path' does not exist")); - } - }; -} - -jsunity.run(BaseMiddlewareWithoutTemplateSpec); -jsunity.run(BaseMiddlewareWithTemplateSpec); +jsunity.run(BaseMiddlewareSpec); return jsunity.done(); diff --git a/js/common/tests/shell-foxx-template-middleware.js b/js/common/tests/shell-foxx-template-middleware.js new file mode 100644 index 0000000000..a7ea1c8b3f --- /dev/null +++ b/js/common/tests/shell-foxx-template-middleware.js @@ -0,0 +1,87 @@ +require("internal").flushModuleCache(); + +var jsunity = require("jsunity"), + arangodb = require("org/arangodb"), + db = arangodb.db; + +function TemplateMiddlewareSpec () { + var BaseMiddleware, request, response, options, next; + + return { + setUp: function () { + request = {}; + response = {}; + options = {}; + next = function () {}; + BaseMiddleware = require("org/arangodb/foxx/template_middleware").TemplateMiddleware; + }, + + testRenderingATemplate: function () { + var myCollection, middleware; + + db._drop("templateTest"); + myCollection = db._create("templateTest"); + + myCollection.save({ + path: "simple/path", + content: "hello <%= username %>", + contentType: "text/plain", + templateLanguage: "underscore" + }); + + middleware = new BaseMiddleware(myCollection).functionRepresentation; + middleware(request, response, options, next); + + response.render("simple/path", { username: "moonglum" }); + assertEqual(response.body, "hello moonglum"); + assertEqual(response.contentType, "text/plain"); + }, + + testRenderingATemplateWithAnUnknownTemplateEngine: function () { + var myCollection, error, middleware; + + db._drop("templateTest"); + myCollection = db._create("templateTest"); + + myCollection.save({ + path: "simple/path", + content: "hello <%= username %>", + contentType: "text/plain", + templateLanguage: "pirateEngine" + }); + + middleware = new BaseMiddleware(myCollection).functionRepresentation; + middleware(request, response, options, next); + + try { + response.render("simple/path", { username: "moonglum" }); + } catch(e) { + error = e; + } + + assertEqual(error, new Error("Unknown template language 'pirateEngine'")); + }, + + testRenderingATemplateWithAnNotExistingTemplate: function () { + var myCollection, error, middleware; + + db._drop("templateTest"); + myCollection = db._create("templateTest"); + + middleware = new BaseMiddleware(myCollection).functionRepresentation; + middleware(request, response, options, next); + + try { + response.render("simple/path", { username: "moonglum" }); + } catch(e) { + error = e; + } + + assertEqual(error, new Error("Template 'simple/path' does not exist")); + } + }; +} + +jsunity.run(TemplateMiddlewareSpec); + +return jsunity.done(); diff --git a/js/common/tests/shell-foxx.js b/js/common/tests/shell-foxx.js index 3d762a0b8d..4ca7ca1fff 100644 --- a/js/common/tests/shell-foxx.js +++ b/js/common/tests/shell-foxx.js @@ -426,7 +426,7 @@ function ViewHelperSpec () { return { setUp: function () { app = new FoxxApplication({prefix: "", foxxes: []}); - Middleware = require('org/arangodb/foxx/base_middleware').BaseMiddleware; + Middleware = require('org/arangodb/foxx/template_middleware').TemplateMiddleware; request = {}; response = {}; options = {}; diff --git a/js/server/modules/org/arangodb/foxx/application.js b/js/server/modules/org/arangodb/foxx/application.js index 1b2a7baab7..7c619fa1bb 100644 --- a/js/server/modules/org/arangodb/foxx/application.js +++ b/js/server/modules/org/arangodb/foxx/application.js @@ -1,4 +1,3 @@ -/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true */ /*global module, require, exports */ //////////////////////////////////////////////////////////////////////////////// @@ -130,11 +129,10 @@ Application = function (context, options) { if (_.isString(templateCollection)) { this.templateCollection = db._collection(templateCollection) || db._create(templateCollection); - myMiddleware = new BaseMiddleware(templateCollection, this.helperCollection); - } else { - myMiddleware = new BaseMiddleware(); } + myMiddleware = new BaseMiddleware(); + this.routingInfo.middleware = [ { url: { match: "/*" }, diff --git a/js/server/modules/org/arangodb/foxx/base_middleware.js b/js/server/modules/org/arangodb/foxx/base_middleware.js index 9e45c3e45d..d5aa5cc88a 100644 --- a/js/server/modules/org/arangodb/foxx/base_middleware.js +++ b/js/server/modules/org/arangodb/foxx/base_middleware.js @@ -38,7 +38,7 @@ var BaseMiddleware; /// objects to give you a nicer API. //////////////////////////////////////////////////////////////////////////////// -BaseMiddleware = function (templateCollection, helperCollection) { +BaseMiddleware = function () { 'use strict'; var middleware = function (request, response, options, next) { var responseFunctions, @@ -167,70 +167,6 @@ BaseMiddleware = function (templateCollection, helperCollection) { json: function (obj) { this.contentType = "application/json"; this.body = JSON.stringify(obj); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @fn JSF_foxx_BaseMiddleware_response_render -/// @brief The magical `json` function -/// -/// @FUN{response.render(@FA{templatePath}, @FA{data})} -/// -/// If you initialize your Application with a `templateCollection`, you're in -/// luck now. -/// -/// It expects documents in the following form in this collection: -/// -/// @code -/// { -/// path: "high/way", -/// content: "hello <%= username %>", -/// contentType: "text/plain", -/// templateLanguage: "underscore" -/// } -/// @endcode -/// -/// The `content` is the string that will be rendered by the template -/// processor. The `contentType` is the type of content that results from this -/// call. And with the `templateLanguage` you can choose your template -/// processor. There is only one choice now: `underscore`. -/// -/// If you call render, Application will look into the this collection and -/// search by the path attribute. It will then render the template with the -/// given data: -/// -/// Which would set the body of the response to `hello Application` with the -/// template defined above. It will also set the `contentType` to `text/plain` -/// in this case. -/// -/// In addition to the attributes you provided, you also have access to all your -/// view helpers. How to define them? Read above in the ViewHelper section. -/// -/// @EXAMPLES -/// -/// @code -/// response.render("high/way", {username: 'Application'}) -/// @endcode -//////////////////////////////////////////////////////////////////////////////// - - render: function (templatePath, data) { - var template; - - if (_.isUndefined(templateCollection)) { - throw new Error("No template collection has been provided when creating a new FoxxApplication"); - } - - template = templateCollection.firstExample({path: templatePath }); - - if (_.isNull(template)) { - throw new Error("Template '" + templatePath + "' does not exist"); - } - - if (template.templateLanguage !== "underscore") { - throw new Error("Unknown template language '" + template.templateLanguage + "'"); - } - - this.body = _.template(template.content, _.extend(data, helperCollection)); - this.contentType = template.contentType; } }; diff --git a/js/server/modules/org/arangodb/foxx/template_middleware.js b/js/server/modules/org/arangodb/foxx/template_middleware.js new file mode 100644 index 0000000000..a50f7d727e --- /dev/null +++ b/js/server/modules/org/arangodb/foxx/template_middleware.js @@ -0,0 +1,132 @@ +/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true */ +/*global module, require, exports */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Foxx Template Middleware +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2013 triagens GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Lucas Dohmen +/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +var TemplateMiddleware; + +//////////////////////////////////////////////////////////////////////////////// +/// @fn JSF_foxx_TemplateMiddleware_initializer +/// @brief The Template Middleware +/// +/// The `TemplateMiddleware` manipulates the request and response +/// objects to give you a nicer API. +//////////////////////////////////////////////////////////////////////////////// + +TemplateMiddleware = function (templateCollection, helperCollection) { + 'use strict'; + var middleware = function (request, response, options, next) { + var responseFunctions, + _ = require("underscore"); + + responseFunctions = { + +//////////////////////////////////////////////////////////////////////////////// +/// @fn JSF_foxx_BaseMiddleware_response_render +/// @brief The magical `json` function +/// +/// @FUN{response.render(@FA{templatePath}, @FA{data})} +/// +/// If you initialize your Application with a `templateCollection`, you're in +/// luck now. +/// +/// It expects documents in the following form in this collection: +/// +/// @code +/// { +/// path: "high/way", +/// content: "hello <%= username %>", +/// contentType: "text/plain", +/// templateLanguage: "underscore" +/// } +/// @endcode +/// +/// The `content` is the string that will be rendered by the template +/// processor. The `contentType` is the type of content that results from this +/// call. And with the `templateLanguage` you can choose your template +/// processor. There is only one choice now: `underscore`. +/// +/// If you call render, Application will look into the this collection and +/// search by the path attribute. It will then render the template with the +/// given data: +/// +/// Which would set the body of the response to `hello Application` with the +/// template defined above. It will also set the `contentType` to `text/plain` +/// in this case. +/// +/// In addition to the attributes you provided, you also have access to all your +/// view helpers. How to define them? Read above in the ViewHelper section. +/// +/// @EXAMPLES +/// +/// @code +/// response.render("high/way", {username: 'Application'}) +/// @endcode +//////////////////////////////////////////////////////////////////////////////// + + render: function (templatePath, data) { + var template; + + if (_.isUndefined(templateCollection)) { + throw new Error("No template collection has been provided when creating a new FoxxApplication"); + } + + template = templateCollection.firstExample({path: templatePath }); + + if (_.isNull(template)) { + throw new Error("Template '" + templatePath + "' does not exist"); + } + + if (template.templateLanguage !== "underscore") { + throw new Error("Unknown template language '" + template.templateLanguage + "'"); + } + + this.body = _.template(template.content, _.extend(data, helperCollection)); + this.contentType = template.contentType; + } + }; + + _.extend(response, responseFunctions); + }; + + return { + stringRepresentation: String(middleware), + functionRepresentation: middleware + }; +}; + +exports.TemplateMiddleware = TemplateMiddleware; + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +/// Local Variables: +/// mode: outline-minor +/// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint" +/// End: