npm install express-handlebarsconst express = require('express');
const { engine } = require('express-handlebars');
const app = express();
// Handlebars als View Engine registrieren
app.engine('handlebars', engine());
app.set('view engine', 'handlebars');
app.set('views', './views');const { engine } = require('express-handlebars');
app.engine('handlebars', engine({
defaultLayout: 'main', // Standard-Layout
layoutsDir: './views/layouts', // Layout-Verzeichnis
partialsDir: './views/partials', // Partials-Verzeichnis
extname: '.handlebars', // Dateiendung
helpers: { // Custom Helpers
// Helper-Funktionen hier
}
}));views/
├── layouts/
│ └── main.handlebars # Hauptlayout
├── partials/
│ ├── header.handlebars # Wiederverwendbare Komponenten
│ └── footer.handlebars
└── home.handlebars # Views
app.get('/', (req, res) => {
res.render('home', {
title: 'Startseite',
layout: 'main' // Optional, wenn defaultLayout gesetzt
});
});res.render('home', {
layout: false // Rendert ohne Layout
});app.engine('handlebars', engine({
partialsDir: [
'views/partials',
'views/components' // Mehrere Verzeichnisse möglich
]
}));app.engine('handlebars', engine({
helpers: {
// String in Großbuchstaben
uppercase: (str) => str.toUpperCase(),
// Datum formatieren
formatDate: (date) => {
return new Date(date).toLocaleDateString('de-DE');
},
// Mathematische Operation
add: (a, b) => a + b,
// JSON ausgeben
json: (context) => JSON.stringify(context, null, 2)
}
}));helpers: {
// Bedingte Anzeige
ifEquals: function(arg1, arg2, options) {
return (arg1 == arg2) ? options.fn(this) : options.inverse(this);
},
// Liste mit Trenner
list: function(items, options) {
const itemsAsHtml = items.map(item => options.fn(item));
return itemsAsHtml.join(options.hash.separator || ', ');
}
}Verwendung:
app.get('/user/:id', (req, res) => {
res.render('user', {
title: 'Benutzerprofil',
user: {
name: 'Max Mustermann',
email: 'max@example.com',
age: 30
}
});
});| Option | Typ | Beschreibung |
|---|---|---|
defaultLayout |
String | Standard-Layout-Name (Standard: 'main') |
layoutsDir |
String | Pfad zum Layouts-Verzeichnis |
partialsDir |
String/Array | Pfad(e) zu Partials-Verzeichnissen |
extname |
String | Dateiendung (Standard: '.handlebars') |
helpers |
Object | Custom Helper-Funktionen |
compilerOptions |
Object | Handlebars Compiler-Optionen |
runtimeOptions |
Object | Handlebars Runtime-Optionen |
app.engine('handlebars', engine({
runtimeOptions: {
allowProtoPropertiesByDefault: true,
allowProtoMethodsByDefault: true
}
}));app.engine('handlebars', engine({
compilerOptions: {
strict: true,
noEscape: false
}
}));const { create } = require('express-handlebars');
const hbs = create({
extname: '.hbs',
helpers: {
section: function(name, options) {
if (!this._sections) this._sections = {};
this._sections[name] = options.fn(this);
return null;
}
}
});
app.engine('.hbs', hbs.engine);
app.set('view engine', '.hbs');app.get('/page', (req, res, next) => {
res.render('page', { data }, (err, html) => {
if (err) {
console.error(err);
return next(err);
}
res.send(html);
});
});helpers: {
fullName: function() {
return `${this.firstName} ${this.lastName}`;
}
}Verwendung:
// Layout: main.handlebars
<!DOCTYPE html>
<html>
<head>
{{{_sections.head}}}
</head>
<body>
{{{body}}}
{{{_sections.scripts}}}
</body>
</html>
// View: page.handlebars
{{#section 'head'}}
<link rel="stylesheet" href="/css/custom.css">
{{/section}}
<h1>Inhalt</h1>
{{#section 'scripts'}}
<script src="/js/custom.js"></script>
{{/section}}