Compiled temapltes.
Benchmark cleanup
This commit is contained in:
50
examples/demo/build.zig
Normal file
50
examples/demo/build.zig
Normal file
@@ -0,0 +1,50 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
// Get dependencies
|
||||
const pugz_dep = b.dependency("pugz", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
const httpz_dep = b.dependency("httpz", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// Compile templates at build time using pugz's build_templates
|
||||
// Generates views/generated.zig with all templates
|
||||
const build_templates = @import("pugz").build_templates;
|
||||
const compiled_templates = build_templates.compileTemplates(b, .{
|
||||
.source_dir = "views",
|
||||
});
|
||||
|
||||
// Main executable
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "demo",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.imports = &.{
|
||||
.{ .name = "pugz", .module = pugz_dep.module("pugz") },
|
||||
.{ .name = "httpz", .module = httpz_dep.module("httpz") },
|
||||
.{ .name = "tpls", .module = compiled_templates },
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
b.installArtifact(exe);
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const run_step = b.step("run", "Run the demo server");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
21
examples/demo/build.zig.zon
Normal file
21
examples/demo/build.zig.zon
Normal file
@@ -0,0 +1,21 @@
|
||||
.{
|
||||
.name = .demo,
|
||||
.version = "0.0.1",
|
||||
.fingerprint = 0xd642dfa01393173d,
|
||||
.minimum_zig_version = "0.15.2",
|
||||
.dependencies = .{
|
||||
.pugz = .{
|
||||
.path = "../..",
|
||||
},
|
||||
.httpz = .{
|
||||
.url = "git+https://github.com/karlseguin/http.zig?ref=master#9ef2ffe8d611ff2e1081e5cf39cb4632c145c5b9",
|
||||
.hash = "httpz-0.0.0-PNVzrIowBwAFr_kqBN1W4KBMC2Ofutasj2ZfNAIcfTzF",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
"views",
|
||||
},
|
||||
}
|
||||
156
examples/demo/src/main.zig
Normal file
156
examples/demo/src/main.zig
Normal file
@@ -0,0 +1,156 @@
|
||||
//! Pugz Demo - Interpreted vs Compiled Templates
|
||||
//!
|
||||
//! This demo shows two approaches:
|
||||
//! 1. **Interpreted** (ViewEngine) - supports extends/blocks, parsed at runtime
|
||||
//! 2. **Compiled** (build-time) - 3x faster, templates compiled to Zig code
|
||||
//!
|
||||
//! Routes:
|
||||
//! GET / - Compiled home page (fast)
|
||||
//! GET /users - Compiled users list (fast)
|
||||
//! GET /interpreted - Interpreted with inheritance (flexible)
|
||||
//! GET /page-a - Interpreted page A
|
||||
|
||||
const std = @import("std");
|
||||
const httpz = @import("httpz");
|
||||
const pugz = @import("pugz");
|
||||
|
||||
// Compiled templates - generated at build time from views/compiled/*.pug
|
||||
const tpls = @import("tpls");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
/// Application state shared across all requests
|
||||
const App = struct {
|
||||
allocator: Allocator,
|
||||
view: pugz.ViewEngine,
|
||||
|
||||
pub fn init(allocator: Allocator) App {
|
||||
return .{
|
||||
.allocator = allocator,
|
||||
.view = pugz.ViewEngine.init(.{
|
||||
.views_dir = "views",
|
||||
}),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer if (gpa.deinit() == .leak) @panic("leak");
|
||||
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var app = App.init(allocator);
|
||||
|
||||
const port = 8080;
|
||||
var server = try httpz.Server(*App).init(allocator, .{ .port = port }, &app);
|
||||
defer server.deinit();
|
||||
|
||||
var router = try server.router(.{});
|
||||
|
||||
// Compiled template routes (fast - 3x faster than Pug.js)
|
||||
router.get("/", indexCompiled, .{});
|
||||
router.get("/users", usersCompiled, .{});
|
||||
|
||||
// Interpreted template routes (flexible - supports extends/blocks)
|
||||
router.get("/interpreted", indexInterpreted, .{});
|
||||
router.get("/page-a", pageA, .{});
|
||||
|
||||
std.debug.print(
|
||||
\\
|
||||
\\Pugz Demo - Interpreted vs Compiled Templates
|
||||
\\=============================================
|
||||
\\Server running at http://localhost:{d}
|
||||
\\
|
||||
\\Compiled routes (3x faster than Pug.js):
|
||||
\\ GET / - Home page (compiled)
|
||||
\\ GET /users - Users list (compiled)
|
||||
\\
|
||||
\\Interpreted routes (supports extends/blocks):
|
||||
\\ GET /interpreted - Home with ViewEngine
|
||||
\\ GET /page-a - Page with inheritance
|
||||
\\
|
||||
\\Press Ctrl+C to stop.
|
||||
\\
|
||||
, .{port});
|
||||
|
||||
try server.listen();
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Compiled template handlers (fast - no parsing at runtime)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// GET / - Compiled home page
|
||||
fn indexCompiled(_: *App, _: *httpz.Request, res: *httpz.Response) !void {
|
||||
const html = tpls.home(res.arena, .{
|
||||
.title = "Welcome - Compiled",
|
||||
.authenticated = true,
|
||||
}) catch |err| {
|
||||
res.status = 500;
|
||||
res.body = @errorName(err);
|
||||
return;
|
||||
};
|
||||
|
||||
res.content_type = .HTML;
|
||||
res.body = html;
|
||||
}
|
||||
|
||||
/// GET /users - Compiled users list
|
||||
fn usersCompiled(_: *App, _: *httpz.Request, res: *httpz.Response) !void {
|
||||
const User = struct {
|
||||
name: []const u8,
|
||||
email: []const u8,
|
||||
};
|
||||
|
||||
const html = tpls.users(res.arena, .{
|
||||
.title = "Users - Compiled",
|
||||
.users = &[_]User{
|
||||
.{ .name = "Alice", .email = "alice@example.com" },
|
||||
.{ .name = "Bob", .email = "bob@example.com" },
|
||||
.{ .name = "Charlie", .email = "charlie@example.com" },
|
||||
},
|
||||
}) catch |err| {
|
||||
res.status = 500;
|
||||
res.body = @errorName(err);
|
||||
return;
|
||||
};
|
||||
|
||||
res.content_type = .HTML;
|
||||
res.body = html;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Interpreted template handlers (flexible - supports inheritance)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// GET /interpreted - Uses ViewEngine (parsed at runtime)
|
||||
fn indexInterpreted(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
|
||||
const html = app.view.render(res.arena, "index", .{
|
||||
.title = "Home - Interpreted",
|
||||
.authenticated = true,
|
||||
}) catch |err| {
|
||||
res.status = 500;
|
||||
res.body = @errorName(err);
|
||||
return;
|
||||
};
|
||||
|
||||
res.content_type = .HTML;
|
||||
res.body = html;
|
||||
}
|
||||
|
||||
/// GET /page-a - Demonstrates extends and block override
|
||||
fn pageA(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
|
||||
const html = app.view.render(res.arena, "page-a", .{
|
||||
.title = "Page A - Pets",
|
||||
.items = &[_][]const u8{ "A", "B", "C" },
|
||||
.n = 0,
|
||||
}) catch |err| {
|
||||
res.status = 500;
|
||||
res.body = @errorName(err);
|
||||
return;
|
||||
};
|
||||
|
||||
res.content_type = .HTML;
|
||||
res.body = html;
|
||||
}
|
||||
15
examples/demo/views/home.pug
Normal file
15
examples/demo/views/home.pug
Normal file
@@ -0,0 +1,15 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
title #{title}
|
||||
link(rel="stylesheet" href="/style.css")
|
||||
body
|
||||
header
|
||||
h1 #{title}
|
||||
if authenticated
|
||||
span.user Welcome back!
|
||||
main
|
||||
p This page is rendered using a compiled template.
|
||||
p Compiled templates are 3x faster than Pug.js!
|
||||
footer
|
||||
p © 2024 Pugz Demo
|
||||
15
examples/demo/views/index.pug
Normal file
15
examples/demo/views/index.pug
Normal file
@@ -0,0 +1,15 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
title hello
|
||||
body
|
||||
p some thing
|
||||
| ballah
|
||||
| ballah
|
||||
+btn("click me ", "secondary")
|
||||
br
|
||||
a(href='//google.com' target="_blank") Google 1
|
||||
br
|
||||
a(class='button' href='//google.com' target="_blank") Google 2
|
||||
br
|
||||
a(class='button', href='//google.com' target="_blank") Google 3
|
||||
7
examples/demo/views/layout-2.pug
Normal file
7
examples/demo/views/layout-2.pug
Normal file
@@ -0,0 +1,7 @@
|
||||
html
|
||||
head
|
||||
block head
|
||||
script(src='/vendor/jquery.js')
|
||||
script(src='/vendor/caustic.js')
|
||||
body
|
||||
block content
|
||||
10
examples/demo/views/layout.pug
Normal file
10
examples/demo/views/layout.pug
Normal file
@@ -0,0 +1,10 @@
|
||||
html
|
||||
head
|
||||
title My Site - #{title}
|
||||
block scripts
|
||||
script(src='/jquery.js')
|
||||
body
|
||||
block content
|
||||
block foot
|
||||
#footer
|
||||
p some footer content
|
||||
5
examples/demo/views/mixins/buttons.pug
Normal file
5
examples/demo/views/mixins/buttons.pug
Normal file
@@ -0,0 +1,5 @@
|
||||
mixin btn(text, type="primary")
|
||||
button(class="btn btn-" + type)= text
|
||||
|
||||
mixin btn-link(href, text)
|
||||
a.btn.btn-link(href=href)= text
|
||||
11
examples/demo/views/mixins/cards.pug
Normal file
11
examples/demo/views/mixins/cards.pug
Normal file
@@ -0,0 +1,11 @@
|
||||
mixin card(title)
|
||||
.card
|
||||
.card-header
|
||||
h3= title
|
||||
.card-body
|
||||
block
|
||||
|
||||
mixin card-simple(title, body)
|
||||
.card
|
||||
h3= title
|
||||
p= body
|
||||
15
examples/demo/views/page-a.pug
Normal file
15
examples/demo/views/page-a.pug
Normal file
@@ -0,0 +1,15 @@
|
||||
extends layout.pug
|
||||
|
||||
block scripts
|
||||
script(src='/jquery.js')
|
||||
script(src='/pets.js')
|
||||
|
||||
block content
|
||||
h1= title
|
||||
p Welcome to the pets page!
|
||||
ul
|
||||
li Cat
|
||||
li Dog
|
||||
ul
|
||||
each val in items
|
||||
li= val
|
||||
5
examples/demo/views/page-appen-optional-blk.pug
Normal file
5
examples/demo/views/page-appen-optional-blk.pug
Normal file
@@ -0,0 +1,5 @@
|
||||
extends layout
|
||||
|
||||
append head
|
||||
script(src='/vendor/three.js')
|
||||
script(src='/game.js')
|
||||
11
examples/demo/views/page-append.pug
Normal file
11
examples/demo/views/page-append.pug
Normal file
@@ -0,0 +1,11 @@
|
||||
extends layout-2.pug
|
||||
|
||||
block append head
|
||||
script(src='/vendor/three.js')
|
||||
script(src='/game.js')
|
||||
|
||||
block content
|
||||
p
|
||||
| cheks manually the head section
|
||||
br
|
||||
| hello there
|
||||
9
examples/demo/views/page-b.pug
Normal file
9
examples/demo/views/page-b.pug
Normal file
@@ -0,0 +1,9 @@
|
||||
extends sub-layout.pug
|
||||
|
||||
block content
|
||||
.sidebar
|
||||
block sidebar
|
||||
p nothing
|
||||
.primary
|
||||
block primary
|
||||
p nothing
|
||||
1
examples/demo/views/pet.pug
Normal file
1
examples/demo/views/pet.pug
Normal file
@@ -0,0 +1 @@
|
||||
p= petName
|
||||
9
examples/demo/views/sub-layout.pug
Normal file
9
examples/demo/views/sub-layout.pug
Normal file
@@ -0,0 +1,9 @@
|
||||
extends layout.pug
|
||||
|
||||
block content
|
||||
.sidebar
|
||||
block sidebar
|
||||
p nothing
|
||||
.primary
|
||||
block primary
|
||||
p nothing
|
||||
11
examples/demo/views/users.pug
Normal file
11
examples/demo/views/users.pug
Normal file
@@ -0,0 +1,11 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
title Users
|
||||
body
|
||||
h1 User List
|
||||
ul.user-list
|
||||
each user in users
|
||||
li.user
|
||||
strong= user.name
|
||||
span.email= user.email
|
||||
Reference in New Issue
Block a user