web-dev-qa-db-fra.com

Partials avec Node.js + Express + Hogan.js

Je développe un site avec Node.js + Express et utilise le moteur de visualisation Hogan.js.

Ceci est mon fichier 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'));
});

Le fichier /routes/index.js est:

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

Dans le dossier /views, il y a:

| - part.hjs

| - index.hjs

| - cv.hjs

Le fichier part.hjs est:

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

Le fichier index.hjs est:

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

Et le fichier about.hjs est:

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

J'ai deux questions:

  1. Comment utiliser correctement les partiels dans mes pages? (ce code ne fonctionne pas)
  2. Puis-je utiliser le même "titre" pour deux pages ou plus sans répéter l'attribution de valeurs dans le fichier /routes/index.js?

Cordialement, Vi.

18
user1288707

J'ai trouvé une solution à la première question.

Tout d’abord, j’ai supprimé hjs

npm remove hjs

Ensuite, j'ai installé le paquet hogan-express:

npm install hogan-express

De plus, j'ai édité 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'));
});

Et routes/index.js:

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

Maintenant, dans /views il y a index.html, part.html. Le fichier part.html contient:

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

Le fichier index.html contient:

{{> part}}
Hello world!

Donc, ça marche bien.

25
user1288707

Au moins dans Express 4+, les partiels fonctionnent simplement. Vous pouvez utiliser express-generator (à partir de npm) avec l'option --hogan ou -H.

Après cela, vous devez ajouter des partiels à la méthode de rendu:

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

Ensuite, dans votre modèle, utilisez {{> xxx}}

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

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

NOTE: cela a header.hjs dans les vues

6
bryanmac

Pour utiliser les partiels avec express + hogan, procédez comme suit:

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

Et maintenant, votreMainView.html:

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

Remarquez le triple '{' au lieu de double comme vous le faites habituellement! Ce mot d'ordre (moustache) pour analyser cela en tant que HTML plutôt que comme une chaîne!

C'est tout.

4
Oren Yakobi

Quant à votre question partielle, si vous utilisez consolidate.js vous pouvez simplement faire:

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

J'utiliserais mmm au lieu de hjs.

https://github.com/techhead/mmm

Disclaimer: J'ai écrit le package.

Il suffit de remplacer toutes les occurrences de hjs par mmm et les partiels commenceront à fonctionner. Il y a beaucoup plus d'informations et un exemple sur le lien ci-dessus.

Quant à votre autre question, si vous souhaitez partager des propriétés entre plusieurs vues, vous avez plusieurs options.

Lorsque vous appelez res.render(name, options), la options sera réellement fusionnée sur res.locals et app.locals avant d'être transmise au moteur de rendu. Par conséquent, pour définir une propriété à l'échelle de l'application, vous pouvez simplement l'attribuer à app.locals.

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

Ce concept s’applique vraiment à n’importe quel moteur Express 3 View Engine.

Toutefois, pour mmm en particulier, veuillez vous reporter à la section Logique de présentation pour davantage de façons de lier des valeurs à un modèle ou à un ensemble de modèles.

2
Jonathan Hawkes

C'est un problème. Un support partiel est difficile à obtenir dans Express 3.

Votre meilleur pari est: https://github.com/visionmedia/consolidate.jsnpm install consolidate

Ces correctifs utilisent différentes approches pour ajouter des partiels pour Hogan:

Malheureusement, le moteur ne dispose pas d'un crochet pour les partiels basés sur un système de fichiers de manière native, donc je pense que les gens ne savent pas trop comment et où les partiels doivent être implémentés. Je me suis retrouvé avec la mise en œuvre de Dust.js de LinkedIn, car un support partiel était déjà là. Le support de Master est encore meilleur, de plus, j'ai soumis un correctif hier pour les chemins relatifs.

Josh

2
Josh