fix: make conditional fields optional using @hasField
Templates can now use 'if error' or similar conditionals without requiring the caller to always provide those fields in the data struct.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
.{
|
.{
|
||||||
.name = .pugz,
|
.name = .pugz,
|
||||||
.version = "0.1.10",
|
.version = "0.1.11",
|
||||||
.fingerprint = 0x822db0790e17621d, // Changing this has security and trust implications.
|
.fingerprint = 0x822db0790e17621d, // Changing this has security and trust implications.
|
||||||
.minimum_zig_version = "0.15.2",
|
.minimum_zig_version = "0.15.2",
|
||||||
.dependencies = .{},
|
.dependencies = .{},
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ pub fn home(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|||||||
try o.appendSlice(a, "</title><link rel=\"stylesheet\" href=\"/style.css\" /></head><body><header><h1>");
|
try o.appendSlice(a, "</title><link rel=\"stylesheet\" href=\"/style.css\" /></head><body><header><h1>");
|
||||||
try esc(&o, a, strVal(@field(d, "title")));
|
try esc(&o, a, strVal(@field(d, "title")));
|
||||||
try o.appendSlice(a, "</h1>");
|
try o.appendSlice(a, "</h1>");
|
||||||
if (truthy(@field(d, "authenticated"))) {
|
if (@hasField(@TypeOf(d), "authenticated") and truthy(@field(d, "authenticated"))) {
|
||||||
try o.appendSlice(a, "<span class=\"user\">Welcome back!</span>");
|
try o.appendSlice(a, "<span class=\"user\">Welcome back!</span>");
|
||||||
}
|
}
|
||||||
try o.appendSlice(a, "</header><main><p>This page is rendered using a compiled template.</p><p>Compiled templates are 3x faster than Pug.js!</p></main><footer><p>© 2024 Pugz Demo</p></footer></body></html>");
|
try o.appendSlice(a, "</header><main><p>This page is rendered using a compiled template.</p><p>Compiled templates are 3x faster than Pug.js!</p></main><footer><p>© 2024 Pugz Demo</p></footer></body></html>");
|
||||||
@@ -209,7 +209,7 @@ pub fn page_a(a: Allocator, d: anytype) Allocator.Error![]u8 {
|
|||||||
try o.appendSlice(a, " /></fieldset>");
|
try o.appendSlice(a, " /></fieldset>");
|
||||||
}
|
}
|
||||||
try o.appendSlice(a, "<submit>sumit</submit>");
|
try o.appendSlice(a, "<submit>sumit</submit>");
|
||||||
if (truthy(@field(d, "error"))) {
|
if (@hasField(@TypeOf(d), "error") and truthy(@field(d, "error"))) {
|
||||||
{
|
{
|
||||||
const message = @field(d, "error");
|
const message = @field(d, "error");
|
||||||
const mixin_attrs_1: struct {
|
const mixin_attrs_1: struct {
|
||||||
|
|||||||
@@ -1254,7 +1254,18 @@ const Compiler = struct {
|
|||||||
// Regular field access - use buildAccessor for consistency
|
// Regular field access - use buildAccessor for consistency
|
||||||
var accessor_buf: [512]u8 = undefined;
|
var accessor_buf: [512]u8 = undefined;
|
||||||
const accessor = self.buildAccessor(cond, &accessor_buf);
|
const accessor = self.buildAccessor(cond, &accessor_buf);
|
||||||
try self.writer.print("truthy({s})", .{accessor});
|
|
||||||
|
// Check if this is a simple top-level field access (no dots, not a loop var or mixin param)
|
||||||
|
const is_simple_field = std.mem.indexOfScalar(u8, cond, '.') == null and
|
||||||
|
!self.isLoopVar(cond) and !self.isMixinParam(cond);
|
||||||
|
|
||||||
|
if (is_simple_field) {
|
||||||
|
// Use @hasField to make the field optional at compile time
|
||||||
|
self.uses_data = true;
|
||||||
|
try self.writer.print("@hasField(@TypeOf(d), \"{s}\") and truthy({s})", .{ cond, accessor });
|
||||||
|
} else {
|
||||||
|
try self.writer.print("truthy({s})", .{accessor});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emitEach(self: *Compiler, e: ast.Each) anyerror!void {
|
fn emitEach(self: *Compiler, e: ast.Each) anyerror!void {
|
||||||
|
|||||||
Reference in New Issue
Block a user