From a55831d0ced55b7c343d1e5725837934df3e439b Mon Sep 17 00:00:00 2001 From: "Lucas F." Date: Sun, 11 Jan 2026 16:46:32 -0300 Subject: [PATCH] update: include and super --- src/renderer.zig | 93 +++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 53 deletions(-) diff --git a/src/renderer.zig b/src/renderer.zig index 609578d..429e59c 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -62,7 +62,7 @@ pub const Renderer = struct { fn readTemplateFile(self: *const Renderer, path: []const u8) RenderError![]const u8 { const max_size = 10 * 1024 * 1024; - const base_template = std.fs.cwd().readFileAlloc(self.allocator, path, max_size) catch |err| switch (err) { + return std.fs.cwd().readFileAlloc(self.allocator, path, max_size) catch |err| switch (err) { error.FileNotFound => return RenderError.FileNotFound, error.AccessDenied => return RenderError.AccessDenied, error.FileTooBig => return RenderError.FileTooBig, @@ -70,51 +70,14 @@ pub const Renderer = struct { error.OutOfMemory => return RenderError.OutOfMemory, else => return RenderError.Unexpected, }; - return base_template; } pub fn render(self: *const Renderer, template: []const u8, writer: anytype) RenderError!void { const base_template = try self.readTemplateFile(template); + defer self.allocator.free(base_template); return self.renderString(base_template, writer); } - pub fn renderString_bkp(self: *const Renderer, template: []const u8, writer: anytype) RenderError!void { - var arena = std.heap.ArenaAllocator.init(self.allocator); - defer arena.deinit(); - const alloc = arena.allocator(); - - var p = parser.Parser.init(template); - const nodes = try p.parse(alloc); - defer { - for (nodes) |node| node.deinit(alloc); - alloc.free(nodes); - } - - const has_extends = self.checkForExtends(nodes); - - if (has_extends) { - for (nodes) |node| { - if (node.type == .extends) { - const base_template = try self.readTemplateFile(node.extends.?.parent_name); - defer self.allocator.free(base_template); - - var base_parser = parser.Parser.init(base_template); - const base_nodes = try base_parser.parse(alloc); - defer { - for (base_nodes) |n| n.deinit(alloc); - alloc.free(base_nodes); - } - - try self.renderWithInheritance(alloc, base_nodes, nodes, writer); - return; - } - } - } else { - for (nodes) |node| { - try self.renderNode(alloc, nodes, node, writer, null); - } - } - } pub fn renderString(self: *const Renderer, template: []const u8, writer: anytype) RenderError!void { var arena = std.heap.ArenaAllocator.init(self.allocator); defer arena.deinit(); @@ -127,9 +90,9 @@ pub const Renderer = struct { alloc.free(nodes); } - const block_extends = self.checkForExtends(nodes); + const extends_node = self.checkForExtends(nodes); - if (block_extends) |ext| { + if (extends_node) |ext| { const base_template = try self.readTemplateFile(ext.extends.?.parent_name); defer self.allocator.free(base_template); @@ -142,7 +105,7 @@ pub const Renderer = struct { try self.renderWithInheritance(alloc, base_nodes, nodes, writer); } else { for (nodes) |node| { - try self.renderNode(alloc, nodes, node, writer, null); + try self.renderNode(alloc, nodes, node, writer, null, null); } } } @@ -155,24 +118,24 @@ pub const Renderer = struct { // Procura no filho const child_block = self.findChildBlock(child_nodes, block_name); if (child_block) |child| { - // Renderiza só o filho + // Renderiza o filho, passando o conteúdo do pai para block.super for (child.body) |child_node| { - try self.renderNode(alloc, child_nodes, child_node, writer, null); + try self.renderNode(alloc, child_nodes, child_node, writer, null, base_node.block.?.body); } } else { // Renderiza o do pai for (base_node.block.?.body) |child| { - try self.renderNode(alloc, child_nodes, child, writer, null); + try self.renderNode(alloc, child_nodes, child, writer, null, null); } } } else { // Qualquer outra coisa no base - try self.renderNode(alloc, child_nodes, base_node, writer, null); + try self.renderNode(alloc, child_nodes, base_node, writer, null, null); } } } - fn renderNode(self: *const Renderer, alloc: Allocator, nodes: []parser.Node, node: parser.Node, writer: anytype, context: ?*Context) RenderError!void { + fn renderNode(self: *const Renderer, alloc: Allocator, nodes: []parser.Node, node: parser.Node, writer: anytype, context: ?*Context, parent_block_nodes: ?[]parser.Node) RenderError!void { switch (node.type) { .text => try writer.writeAll(node.text.?.content), .variable => { @@ -212,14 +175,30 @@ pub const Renderer = struct { if (condition) { for (node.@"if".?.true_body) |child| { - try self.renderNode(alloc, nodes, child, writer, null); + try self.renderNode(alloc, nodes, child, writer, null, null); } } else { for (node.@"if".?.false_body) |child| { - try self.renderNode(alloc, nodes, child, writer, null); + try self.renderNode(alloc, nodes, child, writer, null, null); } } }, + .include => { + const included_template = try self.readTemplateFile(node.include.?.template_name); + defer alloc.free(included_template); + + var included_parser = parser.Parser.init(included_template); + const included_nodes = try included_parser.parse(alloc); + defer { + for (included_nodes) |n| n.deinit(alloc); + alloc.free(included_nodes); + } + + // Renderiza o include no contexto atual (sem novo contexto) + for (included_nodes) |included_node| { + try self.renderNode(alloc, nodes, included_node, writer, context, null); + } + }, .for_block => { const list_value = self.context.get(node.@"for".?.iterable) orelse Value.null; const list = switch (list_value) { @@ -234,17 +213,25 @@ pub const Renderer = struct { try ctx.set(node.@"for".?.loop_var, item); for (node.@"for".?.body) |child| { - try self.renderNode(alloc, nodes, child, writer, &ctx); + try self.renderNode(alloc, nodes, child, writer, &ctx, null); } + for (node.@"for".?.empty_body) |child| { - try self.renderNode(alloc, nodes, child, writer, &ctx); + try self.renderNode(alloc, nodes, child, writer, &ctx, null); + } + } + }, + .super => { + if (parent_block_nodes) |parent| { + for (parent) |child| { + try self.renderNode(alloc, nodes, child, writer, null, null); } } }, - .super => std.debug.print("\n\ntenho SUPER!!\n\n", .{}), .block => { for (node.block.?.body) |child| { - try self.renderNode(alloc, nodes, child, writer, null); + const parent_content = parent_block_nodes orelse node.block.?.body; + try self.renderNode(alloc, nodes, child, writer, null, parent_content); } }, else => {},