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.
The typesafety you get is what you already have in Kotlin, and there a little extra in that you cannot nest certain HTML-elements in certain other elements (adhering to the HTML spec). You can come up with your own elements and attributes, but the ones that are in the HMTL-spec are usually available in kotlinx.html as well (and thus can be auto-completed).
A large part of this library is generated from the actual HTML spec.
Claude Code seems to have not problem writing it (I barely write templates myself these days).
https://github.com/kotlin/kotlinx.html
https://dzone.com/articles/modern-type-safe-template-engines...
Sure I hack a 'Sup World in C every 100 years just to get that feeling you get when you stumble into semi-accomplishment but to consider a low-level lang executable as a product that I produce, maintain and develop expertise/taste with?
Regarding web dev in any low-level lang: once you get that there's a parenthetical "services" between the words "web" and "development", the quest for the languages that offer speed, reliability, etc becomes inevitable
Looking forward to seeing some benchmarks!
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)
<!-- #include file="header.html" -->
https://en.wikipedia.org/wiki/Server_Side_Includes(but yes- I used these a lot like 25 years ago)
Why is there no direct support for templating in HTML itself?
Eg some template feature creates a security issue and has to be disabled, which invalidates all the old HTML that used it.
There’s also just not a super great reason to do it. It’s not all that different from pre-templating like Hugo or doing it server-side like Django. You get to offload some compute, but HTML templating isn’t usually the bottleneck.
This might be the worst argument for anything I've read this week, there's got to be a name for this logical fallacy
i.e. MyTemplate.tpl.html
{if $foo}hello world, {$myname}!{else}goodbye, world.{/if}
which creates a kotlin class that can be used like this: MyTemplate(
foo = true,
myname = "bar"
).toString()
the biggest upside for me is that this way there's full, free IDE support, i don't need to write extra view models if the mapping isn't 1:1 and performance is pretty good because in the end there's no runtime parsing/compiling/interpreting except for the baseline JDK stuff (though there are even faster engines).https://codeberg.org/h34tnet/tempolin
warning: so far i'm the only user though, so don't use it in production. also, i'm working on some improvements right now which haven't been pushed yet.
It never occurred to me, either! This is really neat! How does it work?
EDIT: Never mind, seems like it's a custom file format that gets compiled to Zig code. Still quite neat but unfortunately you lose all the IDE support.
I think there is a way to do syntax extensions cleanly, with a special block type like `'{ }` that gets tokenized and passed to a comptime function skipping the parser. But one of Zig's main selling points is no hidden control flow and they want to keep it that way.
Is there maybe a Zig wrapper for Google soy around?
The design point "deterministic, hostable, with enough to make hooks from the templates" is what makes it special: https://lucasdicioccio.github.io/tramaj/ .
For 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.
It looks like you'd have to implement something equivalent to provider/context functionality yourself if you want it, as well as a simple render()-like helper to render a component tree. I've not tried their VS Code plugin, but it's a good sign that they have one.
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).
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>1. https://ziggit.dev/t/making-it-harder-to-swallow-error-cance...
The fact that error handling suffers when combining two of the base interfaces of the standard library is pretty rough though? I don't think rust has that particular problem.
There is a similar issue in kotlin where a cancellation is marked via a CancellationException but that extends IllegalStateException and thus Exception. Because of that it gets caught and swallowed all the time. This is a constant source of bugs for me at work and google has resorted to a bunch of linting to get around this design mistake.
I get the pain, but the answer from Scott Redig totally makes sense. I am not sure what is worse: Libraries swallowing cancelled() or libraries lying that they support cancelled.
> Libraries swallowing cancelled() or libraries lying that they support cancelled.
For me former is obviously worse.
#[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>
}
} on:click=move |_| set_count.set(3) >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
That would be great, I really like openness and ~plugin interfaces of jai compiler internals ...