2012-10-08 4 views
18

Я разрабатываю сайт с Node.js + Express и использую в качестве механизма просмотра Hogan.js.Частицы с Node.js + Express + Hogan.js

Это мой файл 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')); 
}); 

Файл /routes/index.js является:

/* 
* 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' 
    } 
); 
}; 

В /views папке есть:

| - part.hjs

| - index.hjs

| - cv.hjs

Файл part.hjs является:

<h3>Hello {{ author }}</h3> 

Файл index.hjs является:

<h1>Title: {{ title }} </h1> 
{{> part }} 
Welcome to Gotham City. 

И файл about.hjs является:

<h1>Title: {{ title }}</h1> 
{{> part }} 
I'm not Joker. 

Я два вопроса:

  1. Как правильно использовать парциальные в моих страницах? (этот код не работает)
  2. Можно ли использовать один и тот же заголовок для двух или более страниц без повторения присвоения значений в файле /routes/index.js?

С уважением, Vi.

+0

Благодарим вас за сообщение. Sheesh. немного погубился, пока я не наткнулся на этот камень. – FinalForm

+0

Я думаю, что ответ Орена правильный для этого вопроса. – bryanmac

+1

Какая версия экспресса вы здесь работаете? – martisj

ответ

24

Я нашел решение для первого вопроса.

Прежде всего, я удалил hjs:

npm remove hjs 

Затем я установил пакет hogan-express:

npm install hogan-express 

Кроме того, я редактировал 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')); 
}); 

И routes/index.js:

exports.index = function(req, res) { 
    res.locals = { 
    title: 'Title', 
    }; 
    return res.render(
    'index', 
    { 
     partials: 
     { 
     part: 'part', 
     } 
    } 
); 
}; 

Теперь в /views есть index.html, part.html. Файл part.html содержит:

<h1>{{ title }}</h1> 

Файл index.html содержит:

{{> part}} 
Hello world! 

Таким образом, он отлично работает.

+0

http://paularmstrong.github.io/swig –

+1

Не нужно удалять 'hjs' сейчас, просто добавьте' partials: {var: file_path} 'в' render' – user1775888

+1

@ user1775888 правильно ... по крайней мере для express 4+ , Я расширил это в другом ответе – bryanmac

2

Это проблема. Частичная поддержка трудно прийти в Экспресс 3.

Ваш лучший выбор: https://github.com/visionmedia/consolidate.js npm install consolidate

Эти патчи разные подходы к добавлению партиалы для Hogan:

К сожалению, у двигателя нет крючка для частичных элементов, основанных на файловой системе, поэтому я думаю, что люди путаются о том, как и где должны выполняться частичные действия. Я закончил реализацию Dust.js от LinkedIn, поскольку частичная поддержка уже была там. У мастера действительно есть еще лучшая поддержка, плюс я вчера опубликовал патч для относительных путей.

Josh

+0

Большое вам спасибо. Я мог найти решение для частичного использования пакета hogan-express. Существуют ли различия в консолидации? Что лучше? –

+1

Консолидация может иметь фактическую поддержку для частичных. В решении, которое вы указали ниже, вы должны переслать объявление всех своих партикулов и передать их в хэш-параметры. Это несколько неудобно, но не невозможно. На других языках вы можете просто сказать {> partial /}, и он будет напрямую касаться частичной файловой системы. – Josh

2

Я бы использовал mmm вместо hjs.

https://github.com/techhead/mmm

Отказ от ответственности: я написал пакет.

Просто замените все заявки hjs на номер mmm и начните работу с парциалами. Существует более подробная информация и пример по ссылке выше.

Что касается вашего другого вопроса, если вы хотите обмениваться свойствами нескольких видов, у вас есть несколько вариантов.

Когда вы позвоните по номеру res.render(name, options), options фактически будет объединено с res.locals и app.locals перед тем, как передать его в двигатель рендеринга. Поэтому, чтобы установить свойство приложения, вы можете просто присвоить его app.locals.

app.locals.title = "Default Title"; // Sets the default title for the application 

Эта концепция действительно применима практически к любому движку Express 3 View Engine.

Тем не менее, в частности, в разделе «Представление логики» можно найти дополнительные способы привязки значений к шаблону или набору шаблонов.

+0

У меня похожие проблемы, и я не хочу следовать следующему решению и явно передавать переменную partials в мои шаблоны. Сейчас я попробую ммм. Надеюсь, это сработает. Я уже пробовал hulk-hogan, только чтобы понять, что он не работает с express 3.x –

+0

Плохое предложение. Что делать, если у ОП есть много работы, выполненной с использованием hjs. Изменение механизма шаблона для решения такой простой проблемы - массивный избыточный уровень – CrazyMerlin

3

Что касается вашего Partials вопрос, если вы используете consolidate.js вы можете просто сделать:

res.render('index', { 
    partials: { 
    part : 'path/to/part' 
    } 
}); 
4

Чтобы использовать парциальные с курьерским + Hogan, просто сделайте следующее:

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); 
     });  
    }); 
} 

И теперь, yourMainView .html:

<p>Something Something Something</p> 
{{{partialHTML}}} 
<p>Bla Bla Bla</p> 

Обратите внимание на тройной '{' вместо двойного, как вы обычно делаете!Это говорит, что хоган (усы) анализирует это как HTML, а не строку!

Все.

+0

Знаете ли вы, как назначить переменную Javascript? что-то вроде: Но с защитой html escape-символов и т. Д. ???? – cmarrero01

6

По крайней мере, в Express 4+ частичные работы просто работают из коробки. Вы можете использовать экспресс-генератор (от npm) с опцией -hogan или -H.

После выполнения этого вам нужно добавить партиалы методу визуализации:

router.get('/', function(req, res, next) { 
    res.render('index', 
     { 
      title: 'My Site', 
      partials: {header: 'header'} 
     }); 
}); 

Затем в вашем использовании шаблона {{> ххх}}

<body> 
    {{> header }} 
    <h1>{{ title }}</h1> 

    <p>Welcome to {{ title }}</p> 
</body> 

Примечание: это имеет заголовок. hjs in views