mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Fixes #286 - Automatically pass res.locals to template.render()
This commit is contained in:
parent
977bd09b8c
commit
038c71dc1a
@ -10,6 +10,10 @@ npm install marko --save
|
||||
|
||||
# Usage
|
||||
|
||||
Marko provides a submodule (`marko/express`) to add a `res.marko` method to the express response object. This function works much like `res.render`, but doesn't impose the restrictions of the express view engine and allows you to take full advantage of Marko's streaming and modular approach to templates.
|
||||
|
||||
By using `res.marko` you'll automatically have access to `req`, `res`, `app`, `app.locals`, and `res.locals` from within your Marko template and custom tags. These values are added to `out.global`.
|
||||
|
||||
```javascript
|
||||
require('marko/node-require').install();
|
||||
|
||||
@ -18,13 +22,16 @@ var template = require('./template.marko');
|
||||
|
||||
var app = express();
|
||||
|
||||
//enable res.marko
|
||||
require('marko/express').injectInto(express);
|
||||
|
||||
app.get('/', function(req, res) {
|
||||
template.render({
|
||||
name: 'Frank',
|
||||
count: 30,
|
||||
colors: ['red', 'green', 'blue']
|
||||
}, res);
|
||||
res.marko(template, {
|
||||
name: 'Frank',
|
||||
count: 30,
|
||||
colors: ['red', 'green', 'blue']
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(8080);
|
||||
```
|
||||
```
|
||||
|
||||
32
express.js
Normal file
32
express.js
Normal file
@ -0,0 +1,32 @@
|
||||
var assign = require('object-assign');
|
||||
|
||||
exports.injectInto = function injectInto(express) {
|
||||
if(express.response.marko) return;
|
||||
|
||||
express.response.marko = function(template, data) {
|
||||
if(typeof template === 'string') {
|
||||
throw new Error(
|
||||
'res.marko does not take a template name or path like res.render. ' +
|
||||
'Instead you should use `require(\'./path/to/template.marko\')` ' +
|
||||
'and pass the loaded template to this function.'
|
||||
)
|
||||
}
|
||||
|
||||
var res = this;
|
||||
var req = res.req;
|
||||
var app = res.app;
|
||||
var $global = assign({ app, req, res }, app.locals, res.locals);
|
||||
|
||||
if (data) {
|
||||
data = assign(data, {
|
||||
$global: assign($global, data.$global)
|
||||
});
|
||||
} else {
|
||||
data = { $global };
|
||||
}
|
||||
|
||||
res.set({ 'content-type': 'text/html; charset=utf-8' });
|
||||
|
||||
template.render(data, res);
|
||||
};
|
||||
};
|
||||
@ -16,6 +16,7 @@
|
||||
"test-fast": "node_modules/.bin/mocha --ui bdd --reporter spec ./test/render-test",
|
||||
"test-async": "node_modules/.bin/mocha --ui bdd --reporter spec ./test/render-async-test",
|
||||
"test-taglib-loader": "node_modules/.bin/mocha --ui bdd --reporter spec ./test/taglib-loader-test",
|
||||
"test-express": "node_modules/.bin/mocha --ui bdd --reporter spec ./test/express-test",
|
||||
"jshint": "node_modules/.bin/jshint compiler/ runtime/ taglibs/"
|
||||
},
|
||||
"author": "Patrick Steele-Idem <pnidem@gmail.com>",
|
||||
@ -33,6 +34,7 @@
|
||||
"htmljs-parser": "^1.5.3",
|
||||
"lasso-package-root": "^1.0.0",
|
||||
"minimatch": "^0.2.14",
|
||||
"object-assign": "^4.1.0",
|
||||
"property-handlers": "^1.0.0",
|
||||
"raptor-args": "^1.0.0",
|
||||
"raptor-async": "^1.1.2",
|
||||
@ -50,8 +52,10 @@
|
||||
"devDependencies": {
|
||||
"bluebird": "^2.9.30",
|
||||
"chai": "^3.3.0",
|
||||
"express": "^4.13.4",
|
||||
"jshint": "^2.5.0",
|
||||
"mocha": "^2.3.3",
|
||||
"request": "^2.72.0",
|
||||
"through": "^2.3.4"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
|
||||
1
test/autotests/express/headers/template.marko
Normal file
1
test/autotests/express/headers/template.marko
Normal file
@ -0,0 +1 @@
|
||||
<div></div>
|
||||
25
test/autotests/express/headers/test.js
Normal file
25
test/autotests/express/headers/test.js
Normal file
@ -0,0 +1,25 @@
|
||||
exports.createApp = function(express, markoExpress) {
|
||||
var app = express();
|
||||
|
||||
markoExpress.injectInto(express);
|
||||
|
||||
app.locals.foo = 'FOO';
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
res.locals.bar = 'BAR';
|
||||
next();
|
||||
});
|
||||
|
||||
return app;
|
||||
};
|
||||
|
||||
exports.createController = function(template) {
|
||||
return function(req, res) {
|
||||
res.marko(template);
|
||||
};
|
||||
}
|
||||
|
||||
exports.checkResponse = function(response, expect, helpers) {
|
||||
expect(response.headers['content-type']).to.equal('text/html; charset=utf-8');
|
||||
expect(response.body).to.equal('<div></div>');
|
||||
}
|
||||
1
test/autotests/express/locals/expected.html
Normal file
1
test/autotests/express/locals/expected.html
Normal file
@ -0,0 +1 @@
|
||||
<div>FOOBAR</div>
|
||||
1
test/autotests/express/locals/template.marko
Normal file
1
test/autotests/express/locals/template.marko
Normal file
@ -0,0 +1 @@
|
||||
<div>${out.global.foo}${out.global.bar}</div>
|
||||
20
test/autotests/express/locals/test.js
Normal file
20
test/autotests/express/locals/test.js
Normal file
@ -0,0 +1,20 @@
|
||||
exports.createApp = function(express, markoExpress) {
|
||||
markoExpress.injectInto(express);
|
||||
|
||||
var app = express();
|
||||
|
||||
app.locals.foo = 'FOO';
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
res.locals.bar = 'BAR';
|
||||
next();
|
||||
});
|
||||
|
||||
return app;
|
||||
};
|
||||
|
||||
exports.createController = function(template) {
|
||||
return function(req, res) {
|
||||
res.marko(template);
|
||||
};
|
||||
}
|
||||
1
test/autotests/express/priority/expected.html
Normal file
1
test/autotests/express/priority/expected.html
Normal file
@ -0,0 +1 @@
|
||||
<div>DATARESAPPHELLO</div>
|
||||
1
test/autotests/express/priority/template.marko
Normal file
1
test/autotests/express/priority/template.marko
Normal file
@ -0,0 +1 @@
|
||||
<div>${out.global.foo}${out.global.bar}${out.global.baz}${data.test}</div>
|
||||
23
test/autotests/express/priority/test.js
Normal file
23
test/autotests/express/priority/test.js
Normal file
@ -0,0 +1,23 @@
|
||||
exports.createApp = function(express, markoExpress) {
|
||||
markoExpress.injectInto(express);
|
||||
|
||||
var app = express();
|
||||
|
||||
app.locals.foo = 'APP';
|
||||
app.locals.bar = 'APP';
|
||||
app.locals.baz = 'APP';
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
res.locals.foo = 'RES';
|
||||
res.locals.bar = 'RES';
|
||||
next();
|
||||
});
|
||||
|
||||
return app;
|
||||
};
|
||||
|
||||
exports.createController = function(template) {
|
||||
return function(req, res) {
|
||||
res.marko(template, { $global:{ foo:'DATA' }, test:'HELLO' });
|
||||
};
|
||||
}
|
||||
81
test/express-test.js
Normal file
81
test/express-test.js
Normal file
@ -0,0 +1,81 @@
|
||||
'use strict';
|
||||
require('./patch-module');
|
||||
|
||||
var chai = require('chai');
|
||||
chai.config.includeStack = true;
|
||||
var path = require('path');
|
||||
var marko = require('../');
|
||||
var autotest = require('./autotest');
|
||||
var express = require('express');
|
||||
var markoExpress = require('../express');
|
||||
var request = require('request');
|
||||
var fs = require('fs');
|
||||
|
||||
require('../node-require').install();
|
||||
|
||||
describe('render', function() {
|
||||
var autoTestDir = path.join(__dirname, 'autotests/express');
|
||||
|
||||
autotest.scanDir(
|
||||
autoTestDir,
|
||||
function run(dir, helpers, done) {
|
||||
var mainPath = path.join(dir, 'test.js');
|
||||
var templatePath = path.join(dir, 'template.marko');
|
||||
|
||||
var main = fs.existsSync(mainPath) ? require(mainPath) : {};
|
||||
var loadOptions = main && main.loadOptions;
|
||||
|
||||
if (main.checkError) {
|
||||
var e;
|
||||
|
||||
try {
|
||||
main.createApp(express, markoExpress);
|
||||
} catch(_e) {
|
||||
e = _e;
|
||||
}
|
||||
|
||||
if (!e) {
|
||||
throw new Error('Error expected');
|
||||
}
|
||||
|
||||
main.checkError(e);
|
||||
return done();
|
||||
} else {
|
||||
var app = main.createApp(express, markoExpress);
|
||||
var template = marko.load(templatePath, loadOptions);
|
||||
|
||||
app.get('/test', main.createController(template));
|
||||
|
||||
var server = app.listen(0, function(err) {
|
||||
if(err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var port = server.address().port;
|
||||
var address = `http://localhost:${port}/test`;
|
||||
|
||||
request(address, function(error, response, body) {
|
||||
try {
|
||||
if(main.checkResponse) {
|
||||
response.body = body;
|
||||
response.error = error;
|
||||
main.checkResponse(response, chai.expect, helpers);
|
||||
} else {
|
||||
if(error) {
|
||||
return done(error);
|
||||
}
|
||||
chai.expect(response.statusCode).to.equal(200);
|
||||
helpers.compare(body, '.html');
|
||||
}
|
||||
} catch(error) {
|
||||
server.close();
|
||||
throw error;
|
||||
}
|
||||
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user