EJS包含与项目根

时间:2016-07-20 18:17:08

标签: node.js express ejs

我正在使用Express和EJS来构建一个站点 我有一个目录结构,如:

+--www/
  |
  +--partials/
  | |
  | +--header.ejs
  | +--(a bunch of ejs files)
  |
  +--guide
  | |
  | +--index.html
  | +--(other files)
  |
  +--index.html

在我的示例中显示的两个index.html文件中,<% include ... %>命令会有所不同,即使引用相同的包含文件也是如此。

此外,如果我说包括header.ejs然后header.ejs包含另一部分内容,则整个系统会崩溃,因为他们都在寻找不同位置的文件。

为了简化管理,我试图找到一个字符串,以便能够引用相同的包含文件,而不管文件可能位于哪个子目录中。

理想情况下<% include /partials/header.ejs %>之类的东西会很完美。但这不起作用。

有没有人有任何可以在这里得到预期结果的技巧或建议?

3 个答案:

答案 0 :(得分:3)

(其他解决方案看起来有点复杂,所以我决定也在这里发送我的答案)。 That other question related to this subject

我找到了解决办法。我不知道如果你在在线网站上使用它会发生什么!

  1. 首先创建一个名为 app.locals.js 的文件并在其中写入以下代码:
module.exports = {
    static: process.cwd() + "/static/",
    views: process.cwd() + "/views/",
    layouts: process.cwd() + "/views/layouts/",
    pages: process.cwd() + "/views/pages/",
    partials: process.cwd() + "/views/partials/",
    components: process.cwd() + "/views/components/",
}
  1. app.js 文件中:
const express = require("express");
const appLocals = require("./app.locals");

const app = express();
app.locals = appLocals;
  1. 像这样使用它:
<%- include(components + "post.ejs") %>
<%- include(partials + "header.ejs") %>

您不需要在 .ejs 文件中导入任何内容。您可以直接访问componentspartials

如果你知道更多,如果你可以改进代码,请写评论什么的。谢谢。

答案 1 :(得分:2)

看起来这不受EJS的支持,但我找到了解决此问题的方法。 在上面的设置中,痛点是所有部分文件,你需要提到相对路径,如果你重构代码变得更加痛苦。因此,相反提及每个包含的相对路径我声明一个变量rootPath一次,然后我给出了到达家的路径。因此,在每个包含中,我都可以简单地提到相对路径,就像从根路径那样。

例如在guide/index.ejs中,我在ejs文件的顶部提到以下内容

<% var rootPath = '../'; %>

和ejs文件中的代码如下所示

<%- include(rootPath + 'partials/header'); %>

您的HTML代码

<%- include(rootPath + 'partials/footer'); %>

因此,如果我将index.ejs重构为其他文件夹,我需要做的就是更改rootPath的值

答案 2 :(得分:0)

这是一个很好的问题,这是我直到最近才遇到的一个问题。

实际上,似乎没有直接而集中的方法来获得Web根目录……这似乎不是节点,也不是快速开发人员认为这很有价值。

但是,有一些可用的工具可以提供帮助,但不能直接解决问题。

一般方法:

  1. 从初始文件(实例化express的文件)​​中获取根
  2. 将其放入变量
  3. 将该变量获取到模板中

方法一-全局变量
我发现的第一项工作是可以通过的。 它利用了将变量设置为全局范围的功能。 这并不理想,但是如果您想查看更多内容,请点击HERE

重要提示: 以下所有要求在Express应用程序的主文件(实例化Express应用程序的文件)中,将变量设置为当前工作目录。
我知道的三种方法是

  1. __目录
  2. path.dirname(require.main.filename);
  3. path.resolve();

我相信第二种方法有一个优势,但是我不记得它现在是什么...而且我不确定它是否可以在最新版本(14.x)的节点中使用...我开始了我开始使用14.5时将其更改为3 ...

方法二-传递变量
我认为第二种解决方法是最糟糕的...它可以工作,但是如果您没有简单的设置,则可能变得站不住脚。 此方法是通过路径传递变量。 看起来像这样:

router.get('/', (request, response) => 
{
  response.render('PATH TO TEMPLATE', {dataItem1: 'DATA STUFF TO PASS', dataItem2: 'MORE STUFF'});
});

方法三
这绝对是我喜欢的方法。 它使它变得更容易,更简单和更干净。 这里确实有两种方法,但是它们非常相似。

此方法利用了app.locals或response.locals。 当我说app时,我的意思是express的实例(无论您叫什么)。 这很简单:

  1. 创建一个中间件以在response.locals中传递变量
  2. 直接在app.locals上设置变量
    示例
const appDir = path.dirname(require.main.filename);

app.use((request, response, next) => 
{ 
    response.locals.someVar = 'value of someVar'; 
    response.locals.appDir = appDir;
    return next();
});
  1. app.locals.appDir = path.dirname(require.main.filename);//const path = require('path');

在两种情况下,这些值仅可在EJS模板中使用。
所以使用它们的样子:

<%= appDir %>