Type-safe HTML templating in Zig(lalinsky.com) |
Type-safe HTML templating in Zig(lalinsky.com) |
Is there maybe a Zig wrapper for Google soy around?
This is kind of funny remark, given that the author started in 2000 in Web development, and with PHP 3.0.
I started in 1997, our distributed systems class had exercises to write CGIs in Perl and C.
Between 1999 and 2001, most Web development at my employer was in Tcl and C, ASP was naturally a mix of VB and C++ COM components, and there was also the fun to write all those mod_something Apache extensions, and IIS ISAPI modules, naturally in C and C++.
Ah, Microsoft was also shipping ATLServer, because who wouldn't want to use ATL for Web development, while Borland/Inprise was shipping similar stuff for Delphi and C++ Builder.
PHP itself, in 3.0, it was still the time that it hardly had much functionality builtin, so it was quite common to write extension modules in C.
So it is kind of ironic to read coming back to the way things were, before the slow scripting languages takevover in the 2010's, is something no one thought about.
Hence HTML as a mere vocabulary making use of SGML's facilities didn't need to define its own ad-hoc mechanism.
Btw the <?php ...> construct is also derived from SGML. In SGML terms it's a "processing instruction" rather than an "entity reference", the latter being the basic means for content inclusion.
https://web.dev/articles/imports
Been there, tried that.
Introduced in 2014 (Chrome 36) Deprecated 2018 (Chrome 70) Retired 2019 (Chrome 73)
Why is there no direct support for templating in HTML itself?
<!-- #include file="header.html" -->
https://en.wikipedia.org/wiki/Server_Side_IncludesFor examples, see http://www.impredicative.com/ur/demo/
As for Django... well.. Django only has text formatting, you can write any garbage and broken html and lots of invalid templates with silent failures there unfortunately.
me% cat index.m4
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Better user history</title>
<link rel="stylesheet" href="local.css">
</head>
<body>
<h3>Users</h3>
<ul>
<li><em>By username</em></li>
<ul>
sinclude(`byuser.m4')dnl
</ul>
<li><em>By last login date</em></li>
<ul>
sinclude(`bydate.m4')dnl
</ul>
</ul>
sinclude(`footer.m4')dnl
</body>
</html>
me% cat byuser.m4
<li><a href="byuser/A-L">A-L</a></li>
<li><a href="byuser/M-Z">M-Z</a></li>
me% cat bydate.m4
<li><a href="bydate/2025">2025</a></li>
<li><a href="bydate/2026">2026</a></li>
me% cat footer.m4
<p><em>Last update: syscmd(`date | tr -d "\n"')</em>
me% m4 index.m4 > index.htm
me% cat index.htm
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Better user history</title>
<link rel="stylesheet" href="local.css">
</head>
<body>
<h3>Users</h3>
<ul>
<li><em>By username</em></li>
<ul>
<li><a href="byuser/A-L">A-L</a></li>
<li><a href="byuser/M-Z">M-Z</a></li>
</ul>
<li><em>By last login date</em></li>
<ul>
<li><a href="bydate/2025">2025</a></li>
<li><a href="bydate/2026">2026</a></li>
</ul>
</ul>
<p><em>Last update: Mon Oct 12 03:08:32 EDT 2026</em>
</body>
</html>Using a template engine means you systematically ensure that values are escaped (at least, that's one of the reasons i would choose an engine over raw dogging the html).
#[component]
pub fn HomePage(user: Option<User>) -> Element {
rsx! {
Layout {
title: "Home",
if let Some(u) = user {
h1 { "Welcome back, {u.name}!" }
a { href: "/users/{u.id}", "Your profile" }
} else {
h1 { "Welcome, guest!" }
a { href: "/login", "Log in" }
}
}
}
}That's not HTML though, you have to learn a whole new dsl that must conform to rust parser rules. So, not the same thing at all.
#[component]
fn App() -> impl IntoView {
let (count, set_count) = signal(0);
view! {
<button
on:click=move |_| set_count.set(3) >
"Click me”</button>
<p>{move || count.get() * 2}</p>
}
}eg
html! {
<div onclick=|_ev: web_sys::MouseEvent| {}>
You can type text right into the elements
{ component }
{ text_var }
</div>
};this is rsx, but there are other macros that look just like html. i prefer this though, it's much more compact and readable imo
(but yes- I used these a lot like 25 years ago)