srctree

Gregory Mullen parent 969ddae7 07908ac4
add template example

build.zig added: 123, removed: 18, total 105
@@ -3,22 +3,12 @@ const std = @import("std");
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const module = b.addModule("verse", .{
const verse_lib = b.addModule("verse", .{
.root_source_file = b.path("src/verse.zig"),
.target = target,
.optimize = optimize,
});
 
const t_compiler = b.addExecutable(.{
.name = "template-compiler",
.root_source_file = b.path("src/template-compiler.zig"),
.target = target,
});
 
const tc_build_run = b.addRunArtifact(t_compiler);
const tc_build_step = b.step("templates", "Compile templates down into struct");
tc_build_step.dependOn(&tc_build_run.step);
 
const lib_unit_tests = b.addTest(.{
.root_source_file = b.path("src/verse.zig"),
.target = target,
@@ -29,6 +19,7 @@ pub fn build(b: *std.Build) !void {
 
if (std.fs.cwd().access("src/fallback_html/index.html", .{})) {
compiler.addDir("src/fallback_html/");
compiler.addDir("examples/templates/");
compiler.collect() catch unreachable;
const comptime_templates = compiler.buildTemplates() catch unreachable;
// Zig build time doesn't expose it's state in a way I know how to check...
@@ -42,6 +33,7 @@ pub fn build(b: *std.Build) !void {
const examples = [_][]const u8{
"basic",
"cookies",
"template",
};
for (examples) |example| {
const path = try std.fmt.allocPrint(b.allocator, "examples/{s}.zig", .{example});
@@ -54,7 +46,12 @@ pub fn build(b: *std.Build) !void {
// All Examples should compile for tests to pass
test_step.dependOn(&example_exe.step);
 
example_exe.root_module.addImport("verse", module);
example_exe.root_module.addImport("verse", verse_lib);
 
const comptime_structs = compiler.buildStructs() catch unreachable;
verse_lib.addImport("comptime_structs", comptime_structs);
const comptime_templates = compiler.buildTemplates() catch unreachable;
verse_lib.addImport("comptime_templates", comptime_templates);
 
const run_example = b.addRunArtifact(example_exe);
run_example.step.dependOn(b.getInstallStep());
@@ -77,6 +74,7 @@ pub const Compiler = struct {
collected: std.ArrayList([]const u8),
templates: ?*std.Build.Module = null,
structs: ?*std.Build.Module = null,
debugging: bool = false,
 
pub fn init(b: *std.Build) Compiler {
return .{
@@ -139,7 +137,7 @@ pub const Compiler = struct {
pub fn buildStructs(self: *Compiler) !*std.Build.Module {
if (self.structs) |s| return s;
 
//std.debug.print("building structs for {}\n", .{self.collected.items.len});
if (self.debugging) std.debug.print("building structs for {}\n", .{self.collected.items.len});
const local_dir = std.fs.path.dirname(@src().file) orelse ".";
const t_compiler = self.b.addExecutable(.{
.name = "template-compiler",
@@ -153,8 +151,6 @@ pub const Compiler = struct {
t_compiler.root_module.addImport("comptime_templates", comptime_templates);
const tc_build_run = self.b.addRunArtifact(t_compiler);
const tc_structs = tc_build_run.addOutputFileArg("compiled-structs.zig");
const tc_build_step = self.b.step("templates", "Compile templates down into struct");
tc_build_step.dependOn(&tc_build_run.step);
const module = self.b.createModule(.{
.root_source_file = tc_structs,
});
 
filename was Deleted added: 123, removed: 18, total 105
@@ -0,0 +1,58 @@
const std = @import("std");
const Verse = @import("verse");
const Router = Verse.Router;
const BuildFn = Router.BuildFn;
 
const routes = [_]Router.Match{
Router.GET("", index),
};
 
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
 
var server = try Verse.Server.init(
alloc,
.{ .http = .{ .port = 8082 } },
.{ .routefn = route },
);
 
server.serve() catch |err| {
std.debug.print("error: {any}", .{err});
std.posix.exit(1);
};
}
 
fn route(verse: *Verse) Router.Error!BuildFn {
return Verse.Router.router(verse, &routes);
}
 
// This page template is compiled/prepared at comptime.
const ExamplePage = Verse.Template.PageData("templates/example.html");
 
fn index(verse: *Verse) Router.Error!void {
var page = ExamplePage.init(.{
// Simple Variables
.simple_variable = "This is a simple variable",
//.required_but_missing = "Currently unused in the html",
.required_and_provided = "The template requires this from the endpoint",
 
// Customized Variables
// When ornull is used the default null is provided, as the template
// specifies it can be missing.
//.null_variable = "Intentionally left blank",
// The next var could be deleted as the HTML provides a default
.default_provided = "This is the endpoint provided variable",
// Commented so the HTML provided default can be used.
//.default_missing = "This endpoint var could replaced the default",
.positive_number = 1, // Wanted to write 2, but off by one errors are common
 
// Logic based Variables.
// A default isn't provided for .optional, because With statements, require
// an explicit decision.
.optional_with = null,
});
 
try verse.sendPage(&page);
}
 
filename was Deleted added: 123, removed: 18, total 105
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title>Welcome to the Verse!</title>
</head>
<body>
<content>
<!-- You can run and experiment with this example with `zig build run-template` -->
<h1>Verse Template Example</h1>
<!-- Simple Variables that can be replaced by simple slice -->
<p><SimpleVariable /></p>
<!-- The trailing / is optional in Verse, but the HTML is likely invalid -->
<p><SimpleVariable></p>
<!-- Adding or removing variables will generate a compile error. -->
<!-- The leading space will cause Verse to ignore this tag -->
<!-- Because this var is not provided using it will cause an error. -->
<p>< RequiredButMissing /></p>
<!-- Deleting the next tag, will also cause a compile error because -->
<!-- this variable is provided by the example endpoint. -->
<p><RequiredAndProvided /></p>
 
 
<!-- All variables are required by default, but you can use null as well -->
<p><NullVariable ornull /></p>
<!-- You can specify your own default via the HTML as well -->
<p><DefaultProvided default="This default will be replaced by the endpoint" /></p>
<p><DefaultMissing default="This default will used here" /></p>
<!-- Providing valid slices gives you more control of the memory needed -->
<!-- generate any HTML, but there is support for some Zig types -->
<p>The first number: <PositiveNumber type="usize" /></p>
 
 
<!-- Once a name exists, you can't not change the type -->
<!-- The following tags would be invalid and cause a compile error -->
<!-- < SimpleVariable ornull /> -->
<!-- < SimpleVariable default="Invalid" /></p> -->
<!-- < SimpleVariable type="usize" /></p> -->
 
<!-- Some logic is also supported -->
<!-- TODO Write and Document-->
<With OptionalWith>
<p>These internal tags are only seen if optional is defined</p>
</With>
<!--
< For Loop></For>
< Split Slices></For>
< Build TemplateVars _template_name.html />
-->
</content>
</body>
</html>