zynagent-first application framework

Add an HTML page#

Add a server-rendered page with a route action and a ztl view.

Choose the route contract#

Check whether the route scope already supplies a layout, CSRF policy, hooks, or guards. Reuse the surrounding organization instead of creating a second route table or view convention for the same area.

Implement#

  1. Add or extend an action module under src/actions.
  2. Add the view under src/views; nested view paths are relative to that directory.
  3. Import the action module from the owning route module and register the route.
  4. Pass only the values the view needs.

For example:

// src/actions/pages.zig
const zyn = @import("zyn");

pub fn about(action: *zyn.Action) !zyn.Response {
    return action.render("pages/about.html", .{
        .title = "About",
    }, .{});
}
<!-- src/views/pages/about.html.ez -->
<h1><%= @title %></h1>
// In the owning route module.
const pages = @import("actions/pages.zig");

pub const table: zyn.RouteTable = &.{
    .get("/about", pages.about, &.{}),
};

Keep request-specific input types beside the action. If several endpoints share a public representation or codec, put that type under src/resources rather than in the view.

Do not write a complete HTML document in the view when the route already inherits an HTML layout. Do not construct links by concatenating route parameters; use zyn.url in Zig or the literal url helper in ztl.

Verify#

zyn routes
zyn check

Use zyn dev for a browser check when the result depends on layouts, assets, cookies, or middleware.

Verify the effective route, inherited guards and hooks, and rendered layout in application tests.