NodeJs 中的 HTML 模板
- 💂 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】
- 🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】
- 💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】
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.html或template-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 flagreturn 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 Overviewif(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 的方法。
⭐️ 好书推荐
《特效师手册:影视剪辑与特效制作从入门到精通(剪映版)》

【内容简介】
本书根据作者多年的特效制作经验,结合目前年轻人喜爱的短视频特效,设计、讲解了 11 章内容,包括影视剪辑与特效基础、画面特效与人物特效、使用蒙版合成画面、混合模式合成效果、用关键帧制作特效、掌握剪映抠图特效、剪辑影视解说视频、制作影视字幕特效,以及制作热门的武侠类特效、仙侠类特效和科幻类特效等,帮助读者在较短的时间内,从新手成为剪映影视剪辑和特效制作高手。本书既讲解了如何在剪映电脑版中进行影视剪辑与特效制作,也讲解了剪映手机版的案例制作步骤,让读者买一本书精通剪映的两个版本,轻松玩转剪映电脑版 + 手机版,随时随地制作出精彩的影视混剪与特效视频。
📚 京东自营购买链接:《特效师手册:影视剪辑与特效制作从入门到精通(剪映版)》
相关文章:
NodeJs 中的 HTML 模板
💂 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 HTML 模板是一种允许我…...
3.ffmpeg命令行环境搭建、ffmpeg命令行初步了解
在上章,我们讲过: ffmpeg.exe: 主要用于转码或者剪切的应用程序, 也可以从url/现场音频/视频源抓取输入源ffplay.exe: 主要用于播放视频的应用程序,该应用程序源码是开源的,我们后面章节会去源码分析ffprobe.exe: 主要用于分析视频码流的应用程序, 可以获取媒体文件的详细信息,…...
Kubernetes初始化容器
初始化容器 之前了解了容器的健康检查的两个探针:liveness probe(存活探针)和readiness probe(可读性探针)的使用方法,我们说在这两个探针是可以影响容器的生命周期的,包括我们之前提到的容器的…...
leetcode: Swapping Nodes in a Linked List
leetcode: Swapping Nodes in a Linked List1. 题目描述2. 题目解答3. 总结1. 题目描述 You are given the head of a linked list, and an integer k.Return the head of the linked list after swapping the values of the kth node from the beginning and the kth node f…...
Nydus 在约苗平台的容器镜像加速实践
文 | 向申 约苗平台运维工程师 关注云原生领域 本文字数 9574阅读时间24分钟 本文是来自向申同学的分享,介绍了其在 K8s 生产环境集群部署 Nydus 的相关实践。 Nydus 是蚂蚁集团,阿里云和字节等共建的开源容器镜像加速项目,是 CNCF Dragon…...
企业对不同形态CRM系统价格需求不同
很多企业在选型时关心CRM客户管理系统的价格,有人对CRM的价格完全没有概念,也有的人先问价格再看其他。CRM价格在系统选型中到底有多重要?不同类型CRM系统的价格是否有所不同? CRM的不同产品形态也会影响价格 通常情况下&#x…...
「JVM 高效并发」线程安全
面向过程编程,把数据和过程分别作为独立的部分考虑,数据代表问题空间中的客体,程序代码则用于处理这些数据;面向对象编程,把数据和行为都看做对象的一部分,以符合现实世界的思维方式来编写和组织程序&#…...
微信扫码登录
一、准备工作 微信开发者平台:https://open.weixin.qq.com 1、注册 2、邮箱激活 3、完善开发者资料 4、开发者资质认证:仅能企业注册(后面提供学习的使用渠道)准备营业执照,1-2个工作日审批、300元 5、创建网站应用&…...
Unity协程的简单应用
Unity协程是一种特殊的函数,可以让你在Unity中创建一种类似于多线程的异步操作。它可以在需要等待某个操作完成时,暂停执行当前代码,等待某个条件满足后再继续执行。 在一般情况下 unity中调用函数时,函数将运行到完成状态&#x…...
LeetCode 1250. Check If It Is a Good Array【数论】
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
ETHDenver 2023
ETHDenver是全球最大、持续时间最长的以太坊活动之一,今年的活动定于2月24日至3月5日在美国科罗拉多州丹佛市盛大举行。这次活动将面向以太坊和其他区块链协议爱好者、设计者和开发人员。Moonbeam作为ETHDenver 2023的Meta赞助商,将在本次活动中展示令人…...
React架构演变
老版React架构 React 16之前的架构 其实就分为两个部分: Reconciler协调器Render渲染器 Reconciler协调器负责本次更新有什么组件需要被渲染,diff算法就发生在这个步骤中,在diff算法中会将上次更新的组件和本次更新的组件做一个对比&…...
安全认证--JWT介绍及使用
安全认证--JWT介绍及使用1.无状态登录原理1.1.什么是有状态?1.2.什么是无状态1.3.如何实现无状态1.4.JWT1.4.1.简介1.4.2.数据格式2.编写JWT工具2.1.添加JWT依赖2.2.载荷对象2.3.工具2.4.测试2.4.1.配置秘钥2.4.2.测试类1.无状态登录原理 有状态登录和无状态登录详…...
【计算机组成原理】计算机硬件的基础组成、认识各个硬件部件
计算机组成原理(一) 计算机内部是通过电信号传递数据 电信号:分为高电平和低电平,分别代表1/0 数字、文字、图像如何用二进制表示? CPU如何对二进制数进行加减乘除? 如何存储这些二进制数的? 如何从内存中取出想要的数…...
使用ChIPSeeker进行ChIP-seq, ATAC-seq,cuttag等富集峰的基因组注释
二代测序产生的数据类型 常规的下一代高通量测序(next generation sequencing, NGS)实验通常产生大量短片段(reads),通常我们需要将这些reads比对到参考基因组/转录组上,即将它们置于生物学上有意义的基因背景下,才能…...
第九届蓝桥杯省赛——7缩位求和
题目:在电子计算机普及以前,人们经常用一个粗略的方法来验算四则运算是否正确。比如:248 * 15 3720把乘数和被乘数分别逐位求和,如果是多位数再逐位求和,直到是1位数,得2 4 8 14 > 1 4 5;1 5 65…...
【c++】STL常用容器5—list容器
文章目录list基本概念list构造函数list赋值和交换list大小操作list插入和删除list数据存取list反转和排序list基本概念 功能:将数据进行链式存储。 链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链…...
【牛客刷题专栏】0x0D:JZ5 替换空格(C语言编程题)
前言 个人推荐在牛客网刷题(点击可以跳转),它登陆后会保存刷题记录进度,重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏:个人CSDN牛客刷题专栏。 题目来自:牛客/题库 / 在线编程 / 剑指offer: 目录前言问题…...
聚观早报 | 苹果2024年放弃高通;腾讯回应进军类 ChatGPT
今日要闻:苹果2024年放弃高通;腾讯回应进军类 ChatGPT;小米发布无线AR眼镜探索版;50%的美国企业已在使用ChatGPT;Snap推出ChatGPT驱动的聊天机器人 苹果2024年放弃高通 高通公司 CEO 兼总裁克里斯蒂亚诺・安蒙…...
Elasticsearch:如何正确处理 Elasticsearch 摄取管道故障
在我之前的文章 “Elastic:开发者上手指南” 中的 “Ingest pipeline” 章节中个,我有很多文章是关于 ingest pipeline 的。在今天的文章中,我将重点介绍如何处理在摄取管道中的错误。在我之前的文章 “Elasticsearch:如何处理 in…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
