Ручки с Express: разные html-заголовки для разных страниц
Я использую Handlebars в приложении Express Node.js. Мой файл layout.html содержит раздел <head>
. Как сделать раздел <head>
другим для разных страниц? (Чтобы я мог, например, ссылаться на файл JavaScript только на одной странице и изменять <title>
для каждой страницы.)
layout.html выглядит следующим образом:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src='/public/ajsfile.js'></script>
<link type='text/css' href="/public/style.css" rel="stylesheet">
</head>
<body>
{{{body}}}
</body>
</html>
(Я представляю себе изменение содержания <head>
с чем-то аналогичным {{{body}}}
в приведенном выше, но с {{{head}}}
.)
Ответы
Ответ 1
Это большой вопрос и, на мой взгляд, явная слабость в модели Express view. К счастью, есть решение: используйте помощники блока Handlebars. Здесь помощник, который я использую для этой цели:
helpers: {
section: function(name, options){
if(!this._sections) this._sections = {};
this._sections[name] = options.fn(this);
return null;
}
}
Затем в вашем макете вы можете сделать следующее:
<head>
{{{_sections.head}}}
</head>
<body>
{{{body}}}
</body>
И на ваш взгляд:
{{#section 'head'}}
<!-- stuff that goes in head...example: -->
<meta name="robots" content="noindex">
{{/section}}
<h1>Body Blah Blah</h1>
<p>This goes in page body.</p>
Ответ 2
Вы можете сделать следующее:
layout.hbs
<head>
<title>{{title}}</title>
{{#each css}}
<link rel="stylesheet" href="/css/{{this}}" />
{{/each}}
</head>
app.js
router.get('/', function (req, res, next) {
res.render('index', { title: 'MyApp', css: ['style.css', 'custom.css'] });
});
Результат:
<head>
<title>MyApp</title>
<link rel="stylesheet" href="/css/style.css" />
<link rel="stylesheet" href="/css/custom.css" />
</head>
Ответ 3
Возможно, вы могли бы использовать эту реализацию помощника раздела: https://github.com/cyberxander90/express-handlebars-sections
Вам просто нужно установить его и включить:
yarn add express-handlebars-sections # or npm
const expressHandlebarsSections = require('express-handlebars-sections');
app.engine('handlebars', expressHandlebars({
section: expressHandlebarsSections()
}));
Надеюсь, что это поможет.
Юнес
Ответ 4
Я знаю, что это более старый вопрос, но я хотел указать на четкое альтернативное решение того, что вы просите (я не совсем уверен, почему никто больше не говорил об этом на протяжении многих лет). На самом деле у вас был ответ, который вы искали, когда вы поднимаете вещи в {{head}}}, как вы делаете для {{{body}}}, но я думаю, вам нужна помощь, чтобы понять, как заставить ее работать.
Похоже, что большинство ответов на этой странице ориентированы на Node "Разделы", потому что вы говорите о разных разделах HTML, которые вы включили в свой файл макета, который вы хотите изменить. "Разделы", о которых все говорят в этой теме, похоже, являются техникой, хотя я могу ошибаться, исходя из Microsoft Razor Template Engine. Дополнительная информация: https://mobile.codeguru.com/columns/dotnet/using-sections-and-partials-to-manage-razor-views.htm
В любом случае разделы работают по вашему вопросу, и поэтому теоретически возможно "Частицы" (хотя на самом деле это не лучший вариант). Дополнительная информация о Partials:
https://www.npmjs.com/package/express-partial
Однако вы просто попросили изменить HTML-тег содержимого макета шаблона в Handlebars, и, предполагая, что мы говорим о тегах заголовка HTML, все, что вам нужно сделать, это заменить содержимое, которое у вас есть в шаблоне HTML head tags с одним из них (я использую 3 скобки, потому что кажется, что HTML будет включен, и вы не хотите, чтобы он сбежал):
<head>
{{{headContent}}}
</head>
Затем вы просто динамически передаете любые данные, которые вы хотите, через созданный вами маршрут в файле app.js, чтобы "получить" страницу так (я в основном беру код @Fabricio уже предоставленный, поэтому мне не пришлось переписывать это):
router.get('/', function (req, res) {
res.render( 'index', { headContent:'I DID IT!' });
});
Теперь, когда вы загружаете свою страницу, "Я СДЕЛАЛ ЭТО!". будет там, где вы ожидаете, что он появится.