Nodejs新版express中ejs模板编译显示函数未定义 partial,link_to等无法使用

Nodejs新版express中ejs模板编译显示函数未定义 partial,link_to等无法使用

<ul>
<% for(var i=0; i<items.length; i++){ %>
<li><%= link_to(items[i],‘supplies/’+items[i]) %></li>
<% } %>
</ul>

代码是这个样子的,然后出现500错误,在模板编译的时候

link_to is not defined

    at eval (eval at (D:\nodejs\test\node_modules\ejs\lib\ejs.js:226:12))
    at exports.compile (D:\nodejs\test\node_modules\ejs\lib\ejs.js:228:15)
    at Object.exports.render (D:\nodejs\test\node_modules\ejs\lib\ejs.js:266:13)
    at View.exports.renderFile [as engine] (D:\nodejs\test\node_modules\ejs\lib\ejs.js:292:22)
    at View.render (D:\nodejs\test\node_modules\express\lib\view.js:75:8)
    at Function.app.render (D:\nodejs\test\node_modules\express\lib\application.js:504:10)
    at ServerResponse.res.render (D:\nodejs\test\node_modules\express\lib\response.js:677:7)
    at exports.index (D:\nodejs\test\routes\index.js:7:7)
    at callbacks (D:\nodejs\test\node_modules\express\lib\router\index.js:165:11)
    at param (D:\nodejs\test\node_modules\express\lib\router\index.js:139:11)

下面这些完全看不懂了,不知道是哪里的问题,ejs引擎是肯定安装了。

反正用任何函数都不行了,还有partial函数


8 回复

Node.js 新版 Express 中 EJS 模板编译显示函数未定义:partial, link_to 等无法使用

问题描述

在使用 Node.js 和 Express 框架时,如果你尝试使用 EJS 模板引擎,并且在模板中调用了一些自定义函数(如 link_topartial),可能会遇到类似以下的错误:

link_to is not defined

这通常是由于这些函数没有被正确地传递给 EJS 模板引擎。

示例代码

假设你有以下的 EJS 模板文件 (views/index.ejs):

<ul>
<% for(var i=0; i<items.length; i++){ %>
    <li><%= link_to(items[i], 'supplies/' + items[i]) %></li>
<% } %>
</ul>

在你的 Express 路由文件 (routes/index.js) 中,你可能有类似的代码:

const express = require('express');
const router = express.Router();
const ejs = require('ejs');

router.get('/', function(req, res) {
    const items = ['item1', 'item2', 'item3'];
    res.render('index', { items: items });
});

module.exports = router;

解决方案

要解决这个问题,你需要确保在渲染模板之前将所有自定义函数传递给 EJS 模板引擎。你可以通过以下方式来实现:

  1. 创建一个中间件,用于在渲染模板之前注入这些函数。
// app.js 或 server.js
const express = require('express');
const app = express();
const path = require('path');

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use((req, res, next) => {
    res.locals.link_to = function(item, url) {
        return `<a href="${url}">${item}</a>`;
    };

    res.locals.partial = function(template, data) {
        return ejs.renderFile(path.join(app.get('views'), template), data);
    };

    next();
});

const indexRouter = require('./routes/index');
app.use('/', indexRouter);

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});
  1. 更新路由文件,使其不再直接传递数据到模板。
// routes/index.js
const express = require('express');
const router = express.Router();

router.get('/', function(req, res) {
    const items = ['item1', 'item2', 'item3'];
    res.render('index', { items: items });
});

module.exports = router;

总结

通过上述方法,你可以确保在渲染 EJS 模板时,所有的自定义函数都能被正确地传递和使用。这样可以避免 link_to is not defined 这样的错误,并使你的模板更加灵活和可复用。


paritals 我可以用的,link_to不能用,我安装了 express-partials,可能新ejs把link_to也分离出去了?

express-partials 原来这个还需要额外安装,如果我在package.json如何写呢?如果没有就说个普通安装法吧

ejs用include来替代paritals了吧.

npm install express-partials

在app.js里面引用express-partials:

var partials = require('express-partials'); 

app.set('view engine', 'ejs');下面添加

app.use(partials());

3.在需要引用模板的地方调用layout:'模版名称’

示例

app.get('/list', function(req, res){
    res.render('list', {
        title: 'List',
        items: [1991,'byvoid','express', 'Node.js'],
        layout:"list"
    });
});

重要的一点 app.use(partials());需要放在 app.use(app.routes())之前。

app.use(partials());

放在

app.use(app.routes())

之前

在新版的Express中使用EJS模板时,如果你尝试调用自定义的函数(如link_topartial)但遇到"函数未定义"的错误,那是因为默认情况下EJS不包含这些函数。你需要手动定义这些函数或者通过中间件的方式将它们注入到EJS的上下文中。

示例解决方案

首先,确保你已经正确安装了EJS模块:

npm install ejs --save

然后,你可以创建一个中间件来注入这些函数。例如,假设你想使用link_to函数:

// app.js 或你的主文件
const express = require('express');
const app = express();
const path = require('path');

// 设置视图引擎为EJS
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// 注册中间件以添加自定义函数
app.use((req, res, next) => {
  res.locals.link_to = function(item, url) {
    return `<a href="${url}">${item}</a>`;
  };
  next();
});

// 路由示例
app.get('/', (req, res) => {
  const items = ['Item 1', 'Item 2', 'Item 3'];
  res.render('index', { items });
});

app.listen(3000, () => console.log('App listening on port 3000'));

EJS模板 (views/index.ejs)

现在你的模板可以这样写:

<ul>
<% items.forEach(function(item){ %>
    <li><%- link_to(item,'supplies/'+item) %></li>
<% }) %>
</ul>

注意事项

  • 使用<%-而不是<%= 来输出HTML内容,避免转义。
  • 确保你的自定义函数定义在EJS模板渲染之前。

通过这种方式,你可以轻松地将自定义函数添加到EJS模板的上下文中,并且不再会遇到“函数未定义”的错误。

回到顶部