mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-14 22:16:08 +00:00
Allow auto-routing to markdown files
If a route isn't matched but the URI can match directly to a markdown file, render it directly. This allows putting arbitrary markdown files in e.g. `/foo/bar/abc.md`, `/foo/bar/def.md` and rendering them as `/foo/bar/abc.html`, `/foo/bar/def.html`. Since markdown are static content only (i.e. no template data etc.) it makes sense for them to be renderable without needing to create a view for each one.
This commit is contained in:
parent
c2cc9c50f2
commit
625257bcfc
@ -157,39 +157,11 @@ fn renderHTML(
|
||||
};
|
||||
setResponse(request, rendered, .{});
|
||||
return;
|
||||
} else if (try jetzig.markdown.render(request.allocator, matched_route, null)) |markdown_content| {
|
||||
const rendered = self.renderView(matched_route, request, null) catch |err| {
|
||||
if (isUnhandledError(err)) return err;
|
||||
const rendered_error = try self.renderInternalServerError(request, err);
|
||||
setResponse(request, rendered_error, .{});
|
||||
return;
|
||||
};
|
||||
|
||||
try addTemplateConstants(rendered.view, matched_route);
|
||||
|
||||
if (request.getLayout(matched_route)) |layout_name| {
|
||||
// TODO: Allow user to configure layouts directory other than src/app/views/layouts/
|
||||
const prefixed_name = try std.mem.concat(
|
||||
self.allocator,
|
||||
u8,
|
||||
&[_][]const u8{ "layouts_", layout_name },
|
||||
);
|
||||
defer self.allocator.free(prefixed_name);
|
||||
|
||||
if (zmpl.manifest.find(prefixed_name)) |layout| {
|
||||
rendered.view.data.content = .{ .data = markdown_content };
|
||||
request.response.content = try layout.render(rendered.view.data);
|
||||
} else {
|
||||
try self.logger.WARN("Unknown layout: {s}", .{layout_name});
|
||||
request.response.content = markdown_content;
|
||||
}
|
||||
}
|
||||
request.response.status_code = rendered.view.status_code;
|
||||
request.response.content_type = "text/html";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (try self.renderMarkdown(request, route)) return;
|
||||
|
||||
request.response.content = "";
|
||||
request.response.status_code = .not_found;
|
||||
request.response.content_type = "text/html";
|
||||
@ -217,6 +189,59 @@ fn renderJSON(
|
||||
}
|
||||
}
|
||||
|
||||
fn renderMarkdown(self: *Self, request: *jetzig.http.Request, maybe_route: ?*jetzig.views.Route) !bool {
|
||||
const route = maybe_route orelse {
|
||||
if (request.method != .GET) return false;
|
||||
const content = try jetzig.markdown.render(request.allocator, request.path.base_path, null) orelse
|
||||
return false;
|
||||
|
||||
const rendered: RenderedView = .{
|
||||
.view = jetzig.views.View{ .data = request.response_data, .status_code = .ok },
|
||||
.content = content,
|
||||
};
|
||||
setResponse(request, rendered, .{});
|
||||
return true;
|
||||
};
|
||||
|
||||
const path = try std.mem.join(
|
||||
request.allocator,
|
||||
"/",
|
||||
&[_][]const u8{ route.uri_path, @tagName(route.action) },
|
||||
);
|
||||
const markdown_content = try jetzig.markdown.render(request.allocator, path, null) orelse
|
||||
return false;
|
||||
|
||||
const rendered = self.renderView(route, request, null) catch |err| {
|
||||
if (isUnhandledError(err)) return err;
|
||||
const rendered_error = try self.renderInternalServerError(request, err);
|
||||
setResponse(request, rendered_error, .{});
|
||||
return true;
|
||||
};
|
||||
|
||||
try addTemplateConstants(rendered.view, route);
|
||||
|
||||
if (request.getLayout(route)) |layout_name| {
|
||||
// TODO: Allow user to configure layouts directory other than src/app/views/layouts/
|
||||
const prefixed_name = try std.mem.concat(
|
||||
self.allocator,
|
||||
u8,
|
||||
&[_][]const u8{ "layouts_", layout_name },
|
||||
);
|
||||
defer self.allocator.free(prefixed_name);
|
||||
|
||||
if (zmpl.manifest.find(prefixed_name)) |layout| {
|
||||
rendered.view.data.content = .{ .data = markdown_content };
|
||||
request.response.content = try layout.render(rendered.view.data);
|
||||
} else {
|
||||
try self.logger.WARN("Unknown layout: {s}", .{layout_name});
|
||||
request.response.content = markdown_content;
|
||||
}
|
||||
}
|
||||
request.response.status_code = rendered.view.status_code;
|
||||
request.response.content_type = "text/html";
|
||||
return true;
|
||||
}
|
||||
|
||||
const RenderedView = struct { view: jetzig.views.View, content: []const u8 };
|
||||
|
||||
fn renderView(
|
||||
|
@ -5,7 +5,7 @@ const jetzig = @import("../jetzig.zig");
|
||||
const Zmd = @import("zmd").Zmd;
|
||||
pub fn render(
|
||||
allocator: std.mem.Allocator,
|
||||
route: *const jetzig.views.Route,
|
||||
path: []const u8,
|
||||
custom_fragments: ?type,
|
||||
) !?[]const u8 {
|
||||
const fragments = custom_fragments orelse jetzig.config.get(type, "markdown_fragments");
|
||||
@ -15,11 +15,10 @@ pub fn render(
|
||||
|
||||
try path_buf.appendSlice(&[_][]const u8{ "src", "app", "views" });
|
||||
|
||||
var it = std.mem.splitScalar(u8, route.uri_path, '/');
|
||||
var it = std.mem.splitScalar(u8, path, '/');
|
||||
while (it.next()) |segment| {
|
||||
try path_buf.append(segment);
|
||||
}
|
||||
try path_buf.append(@tagName(route.action));
|
||||
|
||||
const base_path = try std.fs.path.join(allocator, path_buf.items);
|
||||
defer allocator.free(base_path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user