Express+Node.js项目中Handlebars无法在EJS文件渲染数据库内容
Express+Node.js中Handlebars模板嵌入EJS后无法渲染数据库变量
问题详情
单独渲染cars.hbs时,能正常展示从数据库获取的数据;但将该HBS文件嵌入包含导航栏、页脚的home.ejs文件后,Handlebars模板变量直接显示,无法被解析为数据库内容。
相关代码
cars.hbs
<!DOCTYPE html> <html> <body> <p> The {{dbcar.model}} features a {{dbcar.specs.engine}} engine... </p> </body> </html>
注:已修正变量名与路由传入的
dbcar统一,原代码中dbcars与路由的dbcar不匹配也会导致渲染失败
home.ejs
<body> <p> <%- include('navbar.ejs') %> </p> <p> <%- carHtml %> </p> <p> <%- include('footer.ejs') %> </p> </body> </html>
car.js(原代码)
router.get('/vehicle/:id', async (req, res) => { Car.findById(req.params.id, function(err, carRouter) { res.render("home.ejs", { dbcar: carRouter }) }) })
当前结果
(navbar) The {{dbcar.model}} features a {{dbcar.specs.engine}} engine... (footer)
期望结果
(navbar) The Nissan Sentra features a 2.0 L 4-cylinder engine... (footer)
解决方案
核心原因:EJS的include方法仅会将目标文件的内容作为纯文本插入,不会触发Handlebars的模板编译逻辑。需要手动编译HBS模板并生成HTML后,再传递给EJS渲染。
- 确保项目已安装Handlebars:
npm install handlebars
- 修改路由代码,先编译HBS模板并生成HTML:
const fs = require('fs'); const handlebars = require('handlebars'); const path = require('path'); router.get('/vehicle/:id', async (req, res) => { Car.findById(req.params.id, function(err, carRouter) { // 读取HBS模板文件 const hbsPath = path.join(__dirname, '../views/handlebars/cars.hbs'); const hbsContent = fs.readFileSync(hbsPath, 'utf8'); // 编译Handlebars模板 const template = handlebars.compile(hbsContent); // 传入数据生成HTML字符串 const carHtml = template({ dbcar: carRouter }); // 将生成的HTML传给EJS渲染 res.render("home.ejs", { carHtml: carHtml }) }) })
- 调整
home.ejs,直接输出编译好的HTML:
将原来的<%- include('handlebars/cars.hbs') %>替换为<%- carHtml %>,如上述home.ejs代码所示。
补充说明
- 原代码中HBS模板的变量名
dbcars与路由传入的dbcar不匹配,需统一变量名才能正确渲染数据; - 若需要复用HBS模板,可将编译逻辑封装为工具函数,避免重复代码。
内容的提问来源于stack exchange,提问作者yegax
相关产品推荐
相关产品推荐

