Express.js модуль hbs — регистрирует части из файла .hbs

#node.js #express #handlebars.js

#node.js #выразить #handlebars.js

Вопрос:

Я использую handlebars.js оболочка hbs в express.js. У меня есть шаблоны, работающие нормально, но мне нужно добавить части, которые будут отображаться в моих представлениях.

Я бы хотел сделать что-то вроде этого:

 hbs.registerPartial('headPartial', 'header'); 
// where "header" is an .hbs file in my views folder
  

Однако он выдает сообщение «частичный заголовок не может быть найден».

Я могу заставить registerPartial работать, если передам строку html второму параметру, но я хотел бы использовать отдельные файлы просмотра для своих частей.

Я не нашел никакой документации по этому вопросу, но надеюсь, что, возможно, я просто упускаю что-то простое.

Кто-нибудь знает, как использовать просмотр файлов в методе registerPartial? Если да, то как мне это реализовать?

Обновить

Чтобы дать больше контекста, позвольте мне добавить больше кода. Вот мой файл «server» — app.js

 var express = require('express')
, routes = require('./routes')
, hbs = require('hbs');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname   '/views');
  app.set('view engine', 'hbs');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname   '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

// this is the line that generates the error
hbs.registerPartial('headPartial', 'header'); 

// What I'm expecting is for "headPartial" to be a compiled template partial 
// of the template within views/header.hbs, but it is not loading this way.
// If I do something like hbs.registerPartial('headPartial', '<p>test</p>');
// then it does work. I need to know how to pass an .hbs file to the
// registerPartial method.

// Routes
app.get('/', routes.index);

app.listen(3000);
  

И вот мой файл routes.index:

 exports.index = function(req, res){
  res.render('index', { title: 'Express' })
};
  

В моей папке views у меня есть три шаблона:

 views/
  header.hbs (this is my partial)
  index.hbs
  layout.hbs
  

В моем файле index.hbs я вызываю часть ‘headPartial’ с помощью:

 {{> headPartial}}
  

Любая помощь приветствуется.

Ответ №1:

Для удобства registerPartials предоставляет быстрый способ загрузки всех частичных файлов из определенного каталога:

 var hbs = require('hbs');
hbs.registerPartials(__dirname   '/views/partials');
  

Части, загруженные из каталога, присваиваются имена на основе их имени файла, где пробелы и дефисы заменяются символом подчеркивания:

 template.html      -> {{> template}}
template 2.html    -> {{> template_2}}
login view.hbs     -> {{> login_view}}
template-file.html -> {{> template_file}}
  

Приветствия!

Комментарии:

1. Привет, это будет работать и для подкаталогов? В этом случае, как мы можем получить представления? Спасибо

2. Это здорово, но имейте в виду, что он загружает части асинхронно с обратным вызовом — вы, вероятно, не захотите принимать запросы, пока это не завершится: Помощники и части

3. О, чувак, большое спасибо! Я только что потратил полчаса, выясняя, почему моя часть keypad-num.hbs не найдена, когда я запрашивал ее с помощью: {{> keypad-num}} . вы сэкономили мне много времени.

4. Проголосовал за краткий код загрузки во всем каталоге и объяснение того факта, что пробелы и тире заменены символами подчеркивания. Это была моя проблема, которая привела меня сюда. Я использовал тире в своих именах частей, но я получал сообщение об ошибке при попытке загрузить его с помощью тире. Я видел, что у человека, задающего этот вопрос, были свои части в том же каталоге, что и их представления, так что, надеюсь, это подтолкнет их разделить их на два подкаталога для более организованного приложения.

5. Это определенно должно быть принятым ответом из-за того факта, что это правильный способ использования частей, и он также охватывает угловые случаи.

Ответ №2:

Этот код загружает все частичные шаблоны в каталог и делает их доступными по имени файла:

 var hbs = require('hbs');
var fs = require('fs');

var partialsDir = __dirname   '/../views/partials';

var filenames = fs.readdirSync(partialsDir);

filenames.forEach(function (filename) {
  var matches = /^([^.] ).hbs$/.exec(filename);
  if (!matches) {
    return;
  }
  var name = matches[1];
  var template = fs.readFileSync(partialsDir   '/'   filename, 'utf8');
  hbs.registerPartial(name, template);
});
  

Комментарии:

1. Неплохо. Быстрый способ иметь все части доступными, когда это необходимо!

2. Спасибо, Бен, это действительно очень помогло.

Ответ №3:

Похоже, что создание переменной и извлечение кода шаблона вручную работает:

 var hbs = require('hbs')
  , fs = require('fs')
  , headerTemplate = fs.readFileSync(__dirname   '/views/_header.hbs', 'utf8');
  

и более поздние версии:

 hbs.registerPartial('headPartial', headerTemplate); 
  

Комментарии:

1. кажется, что для подачи иска на части в express3 требуется много дополнительной работы

Ответ №4:

Для меня у меня был файл шаблона my-partial.hbs

Затем я попытался получить к ним доступ через:

 {{> my-partial }}
  

Но часть была сохранена в hbs как my_partial независимо от имени файла.

Это благодаря версии hbs 3.1.0, строке 218

 .slice(0, -(ext.length)).replace(/[ -]/g, '_').replace('\', '/');
  

Это находится в readme

Ответ №5:

Для меня у меня есть функция, подобная:

 var hbs = require('hbs');
var fs = require('fs');    
var statupfunc = {
      registerHbsPartials : function(){
        //this is run when app start
        hbs.registerPartials(__dirname   "/"   resource.src.views   '/partials');        
      },
      registerOneHbsPartials : function(event){ 
        //this is run for gulp watch
        if(event.type == 'deleted')
        {
          return;
        }   
        var filename = event.path;
        var matches = /^.*\(. ?).hbs$/.exec(filename);
        if (!matches) {
          return;
        }    
        var name = matches[1];    
        var template = fs.readFileSync(filename, 'utf8');    
        hbs.registerPartial(name, template);    
      }
    };
  

Запустите statupfunc.registeronehbspartials при запуске приложения, а затем зарегистрируйте gulp watch с помощью statupfunc.registerOneHbsPartials, чтобы зарегистрировать части при новом создании

 gulp.task('watch', function() {
    gulp.watch(resource.src.views    '/partials/*.*', statupfunc.registerOneHbsPartials);
});
  

Ответ №6:

Структура моего приложения (с использованием ExpressJS и HBS-NPM) такова:

   APP FOLDER
    -src
      app.js
      - routers
      - views
        -- partials
              header.hbs



const hbs = require('hbs')
hbs.registerPartials(path.join(__dirname,'views','partials'))
  

Вышеописанное выполняет работу по загрузке всех частей за один выстрел. Используйте это до тех пор, пока вы считаете, что это не повлияет на вашу производительность (загружая все части, даже если это не требуется).

А затем использовать эту часть в любом файле HBS следующим образом:

 {{> partial_file_name_without_hbs_extension}}
  

Пример

  {{> header}