///
Ztack's `html.zig` module provides a powerful, type-safe, and efficient way to programmatically generate HTML content in Zig. It focuses on minimizing allocations, enabling direct streaming to network
43 views
~43 views from guests
Guest views are estimated from total page views. These include anonymous visitors and users who weren't logged in when they viewed the page.
Ztack's html.zig module provides a powerful, type-safe, and efficient way to programmatically generate HTML content in Zig. It focuses on minimizing allocations, enabling direct streaming to network sockets or files, and offering a clean builder API for common HTML elements.
HtmlDocument and ElementAt the heart of Ztack's HTML generation are two key types:
html.HtmlDocument: This struct manages the overall construction and rendering of an entire HTML page. You initialize it with an allocator, build a page using arrays of elements, and then either get the complete HTML as a []const u8 or stream it directly to a writer.html.Element: This is the fundamental building block. Every HTML builder function returns an Element, representing a self-contained HTML tag or text node. These elements can then be nested to form complex page structures.You can find the full API reference for these types in the [Ztack API Reference].
To start building an HTML page, you first need an instance of HtmlDocument:
doc.build(head_elements: []const Element, body_elements: []const Element) ![]const u8This function takes two arrays of Elements – one for the <head> section and one for the <body> section – and returns a []const u8 containing the complete, rendered HTML document. This is useful when you need the entire HTML content in memory, for example, to send as an HTTP response body.
doc.renderToWriter(writer: anytype, head_elements: []const Element, body_elements: []const Element) !voidFor maximum efficiency, especially with large pages or when sending data directly over a network socket, renderToWriter allows you to stream the generated HTML directly to any std.io.Writer implementation. This method avoids intermediate string buffers and reduces memory allocations significantly, often leading to ~50% faster rendering for large pages and a 99.9% reduction in intermediate allocations.
The html.zig module provides a rich set of helper functions, each corresponding to a standard HTML element. These functions typically take an optional class/ID string (represented by ?[]const u8 for nullable strings) and an array of child Elements.
To include plain text within an HTML element, use html.text():
html.text(content: []const u8) Element: Creates a text node. content is the string to be displayed.These functions help define the layout and hierarchy of your page.
html.div(class_or_id: ?[]const u8, children: []const Element) Element: Creates a <div> element. class_or_id can be a class string or an ID string (e.g., "my-div-id" or "my-class").html.h1(class: ?[]const u8, children: []const Element) Element: Creates an <h1> heading.html.h2(class: ?[]const u8, children: []const Element) Element: Creates an <h2> heading.html.p(class: ?[]const u8, children: []const Element) Element: Creates a <p> (paragraph) element.html.span(class: ?[]const u8, children: []const Element) Element: Creates a <span> element.
children: []const Element, which is an array literal of child elements to be nested inside. Use null for class or class_or_id if no attribute is needed.Ztack provides dedicated builders for common interactive UI components.
html.button(class: ?[]const u8, onclick: []const u8, children: []const Element) Element: Creates a <button> element with an inline onclick attribute. The onclick string will be directly inserted into the HTML.html.button_data(class: ?[]const u8, data_on: []const u8, children: []const Element) Element: Creates a <button> element that leverages event delegation.
onclick, it uses a custom data-on attribute (e.g., data-on="click:handleClick"). This allows a single event listener on a parent element (like document.body) to handle events for multiple children, improving performance and simplifying event management.button_data to work, you must include the html.EVENT_DELEGATION_SCRIPT in your page's <head> or <body>.html.input(type: []const u8, id: []const u8, class: ?[]const u8) Element: Creates an <input> element with specified type, id, and optional class.html.input_with_value(type: []const u8, id: []const u8, value: []const u8) Element: Creates an <input> element with a default value attribute.html.anchor(href: []const u8, class: ?[]const u8, children: []const Element) Element: Creates an <a> (anchor) element. href is the target URL.Elements for the document head and for including JavaScript.
html.meta(charset: []const u8) Element: Creates a <meta> element, commonly used for charset declaration (e.g., html.meta("utf-8")).html.title(children: []const Element) Element: Creates a <title> element, which defines the title shown in the browser tab.html.script(src_or_content: []const u8, is_src: bool) Element: Creates a <script> element.
is_src is true, src_or_content is treated as the src attribute for an external script (e.g., <script src="/path/to/script.js"></script>).is_src is false, src_or_content is inserted as inline JavaScript content within the script tags (e.g., <script>alert('Hello');</script>).EVENT_DELEGATION_SCRIPTAs mentioned, html.button_data() (and similar *_data functions for other elements, if implemented) relies on a client-side JavaScript snippet to intercept events. This script registers a single event listener on the document.body (or a similar root element) and then dispatches events to handlers specified in data-on attributes.
To enable this powerful feature, you must include the html.EVENT_DELEGATION_SCRIPT in your page. It's typically placed in the <head> or at the end of the <body>:
This single script will efficiently manage events for all elements using data-on attributes, reducing redundant event listeners and improving page performance.
Here's a snippet demonstrating how to assemble a full HTML page using various Ztack HTML builders, similar to the simple_server.zig example:
By combining these builder functions, you can construct complex, dynamic, and highly efficient HTML pages directly within your Zig application.