mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-14 14:06:08 +00:00
Inertia - WIP
Not yet complete but provides some functionality with internal templates that Websockets/Channels needs so merging in to main and can pick up later.
This commit is contained in:
parent
1feb18fb74
commit
6a4f99ca14
11
build.zig
11
build.zig
@ -12,11 +12,22 @@ const use_llvm_default = builtin.os.tag != .linux;
|
|||||||
pub fn build(b: *std.Build) !void {
|
pub fn build(b: *std.Build) !void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
var jetzig_templates_path = std.ArrayList([]const u8).init(b.allocator);
|
||||||
|
try jetzig_templates_path.append("/");
|
||||||
|
var it = std.mem.splitSequence(
|
||||||
|
u8,
|
||||||
|
try b.path("src/jetzig/templates").getPath3(b, null).toString(b.allocator),
|
||||||
|
std.fs.path.sep_str,
|
||||||
|
);
|
||||||
|
while (it.next()) |segment| {
|
||||||
|
try jetzig_templates_path.append(segment);
|
||||||
|
}
|
||||||
const templates_paths = try zmpl_build.templatesPaths(
|
const templates_paths = try zmpl_build.templatesPaths(
|
||||||
b.allocator,
|
b.allocator,
|
||||||
&.{
|
&.{
|
||||||
.{ .prefix = "views", .path = &.{ "src", "app", "views" } },
|
.{ .prefix = "views", .path = &.{ "src", "app", "views" } },
|
||||||
.{ .prefix = "mailers", .path = &.{ "src", "app", "mailers" } },
|
.{ .prefix = "mailers", .path = &.{ "src", "app", "mailers" } },
|
||||||
|
.{ .prefix = "jetzig", .path = jetzig_templates_path.items },
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
.hash = "jetkv-0.0.0-zCv0fmCGAgCyYqwHjk0P5KrYVRew1MJAtbtAcIO-WPpT",
|
.hash = "jetkv-0.0.0-zCv0fmCGAgCyYqwHjk0P5KrYVRew1MJAtbtAcIO-WPpT",
|
||||||
},
|
},
|
||||||
.zmpl = .{
|
.zmpl = .{
|
||||||
.url = "https://github.com/jetzig-framework/zmpl/archive/c57fc9b83027e8c1459d9625c3509f59f0fb89f3.tar.gz",
|
.url = "https://github.com/jetzig-framework/zmpl/archive/89ee0ce9b4c96c316cc0575266fb66c864f24a49.tar.gz",
|
||||||
.hash = "zmpl-0.0.1-SYFGBgdqAwDeA6xm4KAhpKoNrWs5CMQK6x447zhWclCs",
|
.hash = "zmpl-0.0.1-SYFGBtuNAwCj2YbqnoEJt3bk1iFIZjGK6JwMc72toZBR",
|
||||||
},
|
},
|
||||||
.httpz = .{
|
.httpz = .{
|
||||||
.url = "https://github.com/karlseguin/http.zig/archive/37d7cb9819b804ade5f4b974b82f8dd0622225ed.tar.gz",
|
.url = "https://github.com/karlseguin/http.zig/archive/37d7cb9819b804ade5f4b974b82f8dd0622225ed.tar.gz",
|
||||||
|
1
demo/src/app/views/inertia/_head.zmpl
Normal file
1
demo/src/app/views/inertia/_head.zmpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
<title>My Inertia App</title>
|
@ -14,7 +14,8 @@ pub const jetzig_options = struct {
|
|||||||
pub const middleware: []const type = &.{
|
pub const middleware: []const type = &.{
|
||||||
// jetzig.middleware.AuthMiddleware,
|
// jetzig.middleware.AuthMiddleware,
|
||||||
// jetzig.middleware.AntiCsrfMiddleware,
|
// jetzig.middleware.AntiCsrfMiddleware,
|
||||||
// jetzig.middleware.HtmxMiddleware,
|
jetzig.middleware.HtmxMiddleware,
|
||||||
|
// jetzig.middleware.InertiaMiddleware,
|
||||||
// jetzig.middleware.CompressionMiddleware,
|
// jetzig.middleware.CompressionMiddleware,
|
||||||
// @import("app/middleware/DemoMiddleware.zig"),
|
// @import("app/middleware/DemoMiddleware.zig"),
|
||||||
};
|
};
|
||||||
|
@ -147,7 +147,7 @@ fn renderMarkdown(
|
|||||||
|
|
||||||
if (zmpl.findPrefixed("views", prefixed_name)) |layout| {
|
if (zmpl.findPrefixed("views", prefixed_name)) |layout| {
|
||||||
view.data.content = .{ .data = content };
|
view.data.content = .{ .data = content };
|
||||||
return try layout.render(view.data, jetzig.TemplateContext, .{}, .{});
|
return try layout.render(view.data, jetzig.TemplateContext, .{}, &.{}, .{});
|
||||||
} else {
|
} else {
|
||||||
std.debug.print("Unknown layout: {s}\n", .{layout_name});
|
std.debug.print("Unknown layout: {s}\n", .{layout_name});
|
||||||
return content;
|
return content;
|
||||||
@ -174,6 +174,7 @@ fn renderZmplTemplate(
|
|||||||
view.data,
|
view.data,
|
||||||
jetzig.TemplateContext,
|
jetzig.TemplateContext,
|
||||||
.{},
|
.{},
|
||||||
|
&.{},
|
||||||
.{ .layout = layout },
|
.{ .layout = layout },
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -181,7 +182,7 @@ fn renderZmplTemplate(
|
|||||||
return try allocator.dupe(u8, "");
|
return try allocator.dupe(u8, "");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return try template.render(view.data, jetzig.TemplateContext, .{}, .{});
|
return try template.render(view.data, jetzig.TemplateContext, .{}, &.{}, .{});
|
||||||
}
|
}
|
||||||
} else return null;
|
} else return null;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const http = @import("http.zig");
|
pub const http = @import("http.zig");
|
||||||
|
pub const views = @import("views.zig");
|
||||||
pub const config = @import("config.zig");
|
pub const config = @import("config.zig");
|
||||||
|
|
||||||
/// Context available in every Zmpl template as `context`.
|
/// Context available in every Zmpl template as `context`.
|
||||||
pub const TemplateContext = @This();
|
pub const TemplateContext = @This();
|
||||||
|
|
||||||
request: ?*http.Request = null,
|
request: ?*http.Request = null,
|
||||||
|
route: ?views.Route = null,
|
||||||
|
|
||||||
|
/// Return an authenticity token stored in the current request's session. If no token exists,
|
||||||
|
/// generate and store before returning.
|
||||||
|
/// Use to create a form element which can be verified by `AntiCsrfMiddleware`.
|
||||||
pub fn authenticityToken(self: TemplateContext) !?[]const u8 {
|
pub fn authenticityToken(self: TemplateContext) !?[]const u8 {
|
||||||
return if (self.request) |request|
|
return if (self.request) |request|
|
||||||
try request.authenticityToken()
|
try request.authenticityToken()
|
||||||
@ -15,6 +20,8 @@ pub fn authenticityToken(self: TemplateContext) !?[]const u8 {
|
|||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate a hidden form element containing an authenticity token provided by
|
||||||
|
/// `authenticityToken`. Use as `{{context.authenticityFormElement()}}` in a Zmpl template.
|
||||||
pub fn authenticityFormElement(self: TemplateContext) !?[]const u8 {
|
pub fn authenticityFormElement(self: TemplateContext) !?[]const u8 {
|
||||||
return if (self.request) |request| blk: {
|
return if (self.request) |request| blk: {
|
||||||
const token = try request.authenticityToken();
|
const token = try request.authenticityToken();
|
||||||
@ -23,3 +30,10 @@ pub fn authenticityFormElement(self: TemplateContext) !?[]const u8 {
|
|||||||
, .{ config.get([]const u8, "authenticity_token_name"), token });
|
, .{ config.get([]const u8, "authenticity_token_name"), token });
|
||||||
} else null;
|
} else null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn path(self: TemplateContext) ?[]const u8 {
|
||||||
|
return if (self.request) |request|
|
||||||
|
request.path.path
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
}
|
||||||
|
@ -15,6 +15,7 @@ pub const RequestState = enum {
|
|||||||
initial, // No processing has taken place
|
initial, // No processing has taken place
|
||||||
processed, // Request headers have been processed
|
processed, // Request headers have been processed
|
||||||
after_request, // Initial middleware processing
|
after_request, // Initial middleware processing
|
||||||
|
after_view, // View returned, response data ready for full response render
|
||||||
rendered, // Rendered by middleware or view
|
rendered, // Rendered by middleware or view
|
||||||
redirected, // Redirected by middleware or view
|
redirected, // Redirected by middleware or view
|
||||||
failed, // Failed by middleware or view
|
failed, // Failed by middleware or view
|
||||||
@ -217,6 +218,20 @@ pub fn render(self: *Request, status_code: jetzig.http.status_codes.StatusCode)
|
|||||||
return self.rendered_view.?;
|
return self.rendered_view.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Render a response with pre-rendered content. This function can only be called once per
|
||||||
|
/// request (repeat calls will trigger an error).
|
||||||
|
pub fn renderContent(
|
||||||
|
self: *Request,
|
||||||
|
status_code: jetzig.http.status_codes.StatusCode,
|
||||||
|
content: []const u8,
|
||||||
|
) jetzig.views.View {
|
||||||
|
if (self.isRendered()) self.rendered_multiple = true;
|
||||||
|
|
||||||
|
self.state = .rendered;
|
||||||
|
self.rendered_view = .{ .data = self.response_data, .status_code = status_code, .content = content };
|
||||||
|
return self.rendered_view.?;
|
||||||
|
}
|
||||||
|
|
||||||
/// Render an error. This function can only be called once per request (repeat calls will
|
/// Render an error. This function can only be called once per request (repeat calls will
|
||||||
/// trigger an error).
|
/// trigger an error).
|
||||||
pub fn fail(self: *Request, status_code: jetzig.http.status_codes.StatusCode) jetzig.views.View {
|
pub fn fail(self: *Request, status_code: jetzig.http.status_codes.StatusCode) jetzig.views.View {
|
||||||
@ -230,7 +245,7 @@ pub fn fail(self: *Request, status_code: jetzig.http.status_codes.StatusCode) je
|
|||||||
pub inline fn isRendered(self: *const Request) bool {
|
pub inline fn isRendered(self: *const Request) bool {
|
||||||
return switch (self.state) {
|
return switch (self.state) {
|
||||||
.initial, .processed, .after_request, .before_response => false,
|
.initial, .processed, .after_request, .before_response => false,
|
||||||
.rendered, .redirected, .failed, .finalized => true,
|
.after_view, .rendered, .redirected, .failed, .finalized => true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,6 +321,7 @@ pub fn renderRedirect(self: *Request, state: RedirectState) !void {
|
|||||||
self.response_data,
|
self.response_data,
|
||||||
jetzig.TemplateContext,
|
jetzig.TemplateContext,
|
||||||
.{ .request = self },
|
.{ .request = self },
|
||||||
|
&.{},
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
} else try std.fmt.allocPrint(self.allocator, "Redirecting to {s}", .{state.location}),
|
} else try std.fmt.allocPrint(self.allocator, "Redirecting to {s}", .{state.location}),
|
||||||
|
@ -152,13 +152,18 @@ pub fn processNextRequest(
|
|||||||
|
|
||||||
try request.process();
|
try request.process();
|
||||||
|
|
||||||
|
// Allow middleware to render templates even though we have not mapped a view/action yet.
|
||||||
|
// TODO: We should probably separate the routing and map routes before we invoke middleware.
|
||||||
|
try request.response_data.addConst("jetzig_action", request.response_data.string(""));
|
||||||
|
try request.response_data.addConst("jetzig_view", request.response_data.string(""));
|
||||||
|
|
||||||
var middleware_data = try jetzig.http.middleware.afterRequest(&request);
|
var middleware_data = try jetzig.http.middleware.afterRequest(&request);
|
||||||
if (try maybeMiddlewareRender(&request, &response)) {
|
if (try maybeMiddlewareRender(&request, &response)) {
|
||||||
try self.logger.logRequest(&request);
|
try self.logger.logRequest(&request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.renderResponse(&request);
|
try self.renderResponse(&request, &middleware_data);
|
||||||
try request.response.headers.append("Content-Type", response.content_type);
|
try request.response.headers.append("Content-Type", response.content_type);
|
||||||
|
|
||||||
try jetzig.http.middleware.beforeResponse(&middleware_data, &request);
|
try jetzig.http.middleware.beforeResponse(&middleware_data, &request);
|
||||||
@ -175,8 +180,7 @@ fn maybeMiddlewareRender(request: *jetzig.http.Request, response: *const jetzig.
|
|||||||
if (request.redirect_state) |state| {
|
if (request.redirect_state) |state| {
|
||||||
try request.renderRedirect(state);
|
try request.renderRedirect(state);
|
||||||
} else if (request.rendered_view) |rendered| {
|
} else if (request.rendered_view) |rendered| {
|
||||||
// TODO: Allow middleware to set content
|
request.setResponse(.{ .view = rendered, .content = rendered.content orelse "" }, .{});
|
||||||
request.setResponse(.{ .view = rendered, .content = "" }, .{});
|
|
||||||
}
|
}
|
||||||
try request.response.headers.append("Content-Type", response.content_type);
|
try request.response.headers.append("Content-Type", response.content_type);
|
||||||
try request.respond();
|
try request.respond();
|
||||||
@ -184,7 +188,11 @@ fn maybeMiddlewareRender(request: *jetzig.http.Request, response: *const jetzig.
|
|||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderResponse(self: *Server, request: *jetzig.http.Request) !void {
|
fn renderResponse(
|
||||||
|
self: *Server,
|
||||||
|
request: *jetzig.http.Request,
|
||||||
|
middleware_data: *jetzig.http.middleware.MiddlewareData,
|
||||||
|
) !void {
|
||||||
const static_resource = self.matchStaticResource(request) catch |err| {
|
const static_resource = self.matchStaticResource(request) catch |err| {
|
||||||
if (isUnhandledError(err)) return err;
|
if (isUnhandledError(err)) return err;
|
||||||
|
|
||||||
@ -236,6 +244,34 @@ fn renderResponse(self: *Server, request: *jetzig.http.Request) !void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// View functions return a `View` to encourage users to return from a view function with
|
||||||
|
// `return request.render(.ok)`, but the actual rendered view is stored in
|
||||||
|
// `request.rendered_view`.
|
||||||
|
_ = route.render(route, request) catch |err| {
|
||||||
|
if (isUnhandledError(err)) return err;
|
||||||
|
const rendered_error = if (isBadRequest(err))
|
||||||
|
try self.renderBadRequest(request)
|
||||||
|
else
|
||||||
|
try self.renderInternalServerError(request, @errorReturnTrace(), err);
|
||||||
|
request.setResponse(rendered_error, .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (request.rendered_view != null) {
|
||||||
|
try jetzig.http.middleware.afterView(middleware_data, request, route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.middleware_rendered) |_| {
|
||||||
|
// Request processing ends when a middleware renders or redirects.
|
||||||
|
if (request.redirect_state) |state| {
|
||||||
|
try request.renderRedirect(state);
|
||||||
|
} else if (request.rendered_view) |rendered| {
|
||||||
|
request.setResponse(.{ .view = rendered, .content = rendered.content orelse "" }, .{});
|
||||||
|
}
|
||||||
|
try request.response.headers.append("Content-Type", request.response.content_type);
|
||||||
|
return try request.respond();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (request.requestFormat()) {
|
switch (request.requestFormat()) {
|
||||||
@ -347,15 +383,6 @@ fn renderView(
|
|||||||
request: *jetzig.http.Request,
|
request: *jetzig.http.Request,
|
||||||
maybe_template: ?zmpl.Template,
|
maybe_template: ?zmpl.Template,
|
||||||
) !RenderedView {
|
) !RenderedView {
|
||||||
// View functions return a `View` to encourage users to return from a view function with
|
|
||||||
// `return request.render(.ok)`, but the actual rendered view is stored in
|
|
||||||
// `request.rendered_view`.
|
|
||||||
_ = route.render(route, request) catch |err| {
|
|
||||||
if (isUnhandledError(err)) return err;
|
|
||||||
if (isBadRequest(err)) return try self.renderBadRequest(request);
|
|
||||||
return try self.renderInternalServerError(request, @errorReturnTrace(), err);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (request.state == .failed) {
|
if (request.state == .failed) {
|
||||||
const view: jetzig.views.View = request.rendered_view orelse .{
|
const view: jetzig.views.View = request.rendered_view orelse .{
|
||||||
.data = request.response_data,
|
.data = request.response_data,
|
||||||
@ -415,7 +442,7 @@ fn renderTemplateWithLayout(
|
|||||||
) ![]const u8 {
|
) ![]const u8 {
|
||||||
try addTemplateConstants(view, route);
|
try addTemplateConstants(view, route);
|
||||||
|
|
||||||
const template_context = jetzig.TemplateContext{ .request = request };
|
const template_context = jetzig.TemplateContext{ .request = request, .route = route };
|
||||||
|
|
||||||
if (request.getLayout(route)) |layout_name| {
|
if (request.getLayout(route)) |layout_name| {
|
||||||
// TODO: Allow user to configure layouts directory other than src/app/views/layouts/
|
// TODO: Allow user to configure layouts directory other than src/app/views/layouts/
|
||||||
@ -431,6 +458,7 @@ fn renderTemplateWithLayout(
|
|||||||
view.data,
|
view.data,
|
||||||
jetzig.TemplateContext,
|
jetzig.TemplateContext,
|
||||||
template_context,
|
template_context,
|
||||||
|
&.{},
|
||||||
.{ .layout = layout },
|
.{ .layout = layout },
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -439,6 +467,7 @@ fn renderTemplateWithLayout(
|
|||||||
view.data,
|
view.data,
|
||||||
jetzig.TemplateContext,
|
jetzig.TemplateContext,
|
||||||
template_context,
|
template_context,
|
||||||
|
&.{},
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -446,6 +475,7 @@ fn renderTemplateWithLayout(
|
|||||||
view.data,
|
view.data,
|
||||||
jetzig.TemplateContext,
|
jetzig.TemplateContext,
|
||||||
template_context,
|
template_context,
|
||||||
|
&.{},
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -608,7 +638,8 @@ fn renderErrorView(
|
|||||||
.content = try template.render(
|
.content = try template.render(
|
||||||
request.response_data,
|
request.response_data,
|
||||||
jetzig.TemplateContext,
|
jetzig.TemplateContext,
|
||||||
.{ .request = request },
|
.{ .request = request, .route = route.* },
|
||||||
|
&.{},
|
||||||
.{},
|
.{},
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
@ -94,6 +94,38 @@ pub fn afterRequest(request: *jetzig.http.Request) !MiddlewareData {
|
|||||||
return middleware_data;
|
return middleware_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn afterView(middleware_data: *MiddlewareData, request: *jetzig.http.Request, route: jetzig.views.Route) !void {
|
||||||
|
if (request.state != .failed) request.state = .after_view;
|
||||||
|
|
||||||
|
inline for (middlewares, 0..) |middleware, index| {
|
||||||
|
if (comptime !@hasDecl(middleware, "afterView")) continue;
|
||||||
|
if (request.state == .after_view) {
|
||||||
|
if (comptime @hasDecl(middleware, "init")) {
|
||||||
|
const data = middleware_data.get(index).?;
|
||||||
|
try @call(
|
||||||
|
.always_inline,
|
||||||
|
middleware.afterView,
|
||||||
|
.{ @as(*middleware, @ptrCast(@alignCast(data))), request, route },
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
try @call(
|
||||||
|
.always_inline,
|
||||||
|
middleware.afterView,
|
||||||
|
.{ request, route },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.state != .after_view) {
|
||||||
|
request.middleware_rendered = .{
|
||||||
|
.name = @typeName(middleware),
|
||||||
|
.action = "afterView",
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn beforeResponse(
|
pub fn beforeResponse(
|
||||||
middleware_data: *MiddlewareData,
|
middleware_data: *MiddlewareData,
|
||||||
request: *jetzig.http.Request,
|
request: *jetzig.http.Request,
|
||||||
|
@ -148,7 +148,7 @@ fn defaultHtml(
|
|||||||
try data.addConst("jetzig_view", data.string(""));
|
try data.addConst("jetzig_view", data.string(""));
|
||||||
try data.addConst("jetzig_action", data.string(""));
|
try data.addConst("jetzig_action", data.string(""));
|
||||||
return if (jetzig.zmpl.findPrefixed("mailers", mailer.html_template)) |template|
|
return if (jetzig.zmpl.findPrefixed("mailers", mailer.html_template)) |template|
|
||||||
try template.render(&data, jetzig.TemplateContext, .{}, .{})
|
try template.render(&data, jetzig.TemplateContext, .{}, &.{}, .{})
|
||||||
else
|
else
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ fn defaultText(
|
|||||||
try data.addConst("jetzig_view", data.string(""));
|
try data.addConst("jetzig_view", data.string(""));
|
||||||
try data.addConst("jetzig_action", data.string(""));
|
try data.addConst("jetzig_action", data.string(""));
|
||||||
return if (jetzig.zmpl.findPrefixed("mailers", mailer.text_template)) |template|
|
return if (jetzig.zmpl.findPrefixed("mailers", mailer.text_template)) |template|
|
||||||
try template.render(&data, jetzig.TemplateContext, .{}, .{})
|
try template.render(&data, jetzig.TemplateContext, .{}, &.{}, .{})
|
||||||
else
|
else
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ pub const HtmxMiddleware = @import("middleware/HtmxMiddleware.zig");
|
|||||||
pub const CompressionMiddleware = @import("middleware/CompressionMiddleware.zig");
|
pub const CompressionMiddleware = @import("middleware/CompressionMiddleware.zig");
|
||||||
pub const AuthMiddleware = @import("middleware/AuthMiddleware.zig");
|
pub const AuthMiddleware = @import("middleware/AuthMiddleware.zig");
|
||||||
pub const AntiCsrfMiddleware = @import("middleware/AntiCsrfMiddleware.zig");
|
pub const AntiCsrfMiddleware = @import("middleware/AntiCsrfMiddleware.zig");
|
||||||
|
pub const InertiaMiddleware = @import("middleware/InertiaMiddleware.zig");
|
||||||
|
|
||||||
const RouteOptions = struct {
|
const RouteOptions = struct {
|
||||||
content: ?[]const u8 = null,
|
content: ?[]const u8 = null,
|
||||||
|
6
src/jetzig/middleware/InertiaMiddleware.zig
Normal file
6
src/jetzig/middleware/InertiaMiddleware.zig
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const jetzig = @import("../../jetzig.zig");
|
||||||
|
|
||||||
|
// WIP
|
||||||
|
|
||||||
|
const InertiaMiddleware = @This();
|
13
src/jetzig/templates/inertia.zmpl
Normal file
13
src/jetzig/templates/inertia.zmpl
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
@partial views:inertia/head
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div
|
||||||
|
id="app"
|
||||||
|
data-page='{"component":"{{jetzig_view}}","props":{{zmpl.toJson()}},"url":"{{context.path()}}","version":"c32b8e4965f418ad16eaebba1d4e960f"}'
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -6,6 +6,7 @@ const jetzig = @import("../../jetzig.zig");
|
|||||||
|
|
||||||
data: *jetzig.data.Data,
|
data: *jetzig.data.Data,
|
||||||
status_code: jetzig.http.status_codes.StatusCode = .ok,
|
status_code: jetzig.http.status_codes.StatusCode = .ok,
|
||||||
|
content: ?[]const u8 = null,
|
||||||
|
|
||||||
pub fn deinit(self: Self) void {
|
pub fn deinit(self: Self) void {
|
||||||
_ = self;
|
_ = self;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user