NodeJs 中的 HTML 模板

JavaScript/前端
478
0
0
2023-04-01
标签   NodeJs

HTML 模板是一种允许我们创建基本 HTML 结构并使用占位符根据从 JSON 文件或数据库中检索到的数据动态生成内容的技术。

让我们考虑一个假设实例,其中我们的网站包含许多产品卡,每个卡都包含从 JSON 文件中检索到的特定产品详细信息。

现在,如果我们要从 JSON 文件中添加或删除任何产品,我们将如何在前端动态更新相应的卡片?

考虑到我们基于内容的数据存储在 JSON 文件中,我们可以继续从现有的 HTML 代码创建可重用的模板。

第 1 步:构建模板

作为开发人员,您可能熟悉提供动态 Web 内容的概念。实现这一目标的一种方法是使用模板。

我们将创建两个 HTML 模板,一个用于产品概览页面,一个用于单个产品卡片。

第一个模板template-card.html用作单个产品卡片的蓝图,第二个模板template-overview.html用作概览页面的蓝图。这些模板包含占位符,当用户请求页面时,这些占位符将被替换为实际内容。

确保您的占位符不包含任何属于 HTML 代码的符号。占位符的常用语法是{%PLACEHOLDER_NAME%}.

这是template-card.html我们的第一个模板,用作根据需要动态创建尽可能多的卡片的蓝图。

<figure class="card">
    <div class="card__emoji">{%IMAGE%}{%IMAGE%}</div>
    <div class="card__title-box">
      <h2 class="card__title">{%PRODUCTNAME%}</h2>
    </div>

    <div class="card__details">
      <div class="card__detail-box">
          <h6 class="card__detail card__detail 
               {%NOT_ORGANIC%}"> Organic!</h6>
      </div>

      <div class="card__detail-box">
        <h6 class="card__detail">{%QUANTITY%} per 📦</h6>
      </div>

      <div class="card__detail-box">
        <h6 class="card__detail card__detail--price"> 
            {%PRICE%}€</h6>
      </div>
    </div>

    <a class="card__link" href="/product?id={%ID%}">
      <span>Detail <i class="emoji-right">👉</i></span>
    </a>
  </figure>

由于此卡片将用作模板,因此其中包含的信息也应替换为占位符。添加占位符后,卡片将类似于以下内容:

<figure class="card">
    <div class="card__emoji">🥦🥦</div>
    <div class="card__title-box">
      <h2 class="card__title">Apollo Broccoli</h2>
    </div>

    <div class="card__details">
      <div class="card__detail-box">
          <h6 class="card__detail card__detail--organic">Organic!</h6>
      </div>

      <div class="card__detail-box">
        <h6 class="card__detail">3🥦 per 📦</h6>
      </div>

      <div class="card__detail-box">
        <h6 class="card__detail card__detail- 
              price">5.50€</h6>
      </div>
    </div>

    <a class="card__link" href="/product?id=">
      <span>Detail <i class="emoji-right">👉</i></span>
    </a>
  </figure>

锚标记包含一个 href 链接,其中包含一个 ID 的占位符。这表明我们的 JSON 文件中的每张卡或产品都有一个不同的 ID。这些 ID 是唯一的,将用于在路由过程中识别每个产品。

此外,当我们需要根据元素的类别设置元素样式时,CSS 类和 ID 可以用占位符代替,就像在图像示例中所做的那样。这种方法在这种情况下特别有用。

<body>
  <div class="container">
    <h1>🌽 Node Farm 🥦</h1>

    <div class="cards-container">
      {%PRODUCT_CARDS%}
    </div>
  </div>
</body>

在此示例中,我们已将模板卡片替换为占位符。请务必记住,我们将使用这个单一模板卡片动态生成多张卡片。

注意:这是我们的第二张模板卡,template-overview.html

第 2 步:填充模板

有趣的部分来了,通过用实际内容替换我们的占位符来填充我们的模板。

当用户请求 URL 时,代码会同步读取相关模板文件(或者template-overview.htmltemplate-card.html),用 JSON 文件中的内容动态填充它,并将相关内容作为响应发回给用户。

这是通过使用函数实现的replaceTemplate,该函数用实际内容替换模板中的占位符。

// SECOND STEP:
const replaceTemplate = (temp, product) => {
    let output = temp.replace(/{%PRODUCTNAME%}/g, product.productName);
    output = output.replace(/{%IMAGE%}/g, product.image);
    output = output.replace(/{%PRICE%}/g, product.price);
    output = output.replace(/{%ID%}/g, product.id); 
     // /g is a regex global flag
    return output;
}

