简介
EJS (Embedded JavaScript) 是一种简单的模板语言,用于在 HTML 中嵌入 JavaScript 代码。
基本语法
1. 输出转义数据
<%= variable %>
HTML 转义输出,防止 XSS 攻击
2. 输出非转义数据
<%- htmlContent %>
原样输出 HTML 内容
3. 执行 JavaScript 代码
<% JavaScript code %>
执行逻辑代码,不输出内容
输出数据
<!-- 转义输出 --> <p><%= user.name %></p> <!-- 非转义输出 --> <div><%- user.bio %></div> <!-- 输出属性 --> <input value="<%= user.email %>"> <!-- 在属性中使用 --> <a href="/users/<%= user.id %>">Profile</a>
逻辑控制
条件语句
<% if (user.isAdmin) { %>
<button>Admin Panel</button>
<% } %>
<% if (score >= 90) { %>
<p>A Grade</p>
<% } else if (score >= 80) { %>
<p>B Grade</p>
<% } else { %>
<p>C Grade</p>
<% } %>
循环语句
<!-- 数组循环 -->
<ul>
<% users.forEach(function(user) { %>
<li><%= user.name %></li>
<% }) %>
</ul>
<!-- 带索引的循环 -->
<% users.forEach(function(user, index) { %>
<div class="user-<%= index %>">
<%= user.name %>
</div>
<% }) %>
<!-- for 循环 -->
<% for (let i = 0; i < products.length; i++) { %>
<div><%= products[i].name %></div>
<% } %>
Switch 语句
<% switch (status) { %>
<% case 'active': %>
<span class="active">Active</span>
<% break; %>
<% case 'inactive': %>
<span class="inactive">Inactive</span>
<% break; %>
<% default: %>
<span class="unknown">Unknown</span>
<% } %>
包含模板
基本包含
<%- include('header') %>
<main>
<h1>Page Content</h1>
</main>
<%- include('footer') %>
包含并传递数据
<%- include('user-card', {user: currentUser}) %>
<%- include('product-list', {products: featuredProducts}) %>
包含相对路径模板
<%- include('./partials/navbar') %>
<%- include('../components/modal') %>
布局和局部
简单布局系统
<!-- layout.ejs -->
<!DOCTYPE html>
<html>
<head>
<title><%- title %></title>
</head>
<body>
<%- include('header') %>
<%- body %>
<%- include('footer') %>
</body>
</html>
<!-- page.ejs -->
<%
const layoutData = {
title: 'My Page',
body: `
<main>
<h1>Welcome</h1>
<p>Page content here</p>
</main>
`
};
%>
<%- include('layout', layoutData) %>
注释
EJS 注释
<%# 这是EJS注释,不会输出到HTML %> <%# 多行注释 这些内容不会被渲染 %>
HTML 注释
<!-- 这是HTML注释,会输出到客户端 -->
自定义分隔符
在代码中配置
// Node.js 中配置
const ejs = require('ejs');
ejs.delimiter = '?'; // 使用 ? 作为分隔符
// 现在可以使用
// ?= variable ?
// ?- htmlContent ?
// ? JavaScript code ?
在模板中配置(某些版本支持)
<% const { delimiter } = require('ejs'); %>
<% delimiter = '$'; %>
<!-- 现在可以使用 -->
<$= variable $>
实用技巧
1. 三元运算符
<span class="<%= isActive ? 'active' : 'inactive' %>"> <%= isActive ? 'Online' : 'Offline' %> </span>
2. 函数调用
<p><%= formatDate(post.createdAt) %></p> <p><%= calculateTotal(price, quantity) %></p>
3. 对象和数组操作
<!-- 对象属性 -->
<%= user.profile?.address?.city %>
<!-- 数组方法 -->
<%= items.map(item => item.name).join(', ') %>
<!-- 数组长度 -->
<span><%= posts.length %> posts</span>
4. 模板字面量风格
<% const fullName = `${user.firstName} ${user.lastName}`; %>
<h1><%= fullName %></h1>
5. 避免 XSS
<!-- 安全:转义输出 --> <p><%= userInput %></p> <!-- 危险:非转义输出 --> <p><%- userInput %></p> <!-- 可能包含恶意脚本 --> <!-- 安全的使用方式 --> <div><%- trustedHtml %></div> <!-- 只有确定安全的内容 -->
6. 错误处理
<% if (typeof user !== 'undefined') { %>
<p><%= user.name %></p>
<% } else { %>
<p>User not found</p>
<% } %>
示例模板
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<%- include('partials/header') %>
<main class="container">
<h1>Welcome, <%= user.name %>!</h1>
<% if (user.isAdmin) { %>
<div class="admin-panel">
<button>Manage Users</button>
</div>
<% } %>
<h2>Products</h2>
<div class="products">
<% products.forEach(function(product) { %>
<div class="product-card">
<h3><%= product.name %></h3>
<p>Price: $<%= product.price %></p>
<% if (product.onSale) { %>
<span class="sale-badge">On Sale!</span>
<% } %>
</div>
<% }) %>
</div>
<% if (products.length === 0) { %>
<p>No products found.</p>
<% } %>
</main>
<%- include('partials/footer') %>
</body>
</html>
评论加载中...