Skip to content
TwitterDiscordGitHub

Introduction

🌐 HMPL (/ˈhæmpəl/ portmanteau of the words Cample and HTML) is a small template language for displaying UI from server to client. It is based on customizable requests sent to the server via fetch and processed into ready-made HTML. The language is syntactically object-based and integrated with JSON5 and DOMPurify. Reduce the size of your javascript files and display the same UI as if it was written in a modern framework!

The HTML you use on your site is enhanced by adding special blocks that resemble components in syntax, but are more like “helper blocks” like in Handlebars.

In these blocks you describe the request that will be sent to the server to get the finished components from there. This includes HTTP methods, request frequency and many other things that are used when talking about fetch.

To describe it more briefly, it is something in between HTMX and EJS 👀.

Unlike other similar modules, the template language provides more complete customization due to a well-thought-out balance between HTML and JS. HMPL supports modern EcmaScript standards - thanks to its well-thought-out functionality, you will not depend on versions.

Also, the template language format itself allows you to work with .hmpl extension files if you use Vite or WebPack.

You may have questions about the template language, here is a short list of those that were asked throughout the development cycle:

Is it necessary to use JavaScript?

No, you don’t have to use it with the hmpl-dom module, but the template language itself is fully configured for this.

Is it safe?

Yes, the template language is completely safe, as it only accepts text/html by default. If you are working with an uncontrolled API, the module also provides protection against XSS attacks. More information about security can be found here.

What is the difference between HTMX and Alpine.js?

We have written several articles on this topic, specifically about the differences from HTMX and Alpine.js

Can I use HMPL with modern frameworks?

Yes! HMPL is designed to work alongside modern frameworks. It’s something in between HTMX and EJS, providing a lightweight alternative for server-client communication without the overhead of full framework implementations.

<template data-hmpl data-config-id="clicker-config">
<div>
<button data-action="increment" id="btn">Click!</button>
<div>
Clicks: {{#request src="/api/clicks" after="click:#btn"}}{{/request}}
</div>
</div>
</template>
<script src="https://unpkg.com/json5/dist/index.min.js"></script>
<script src="https://unpkg.com/dompurify/dist/purify.min.js"></script>
<script src="https://unpkg.com/hmpl-js/dist/hmpl.min.js"></script>
<script src="https://unpkg.com/hmpl-dom/dist/hmpl-dom.min.js"></script>
<span class="counts"><?php $clicks ?></span>
<div>
<button data-action="increment" id="btn">Click!</button>
<div>Clicks: <span class="counts">0</span></div>
</div>
import { compile } from "hmpl-js";
const templateFn = compile(
`<div>
<form onsubmit="function prevent(e){e.preventDefault();};return prevent(event);" id="form">
<div class="form-example">
<label for="login">Login: </label>
<input type="login" name="login" id="login" required />
</div>
<div class="form-example">
<input type="submit" value="Register!" />
</div>
</form>
<p>
{{#request
src="/api/register"
after="submit:#form"
repeat=false
indicators=[
{
trigger: "pending",
content: "<p>Loading...</p>"
}
]
}}
{{/request}}
</p>
</div>`
);
const initFn = (ctx) => {
const event = ctx.request.event;
return {
body: new FormData(event.target, event.submitter),
credentials: "same-origin"
};
};
const obj = templateFn(initFn);
const wrapper = document.getElementById("wrapper");
wrapper.appendChild(obj.response);
Preview