diff --git a/build.zig b/build.zig
index b714831..0902c8f 100644
--- a/build.zig
+++ b/build.zig
@@ -12,7 +12,6 @@ pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const template_path = b.option([]const u8, "zmpl_templates_path", "Path to templates") orelse "src/app/views/";
- const manifest: []const u8 = b.pathJoin(&.{ template_path, "zmpl.manifest.zig" });
const lib = b.addStaticLibrary(.{
.name = "jetzig",
@@ -35,7 +34,6 @@ pub fn build(b: *std.Build) !void {
.target = target,
.optimize = optimize,
.zmpl_templates_path = template_path,
- .zmpl_manifest_path = manifest,
},
);
diff --git a/build.zig.zon b/build.zig.zon
index 440427b..6a6f26e 100644
--- a/build.zig.zon
+++ b/build.zig.zon
@@ -3,8 +3,8 @@
.version = "0.0.0",
.dependencies = .{
.zmpl = .{
- .url = "https://github.com/jetzig-framework/zmpl/archive/84a712349e0cf679fc5c9900b805335d51d9ce86.tar.gz",
- .hash = "1220e9f2133f6cd24c370850cbe3816e3d8b97c33dd822bf7eaf8f6f0ea2cfd2f8db",
+ .url = "https://github.com/jetzig-framework/zmpl/archive/aa7147f8a52d927dce6cdd4f5b3bb2de5080f28c.tar.gz",
+ .hash = "12203d262b39b2328adb981e41c5127507f3d47e977c1a4e69a96688a4213b986d04",
},
},
diff --git a/demo/build.zig b/demo/build.zig
index c0d560f..834f4ff 100644
--- a/demo/build.zig
+++ b/demo/build.zig
@@ -55,13 +55,9 @@ pub fn build(b: *std.Build) !void {
lib.root_module.addImport("routes", routes_module);
routes_module.addImport("jetzig", jetzig_module);
- const templates_module = b.createModule(
- .{ .root_source_file = .{ .path = "src/app/views/zmpl.manifest.zig" } },
- );
exe_static_routes.root_module.addImport("routes", routes_module);
exe_static_routes.root_module.addImport("jetzig", jetzig_module);
- exe_static_routes.root_module.addImport("templates", templates_module);
- templates_module.addImport("zmpl", zmpl_module);
+ exe_static_routes.root_module.addImport("zmpl", zmpl_module);
const run_static_routes_cmd = b.addRunArtifact(exe_static_routes);
exe.step.dependOn(&run_static_routes_cmd.step);
diff --git a/demo/public/favicon.ico b/demo/public/favicon.ico
new file mode 100644
index 0000000..0ccc92b
Binary files /dev/null and b/demo/public/favicon.ico differ
diff --git a/demo/src/app/views/root/_quotes.zmpl b/demo/src/app/views/root/_quotes.zmpl
new file mode 100644
index 0000000..ef479e8
--- /dev/null
+++ b/demo/src/app/views/root/_quotes.zmpl
@@ -0,0 +1,9 @@
+
+
{.message}
+
+
+
+
+
diff --git a/demo/src/app/views/root/index.zmpl b/demo/src/app/views/root/index.zmpl
index 57ee5cc..5de793a 100644
--- a/demo/src/app/views/root/index.zmpl
+++ b/demo/src/app/views/root/index.zmpl
@@ -10,15 +10,8 @@
-
-
{.message}
-
-
-
-
-
+ // Renders `src/app/views/root/_quotes.zmpl`:
+
{^root/quotes}
diff --git a/demo/src/main.zig b/demo/src/main.zig
index d5fcd2b..8159618 100644
--- a/demo/src/main.zig
+++ b/demo/src/main.zig
@@ -1,7 +1,6 @@
const std = @import("std");
pub const jetzig = @import("jetzig");
-pub const templates = @import("app/views/zmpl.manifest.zig").templates;
pub const routes = @import("routes").routes;
pub const jetzig_options = struct {
@@ -16,8 +15,5 @@ pub fn main() !void {
const app = try jetzig.init(allocator);
defer app.deinit();
- try app.start(
- comptime jetzig.route(routes),
- comptime jetzig.loadTemplates(templates),
- );
+ try app.start(comptime jetzig.route(routes));
}
diff --git a/src/app/views/zmpl.manifest.zig b/src/app/views/zmpl.manifest.zig
deleted file mode 100644
index 3d67249..0000000
--- a/src/app/views/zmpl.manifest.zig
+++ /dev/null
@@ -1,5 +0,0 @@
-// Zmpl template manifest.
-// This file is automatically generated at build time. Manual edits will be discarded.
-// This file should _not_ be stored in version control.
-pub const templates = struct {
-};
diff --git a/src/compile_static_routes.zig b/src/compile_static_routes.zig
index cf03fca..149306e 100644
--- a/src/compile_static_routes.zig
+++ b/src/compile_static_routes.zig
@@ -1,7 +1,7 @@
const std = @import("std");
const jetzig = @import("jetzig");
const routes = @import("routes").routes;
-const templates = @import("templates").templates;
+const zmpl = @import("zmpl");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@@ -94,8 +94,7 @@ fn writeContent(
std.debug.print("[jetzig] Compiled static route: {s}\n", .{json_path});
- if (@hasDecl(templates, route.template)) {
- const template = @field(templates, route.template);
+ if (zmpl.find(route.template)) |template| {
const html_path = try std.mem.concat(
allocator,
u8,
diff --git a/src/init/src/main.zig b/src/init/src/main.zig
index 72b2899..a434403 100644
--- a/src/init/src/main.zig
+++ b/src/init/src/main.zig
@@ -1,8 +1,7 @@
const std = @import("std");
pub const jetzig = @import("jetzig");
-pub const templates = @import("app/views/zmpl.manifest.zig").templates;
-pub const routes = @import("app/views/routes.zig").routes;
+pub const routes = @import("routes").routes;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@@ -12,8 +11,5 @@ pub fn main() !void {
const app = try jetzig.init(allocator);
defer app.deinit();
- try app.start(
- comptime jetzig.route(routes),
- comptime jetzig.loadTemplates(templates),
- );
+ try app.start(comptime jetzig.route(routes));
}
diff --git a/src/jetzig.zig b/src/jetzig.zig
index 48d8b94..22945eb 100644
--- a/src/jetzig.zig
+++ b/src/jetzig.zig
@@ -153,31 +153,6 @@ pub fn route(comptime routes: anytype) []views.Route {
return &detected;
}
-// Receives a type (an imported module). All pub const declarations are considered as compiled
-// Zmpl templates, each implementing a `render` function.
-pub fn loadTemplates(comptime module: type) []TemplateFn {
- var size: u16 = 0;
- const decls = @typeInfo(module).Struct.decls;
-
- for (decls) |_| size += 1;
-
- var detected: [size]TemplateFn = undefined;
-
- for (decls, 0..) |decl, decl_index| {
- detected[decl_index] = .{
- .render = @field(module, decl.name).render,
- .name = decl.name,
- };
- }
-
- return &detected;
-}
-
-pub const TemplateFn = struct {
- name: []const u8,
- render: *const fn (*zmpl.Data) anyerror![]const u8,
-};
-
pub fn generateSecret(allocator: std.mem.Allocator) ![]const u8 {
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var secret: [64]u8 = undefined;
diff --git a/src/jetzig/App.zig b/src/jetzig/App.zig
index 8c2c645..96d3d15 100644
--- a/src/jetzig/App.zig
+++ b/src/jetzig/App.zig
@@ -18,7 +18,7 @@ pub fn deinit(self: Self) void {
/// Starts an application. `routes` should be `@import("routes").routes`, a generated file
/// automatically created at build time. `templates` should be
/// `@import("src/app/views/zmpl.manifest.zig").templates`, created by Zmpl at compile time.
-pub fn start(self: Self, comptime_routes: []jetzig.views.Route, templates: []jetzig.TemplateFn) !void {
+pub fn start(self: Self, comptime_routes: []jetzig.views.Route) !void {
var mime_map = jetzig.http.mime.MimeMap.init(self.allocator);
defer mime_map.deinit();
try mime_map.build();
@@ -54,7 +54,6 @@ pub fn start(self: Self, comptime_routes: []jetzig.views.Route, templates: []jet
self.port,
self.server_options,
routes.items,
- templates,
&mime_map,
);
diff --git a/src/jetzig/http/Server.zig b/src/jetzig/http/Server.zig
index 098a87d..feb0d39 100644
--- a/src/jetzig/http/Server.zig
+++ b/src/jetzig/http/Server.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const jetzig = @import("../../jetzig.zig");
+const zmpl = @import("zmpl");
const root_file = @import("root");
@@ -24,7 +25,6 @@ logger: jetzig.loggers.Logger,
options: ServerOptions,
start_time: i128 = undefined,
routes: []*jetzig.views.Route,
-templates: []jetzig.TemplateFn,
mime_map: *jetzig.http.mime.MimeMap,
std_net_server: std.net.Server = undefined,
@@ -36,7 +36,6 @@ pub fn init(
port: u16,
options: ServerOptions,
routes: []*jetzig.views.Route,
- templates: []jetzig.TemplateFn,
mime_map: *jetzig.http.mime.MimeMap,
) Self {
return .{
@@ -47,7 +46,6 @@ pub fn init(
.logger = options.logger,
.options = options,
.routes = routes,
- .templates = templates,
.mime_map = mime_map,
};
}
@@ -123,7 +121,7 @@ fn renderResponse(self: *Self, request: *jetzig.http.Request) !void {
const rendered = try self.renderInternalServerError(request, err);
request.response.content = rendered.content;
- request.response.status_code = .internal_server_error;
+ request.response.status_code = rendered.view.status_code;
request.response.content_type = "text/html";
return;
@@ -155,15 +153,19 @@ fn renderHTML(
route: ?*jetzig.views.Route,
) !void {
if (route) |matched_route| {
- for (self.templates) |template| {
- // TODO: Use a hashmap to avoid O(n)
- if (std.mem.eql(u8, matched_route.template, template.name)) {
- const rendered = try self.renderView(matched_route, request, template);
- request.response.content = rendered.content;
- request.response.status_code = rendered.view.status_code;
+ if (zmpl.find(matched_route.template)) |template| {
+ const rendered = self.renderView(matched_route, request, template) catch |err| {
+ if (isUnhandledError(err)) return err;
+ const rendered_error = try self.renderInternalServerError(request, err);
+ request.response.content = rendered_error.content;
+ request.response.status_code = rendered_error.view.status_code;
request.response.content_type = "text/html";
return;
- }
+ };
+ request.response.content = rendered.content;
+ request.response.status_code = rendered.view.status_code;
+ request.response.content_type = "text/html";
+ return;
}
}
@@ -200,7 +202,7 @@ fn renderView(
self: *Self,
route: *jetzig.views.Route,
request: *jetzig.http.Request,
- template: ?jetzig.TemplateFn,
+ template: ?zmpl.manifest.Template,
) !RenderedView {
const view = route.render(route.*, request) catch |err| {
self.logger.debug("Encountered error: {s}", .{@errorName(err)});
diff --git a/src/jetzig/http/mime.zig b/src/jetzig/http/mime.zig
index 10b8732..7ccac2d 100644
--- a/src/jetzig/http/mime.zig
+++ b/src/jetzig/http/mime.zig
@@ -31,19 +31,14 @@ pub const MimeMap = struct {
}
pub fn deinit(self: *MimeMap) void {
- var it = self.map.iterator();
- while (it.next()) |item| {
- self.allocator.free(item.key_ptr.*);
- self.allocator.free(item.value_ptr.*);
- }
self.map.deinit();
}
pub fn build(self: *MimeMap) !void {
for (mime_types) |mime_type| {
try self.map.put(
- try self.allocator.dupe(u8, mime_type.file_type),
- try self.allocator.dupe(u8, mime_type.name),
+ mime_type.file_type,
+ mime_type.name,
);
}
}