// FIRST STEP:
const tempOverview = fs.readFileSync(`${__dirname}/templates/template-overview.html`, 'utf-8');
const tempCard = fs.readFileSync(`${__dirname}/templates/template-card.html`, 'utf-8');
const data = fs.readFileSync(`${__dirname}/dev-data/data.json`, 'utf-8');
const dataObj = JSON.parse(data);

// THIRD STEP:
const server = http.createServer((req, res) => {
    const pathName = req.url;

    //FOURTH STEP:
    //Here is the Overview
    if(pathName === '/' || pathName === '/overview') {
        res.writeHead(200, {'Content-type': 'text/html'});
        const cardsHtml = dataObj.map(el => replaceTemplate(tempCard, el)).join('');
        const output = tempOverview.replace('{%PRODUCT_CARDS%', cardsHtml);

        res.end(output);

        //API
    } else if(pathName === '/api') {
        res.writeHead(200, {'Content-type': 'application/json'});
        res.end(data);
    // Not Found
    } else {
            res.writeHead(404, {
            'Content-type': 'text/html', //standard header
            'my-header': 'hello-world'
        });
        res.end('<h1>This page cannot be found.</h1>');
    }
});

server.listen(8000, '127.0.0.1', () => {
    console.log('Listening to requests on port 8000');
});
    res.writeHead(404, {
            'Content-type': 'text/html', //standard header
            'my-header': 'hello-world'
        });
        res.end('<h1>This page cannot be found.</h1>');
    }
});

server.listen(8000, '127.0.0.1', () => {
    console.log('Listening to requests on port 8000');
});

别担心,我们将仔细研究上面的大块代码,并用更简单的术语弄清楚它的作用。

  • 首先,读取两个 HTML 模板文件和存储在 JSON 文件中的产品数据
  • 其次,定义一个函数,用特定于产品的数据替换模板中的占位符。在这里,我们的函数被命名为replaceTemplate
  • 第三、监听传入的 HTTP 请求并检查请求 URL 的路径名
  • 第四,如果路径名为//overview,则使用replaceTemplatefunction和JSON文件中的产品数据替换tempCard模板中的占位符,为每个产品卡生成HTML代码。
  • 然后连接每张卡片的结果 HTML 以创建字符串cardsHtml。然后修改模板tempOverview以包含 cardsHtml 字符串,并将生成的 HTML 代码作为响应发回。
  • 此外,如果路径名是,/api它会以 JSON 格式发回产品数据作为响应
  • 最后,如果路径名是其他任何内容,则发回 404 错误消息。

哇,那段代码看起来确实很多,但如果我们仔细看,一步一步来,它并没有那么复杂。

它所做的只是用真实信息替换一些特殊词并将其发送回网站,以便人们可以看到它!

HTML 模板的好处

HTML 模板提供了几个好处,使其成为 Web 开发人员的热门选择:

  • 通过使用 HTML 模板,我们将内容与表示分离,允许开发人员生成可重复使用的模板,这些模板可以处理来自多个来源的不同数量的数据,并维护类似代码的多个副本。
  • HTML 模板为呈现数据、改善用户体验和轻松导航站点提供了标准结构。
  • 模板的灵活性使得修改底层数据变得更加容易。这节省了时间和精力,因为开发人员不需要手动更改 HTML 代码。
  • 由于 HTML 模板可重复使用,因此更易于维护和更新。可以在不修改模板代码的情况下对基础数据进行更改,从而降低出错的可能性。
  • HTML 模板可以在不影响性能的情况下处理大量数据。这使其成为具有大量动态内容的网站的理想选择。

总之,HTML 模板是一种高效、一致、灵活且可扩展的技术,可简化动态 Web 内容的开发和维护。

通过将内容与表示分离,HTML 模板使开发人员能够创建可重用的模板,这些模板可以处理不同数量的数据,而无需将内容硬编码到每个页面中。

拓展部分:

Node.js 中还有其他几个可用的模板引擎,例如 EJS、Pug(以前称为 Jade)、Handlebars 和 Mustache 等。

要在 Node.js 中使用模板引擎,您需要通过 npm 安装它,然后在您的代码中需要它。这些引擎提供了一种通过将数据插入模板内的占位符来生成 HTML 的方法。