এই কোর্সের আগের প্রতিটা lesson হয় JSON return করেছে (একটা REST API) বা একটা আলাদা frontend ধরে নিয়েছে। একটা template engine traditional বিকল্প — server সরাসরি সম্পূর্ণ HTML পেজ render করে, placeholder-এ data plug in করে।
import express from 'express'
const app = express()
app.set('view engine', 'ejs')
app.set('views', './views') // template file কোথায় থাকে<!-- views/profile.ejs -->
<!DOCTYPE html>
<html>
<head><title><%= user.name %>'s Profile</title></head>
<body>
<h1>Welcome, <%= user.name %>!</h1>
<p>Email: <%= user.email %></p>
</body>
</html><%= value %> একটা মান output করে, নিরাপত্তার জন্য স্বয়ংক্রিয়ভাবে escape করা (আগের Cybersecurity কোর্সের XSS-prevention lesson-এর একই escaping ধারণা) — HTML-দেখতে character থাকলেও plain টেক্সট plain টেক্সট থাকে।
app.get('/profile/:id', async (req, res) => {
const user = await getUser(req.params.id)
res.render('profile', { user })
})<ul>
<% products.forEach(function(product) { %>
<li><%= product.name %> — $<%= product.price %></li>
<% }) %>
</ul>
<% if (user.isAdmin) { %>
<a href="/admin">Admin Panel</a>
<% } %><% ... %> (কোনো = ছাড়া) সরাসরি কিছু output না করে JavaScript logic চালায় — loop আর conditional এই form ব্যবহার করে।
<!-- views/partials/header.ejs -->
<header><h1>My Site</h1></header>
<!-- views/profile.ejs -->
<%- include('partials/header') %>
<h2>Profile</h2><%- %> (একটা dash সহ) raw, unescaped HTML output করে — include()-এর জন্য দরকার কারণ একটা partial-এর নিজের HTML escape করে ফেলা উচিত না।
| Tag | উদ্দেশ্য |
|---|---|
| <%= value %> | একটা মান output করে, HTML-escaped |
| <%- html %> | Raw HTML output করে, escaped না (include-এর জন্য ব্যবহৃত) |
| <% code %> | JavaScript logic চালায় — কোনো output না |
বেশ কয়েকটা template engine-এর একটা
EJS বেশ কয়েকটা option-এর একটা (Pug আর Handlebars common বিকল্প) — underlying ধারণা (data plug in করা server-rendered HTML) সবগুলোতেই একই, এই lesson-এর সিনট্যাক্স EJS-নির্দিষ্ট।