可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm developing a site with Node.js + Express and using as view engine Hogan.js.
This is my file app.js
:
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'hjs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
app.get('/about', routes.about);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
The file /routes/index.js
is:
/*
* GET pages.
*/
exports.index = function(req, res){
res.render(
'index',
{
title: 'Home Page',
author: 'Bruce Wayne'
}
);
};
exports.about = function(req, res){
res.render(
'about',
{
title: 'About Page',
author: 'Bruce Wayne'
}
);
};
In /views
folder, there are:
|- part.hjs
|- index.hjs
|- cv.hjs
The file part.hjs
is:
<h3>Hello {{ author }}</h3>
The file index.hjs
is:
<h1>Title: {{ title }} </h1>
{{> part }}
Welcome to Gotham City.
And the file about.hjs
is:
<h1>Title: {{ title }}</h1>
{{> part }}
I'm not Joker.
I've two questions:
- How can I use properly the partials in my pages? (this code doesn't work)
- Can I use the same "title" for two or more pages without repeat the values assignment in file
/routes/index.js
?
Best regards, Vi.
回答1:
I've found a solution for the first question.
First of all, I removed hjs
:
npm remove hjs
Then, I installed the package hogan-express
:
npm install hogan-express
Furthermore, I edited app.js
:
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');
var app = express();
app.engine('html', require('hogan-express'));
app.enable('view cache');
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'html');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
And routes/index.js
:
exports.index = function(req, res) {
res.locals = {
title: 'Title',
};
return res.render(
'index',
{
partials:
{
part: 'part',
}
}
);
};
Now, in /views
there are index.html
, part.html
.
The file part.html
contains:
<h1>{{ title }}</h1>
The file index.html
contains:
{{> part}}
Hello world!
So, It works fine.
回答2:
At least in Express 4+, partials just work out of the box. You can use express-generator (from npm) with --hogan or -H option.
After doing that, you need to add partials to the render method:
router.get('/', function(req, res, next) {
res.render('index',
{
title: 'My Site',
partials: {header: 'header'}
});
});
Then, in your template use {{ > xxx }}
<body>
{{> header }}
<h1>{{ title }}</h1>
<p>Welcome to {{ title }}</p>
</body>
NOTE: this has header.hjs in views
回答3:
To use partials with express+hogan, just do the following:
app.get('/yourRoute', function(req, res){
res.render('yourPartial', function(err,html){
var partialHTML = html;
res.render('yourMainView', { myPartial: partialHTML }, function(err,html){
res.send(html);
});
});
}
And now, yourMainView.html:
<p>Something Something Something</p>
{{{partialHTML}}}
<p>Bla Bla Bla</p>
Notice the triple '{' instead of double as you usually do! That telling hogan (mustache) to parse this as HTML rather then a string!
That's it.
回答4:
As for your partials question, if you use consolidate.js you can simply do:
res.render('index', {
partials: {
part : 'path/to/part'
}
});
回答5:
This is a problem. Partial support is difficult to come by in Express 3.
Your best bet is:
https://github.com/visionmedia/consolidate.js
npm install consolidate
These patches take different approaches to adding partials for Hogan:
- https://github.com/visionmedia/consolidate.js/pull/51
- https://github.com/visionmedia/consolidate.js/pull/29
Unfortunately, the engine doesn't have a hook for filesystem based partials natively, so I think people are confused about how and where partials should be implemented. I ended up with LinkedIn's Dust.js implementation, since partial support was already there. Master actually has even better support, plus I submitted a patch yesterday for relative paths.
Josh
回答6:
I would use mmm
instead of hjs
.
https://github.com/techhead/mmm
Disclaimer: I wrote the package.
Just replace all occurrences of hjs
with mmm
and partials will start working. There is a lot more information and an example at the link above.
As for your other question, if you want to share properties across multiple views, you have a couple of options.
When you call res.render(name, options)
, the options
will actually be merged onto res.locals
and app.locals
before being passed to the rendering engine. Therefore to set an app-wide property, you can simply assign it to app.locals
.
app.locals.title = "Default Title"; // Sets the default title for the application
This concept really applies to just about any Express 3 View Engine.
However, for mmm
specifically, please see the section under Presentation Logic for more ways to bind values to a template or set of templates.