diff --git a/build.zig.zon b/build.zig.zon index d352ee4..2c79cfc 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,6 +1,6 @@ .{ .name = .pugz, - .version = "0.3.9", + .version = "0.3.10", .fingerprint = 0x822db0790e17621d, // Changing this has security and trust implications. .minimum_zig_version = "0.15.2", .dependencies = .{}, diff --git a/examples/demo/views/pages/include-demo.pug b/examples/demo/views/pages/include-demo.pug index f649584..14fb7ae 100644 --- a/examples/demo/views/pages/include-demo.pug +++ b/examples/demo/views/pages/include-demo.pug @@ -14,7 +14,7 @@ block content h2 Content from this page p The box below is included from a separate partial file. - include includes/some_partial.pug + include ../includes/some_partial.pug h2 After the include p This content comes after the included partial. diff --git a/src/mixin.zig b/src/mixin.zig index 46c2dfa..f296dfa 100644 --- a/src/mixin.zig +++ b/src/mixin.zig @@ -130,6 +130,8 @@ fn expandNode( const new_node = allocator.create(Node) catch return error.OutOfMemory; new_node.* = node.*; new_node.nodes = .{}; + new_node.consequent = null; + new_node.alternate = null; // Clone and expand children for (node.nodes.items) |child| { @@ -137,6 +139,14 @@ fn expandNode( new_node.nodes.append(allocator, expanded_child) catch return error.OutOfMemory; } + // Handle Conditional nodes which store children in consequent/alternate + if (node.consequent) |cons| { + new_node.consequent = try expandNode(allocator, cons, registry, caller_block); + } + if (node.alternate) |alt| { + new_node.alternate = try expandNode(allocator, alt, registry, caller_block); + } + return new_node; } @@ -239,6 +249,8 @@ fn expandNodeWithArgs( new_node.* = node.*; new_node.nodes = .{}; new_node.attrs = .{}; + new_node.consequent = null; + new_node.alternate = null; // Substitute argument references in text/val if (node.val) |val| { @@ -260,6 +272,14 @@ fn expandNodeWithArgs( new_node.nodes.append(allocator, expanded) catch return error.OutOfMemory; } + // Handle Conditional nodes which store children in consequent/alternate + if (node.consequent) |cons| { + new_node.consequent = try expandNodeWithArgs(allocator, cons, registry, caller_block, arg_bindings); + } + if (node.alternate) |alt| { + new_node.alternate = try expandNodeWithArgs(allocator, alt, registry, caller_block, arg_bindings); + } + return new_node; } diff --git a/src/view_engine.zig b/src/view_engine.zig index 3a62aca..8569c38 100644 --- a/src/view_engine.zig +++ b/src/view_engine.zig @@ -207,6 +207,13 @@ pub const ViewEngine = struct { const parent_path = if (first_node.file) |file| file.path else null; if (parent_path == null) return ast; + // Process includes in child template BEFORE extracting blocks + // This ensures mixin definitions from included files are available + try self.processIncludes(allocator, ast, current_dir, registry); + + // Collect mixins from child template (including from processed includes) + mixin.collectMixins(allocator, ast, registry) catch {}; + // Collect named blocks from child template (excluding the extends node) var child_blocks = std.StringHashMap(*Node).init(allocator); defer child_blocks.deinit();