如何在 EJS 视图中使用节点模块(如 MomentJS)?

Posted

技术标签:

【中文标题】如何在 EJS 视图中使用节点模块(如 MomentJS)?【英文标题】:How to use node modules (like MomentJS) in EJS views? 【发布时间】:2012-09-29 11:29:54 【问题描述】:

要在views/custom.ejs 中使用MomentJS,正确的方法是什么(如果有的话)?

    服务器端

    routes/index 等我们可以轻松使用require('moment'); 等,而且效果很好。

    服务器端(EJS 视图)

    views/custome.ejs,<% var m = require('moment'); %> 之类的东西不起作用

我使用 ExpressJS 和 EJS 作为模板引擎。

【问题讨论】:

【参考方案1】:

我找到了另一种方法,我认为它有一些优势。

不要污染您的代码导出过滤器。 无需全部导出即可访问任何方法。 更好地使用 ejs(无 | 管道)。

在您的控制器或 view.js 上执行以下操作:

var moment = require('moment');
exports.index = function(req, res) 
    // send moment to your ejs
    res.render('index',  moment: moment );

现在您可以在您的 ejs 中使用 moment:

<html>
    <h1><%= moment().fromNow() %></h1>
</html>

我不是 Node 专家,所以如果有人发现这样做有什么不好的地方,请告诉我! :)

【讨论】:

这是 IMO 最灵活的方式 工作完美,只需要组织将所有额外的库发送到模板。【参考方案2】:

另一种选择:

这样,您将 moment 变量设置为可用于您网站上任何 EJS 页面中所有脚本的本地变量。

在您的“index.js”(或“app.js”)文件中执行以下操作:(在使用 Express 设置您的“应用程序”之后)

var moment = require('moment');
var shortDateFormat = "ddd @ h:mmA"; // this is just an example of storing a date format once so you can change it in one place and have it propagate
app.locals.moment = moment; // this makes moment available as a variable in every EJS page
app.locals.shortDateFormat = shortDateFormat;

然后在您的 EJS 文件中,您可以将时刻(和 shortDateFormat)引用为如下变量:

<%= moment(Date()).format(shortDateFormat) %>

也许这更优雅一些?

【讨论】:

最干净的解决方案! 有什么特别的理由把它放在 app.locals 中,而不是使用 res.locals 来将时间传递给特定的视图吗? 我不记得了!我已经很长时间没有在这方面工作了。 :-)【参考方案3】:
var moment = require('moment');
app.locals.moment = require('moment');

在视图中使用:

<%= moment(myDateValue).fromNow() %>

现在您可以简单地在 EJS 文件中使用 moment。

【讨论】:

【参考方案4】:

我在服务器端使用 ejs 的时刻。我写了一个从Now返回的ejs过滤函数。

npm install moment

./views/page.ejs

<span class="created_at"><%=: item.created_at | fromNow %></span>

./routes/page.js

var ejs = require('ejs')
  , moment = require('moment');

ejs.filters.fromNow = function(date)
  return moment(date).fromNow()

【讨论】:

如果您导出时刻(日期)而不是函数,它可能会更灵活。可能有效,我没试过 | moment.fromNow【参考方案5】:

您可以创建函数并将其附加到 app.locals。并在服务端的ejs模板中使用。

在你的路线文件中你做

../routes/page.js

var ejs = require('ejs')
  , moment = require('moment');

app.locals.fromNow = function(date)
  return moment(date).fromNow();

../views/page.ejs

<span class="created_at"><%= fromNow(item.created_at) %></span>

请记住将时刻添加到您的 package.json 文件中

【讨论】:

我更喜欢这个,因为它只会将 ejs 与函数链接,而不是与模块链接。【参考方案6】:

像这样传递require怎么样:

res.render('index',  require: require );

您可能需要调整以保持路径:

res.render('index',  require: module => require(module /* here you may insert path correction */) );

显然这仅适用于 Node(后端)。

【讨论】:

这似乎是问题的唯一真正答案。干得好。需要尝试一下。 我能够在这个 repo 中得到这个工作:github.com/chriscalo/ejs-require。真正令人满意的解决方案。不知道为什么 EJS 模板不能以这种方式开箱即用。【参考方案7】:

您上面提到的服务器端(EJS 视图)是在浏览器上而不是在您的服务器上运行的。您不能使用 require ,因为浏览器无法理解它。需要导入 moment.js 才能使用

<script src="/js/moment.min.js"></script>

【讨论】:

谢谢@Vinoth 我现在正在查看渲染代码(浏览器端),我的 Layout.ejs 包括:&lt;script type="text/javascript" src="javascripts/moment.min.js"&gt;&lt;/script&gt; custom.ejs(视图)有代码使用 momentJS lib,例如var a = moment(new Date()); 这里@ 987654325@被发现为空。 查看此链接以了解如何使用它 - ***.com/questions/10967736/how-to-use-moment-js 据我了解,'' 和 '' 封闭的代码是在服务器端运行/渲染的,不是 在客户端。客户端只是将渲染(处理)的结果作为纯 html 获取,除非您明确使用 标记,该标记将在客户端运行。【参考方案8】:

我也认为如果你想添加一个中间件是个好主意,你可以在其中添加任何你想要的东西到主题层,包括用户、配置和时刻:

// config, user, moment to the theme layer
app.use(function (req, res, next) 
    // grab reference of render
    var _render = res.render;
    // override logic
    res.render = function (view, options, fn) 
        // extend config and continue with original render
        options = options || ;
        options.config = config;
        options.moment = moment;
        if (req.user && req.user.toJSON) 
            options.user = req.user.toJSON();
        
        _render.call(this, view, options, fn);
    
    next();
);

【讨论】:

【参考方案9】:

我写了一个助手来返回在ejs视图和布局上使用的时刻。

./helpers/utils/get-moment.js

const moment = require('moment');

module.exports = 
    friendlyName: 'formatMoney',
    description: 'format money number.',
    inputs: ,
    sync: true,
    exits: ,
    fn: function (inputs, exits) 
        return exits.success(moment);
    
;

然后使用:

const moment = sails.helpers.utils.getMoment();

【讨论】:

请解释您的代码行,以便其他用户了解其功能。谢谢!【参考方案10】:

从 Node v12.8.3 开始,您似乎可以将 require 直接传递给 EJS 模板,即这样可以:

const ejs = require('ejs')
let renderedHTML = ejs.render(`<% const moment = require('moment') %>`,  require )

【讨论】:

你能补充一点信息吗?如何在 ejs 中使用它

以上是关于如何在 EJS 视图中使用节点模块(如 MomentJS)?的主要内容,如果未能解决你的问题,请参考以下文章

节点 Ejs 模块,包括不工作

Node.js - 如何在 EJS 视图中使用我的局部变量

渲染 EJS 视图中的 Mongoose 对象到 CSV

如何让 Eclipse 将 .ejs 文件解释为 .html?

在 EJS 模板引擎中,如何“包含”页脚?

使用 ejs 模板和 MYSQL 在节点 js 中的服务器端分页