Genearte .zig verions of templates to use in production.

This commit is contained in:
2026-01-28 17:01:28 +05:30
parent 4092e6ad8e
commit 8db2e0df37
1170 changed files with 10153 additions and 3722 deletions

View File

@@ -1,229 +0,0 @@
//! Pugz Benchmark - Template Rendering
//!
//! Two benchmark modes:
//! 1. Cached AST: Parse once, render 2000 times (matches Pug.js behavior)
//! 2. No Cache: Parse + render on every iteration
//!
//! Run: zig build bench
const std = @import("std");
const pugz = @import("pugz");
const iterations: usize = 2000;
const templates_dir = "benchmarks/templates";
// Data structures matching JSON files
const SubFriend = struct {
id: i64,
name: []const u8,
};
const Friend = struct {
name: []const u8,
balance: []const u8,
age: i64,
address: []const u8,
picture: []const u8,
company: []const u8,
email: []const u8,
emailHref: []const u8,
about: []const u8,
tags: []const []const u8,
friends: []const SubFriend,
};
const Account = struct {
balance: i64,
balanceFormatted: []const u8,
status: []const u8,
negative: bool,
};
const Project = struct {
name: []const u8,
url: []const u8,
description: []const u8,
};
const SearchRecord = struct {
imgUrl: []const u8,
viewItemUrl: []const u8,
title: []const u8,
description: []const u8,
featured: bool,
sizes: ?[]const []const u8,
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Load JSON data
var data_arena = std.heap.ArenaAllocator.init(allocator);
defer data_arena.deinit();
const data_alloc = data_arena.allocator();
const simple0 = try loadJson(struct { name: []const u8 }, data_alloc, "simple-0.json");
const simple1 = try loadJson(struct {
name: []const u8,
messageCount: i64,
colors: []const []const u8,
primary: bool,
}, data_alloc, "simple-1.json");
const simple2 = try loadJson(struct {
header: []const u8,
header2: []const u8,
header3: []const u8,
header4: []const u8,
header5: []const u8,
header6: []const u8,
list: []const []const u8,
}, data_alloc, "simple-2.json");
const if_expr = try loadJson(struct { accounts: []const Account }, data_alloc, "if-expression.json");
const projects = try loadJson(struct {
title: []const u8,
text: []const u8,
projects: []const Project,
}, data_alloc, "projects-escaped.json");
const search = try loadJson(struct { searchRecords: []const SearchRecord }, data_alloc, "search-results.json");
const friends_data = try loadJson(struct { friends: []const Friend }, data_alloc, "friends.json");
// Load template sources
const simple0_tpl = try loadTemplate(data_alloc, "simple-0.pug");
const simple1_tpl = try loadTemplate(data_alloc, "simple-1.pug");
const simple2_tpl = try loadTemplate(data_alloc, "simple-2.pug");
const if_expr_tpl = try loadTemplate(data_alloc, "if-expression.pug");
const projects_tpl = try loadTemplate(data_alloc, "projects-escaped.pug");
const search_tpl = try loadTemplate(data_alloc, "search-results.pug");
const friends_tpl = try loadTemplate(data_alloc, "friends.pug");
// ═══════════════════════════════════════════════════════════════════════
// Benchmark 1: Cached AST (parse once, render many)
// ═══════════════════════════════════════════════════════════════════════
std.debug.print("\n", .{});
std.debug.print("╔═══════════════════════════════════════════════════════════════╗\n", .{});
std.debug.print("║ Pugz Benchmark - CACHED AST ({d} iterations) ║\n", .{iterations});
std.debug.print("║ Mode: Parse once, render many (like Pug.js) ║\n", .{});
std.debug.print("╚═══════════════════════════════════════════════════════════════╝\n", .{});
std.debug.print("\nParsing templates...\n", .{});
const simple0_ast = try pugz.template.parse(data_alloc, simple0_tpl);
const simple1_ast = try pugz.template.parse(data_alloc, simple1_tpl);
const simple2_ast = try pugz.template.parse(data_alloc, simple2_tpl);
const if_expr_ast = try pugz.template.parse(data_alloc, if_expr_tpl);
const projects_ast = try pugz.template.parse(data_alloc, projects_tpl);
const search_ast = try pugz.template.parse(data_alloc, search_tpl);
const friends_ast = try pugz.template.parse(data_alloc, friends_tpl);
std.debug.print("Starting benchmark (render only)...\n\n", .{});
var total_cached: f64 = 0;
total_cached += try benchCached("simple-0", allocator, simple0_ast, simple0);
total_cached += try benchCached("simple-1", allocator, simple1_ast, simple1);
total_cached += try benchCached("simple-2", allocator, simple2_ast, simple2);
total_cached += try benchCached("if-expression", allocator, if_expr_ast, if_expr);
total_cached += try benchCached("projects-escaped", allocator, projects_ast, projects);
total_cached += try benchCached("search-results", allocator, search_ast, search);
total_cached += try benchCached("friends", allocator, friends_ast, friends_data);
std.debug.print("\n", .{});
std.debug.print(" {s:<20} => {d:>7.1}ms\n", .{ "TOTAL (cached)", total_cached });
std.debug.print("\n", .{});
// ═══════════════════════════════════════════════════════════════════════
// Benchmark 2: No Cache (parse + render every time)
// ═══════════════════════════════════════════════════════════════════════
std.debug.print("\n", .{});
std.debug.print("╔═══════════════════════════════════════════════════════════════╗\n", .{});
std.debug.print("║ Pugz Benchmark - NO CACHE ({d} iterations) ║\n", .{iterations});
std.debug.print("║ Mode: Parse + render every iteration ║\n", .{});
std.debug.print("╚═══════════════════════════════════════════════════════════════╝\n", .{});
std.debug.print("\nStarting benchmark (parse + render)...\n\n", .{});
var total_nocache: f64 = 0;
total_nocache += try benchNoCache("simple-0", allocator, simple0_tpl, simple0);
total_nocache += try benchNoCache("simple-1", allocator, simple1_tpl, simple1);
total_nocache += try benchNoCache("simple-2", allocator, simple2_tpl, simple2);
total_nocache += try benchNoCache("if-expression", allocator, if_expr_tpl, if_expr);
total_nocache += try benchNoCache("projects-escaped", allocator, projects_tpl, projects);
total_nocache += try benchNoCache("search-results", allocator, search_tpl, search);
total_nocache += try benchNoCache("friends", allocator, friends_tpl, friends_data);
std.debug.print("\n", .{});
std.debug.print(" {s:<20} => {d:>7.1}ms\n", .{ "TOTAL (no cache)", total_nocache });
std.debug.print("\n", .{});
// ═══════════════════════════════════════════════════════════════════════
// Summary
// ═══════════════════════════════════════════════════════════════════════
std.debug.print("╔═══════════════════════════════════════════════════════════════╗\n", .{});
std.debug.print("║ SUMMARY ║\n", .{});
std.debug.print("╚═══════════════════════════════════════════════════════════════╝\n", .{});
std.debug.print(" Cached AST (render only): {d:>7.1}ms\n", .{total_cached});
std.debug.print(" No Cache (parse+render): {d:>7.1}ms\n", .{total_nocache});
std.debug.print(" Parse overhead: {d:>7.1}ms ({d:.1}%)\n", .{
total_nocache - total_cached,
((total_nocache - total_cached) / total_nocache) * 100.0,
});
std.debug.print("\n", .{});
}
fn loadJson(comptime T: type, alloc: std.mem.Allocator, comptime filename: []const u8) !T {
const path = templates_dir ++ "/" ++ filename;
const content = try std.fs.cwd().readFileAlloc(alloc, path, 10 * 1024 * 1024);
const parsed = try std.json.parseFromSlice(T, alloc, content, .{});
return parsed.value;
}
fn loadTemplate(alloc: std.mem.Allocator, comptime filename: []const u8) ![]const u8 {
const path = templates_dir ++ "/" ++ filename;
return try std.fs.cwd().readFileAlloc(alloc, path, 1 * 1024 * 1024);
}
// Benchmark with cached AST (render only)
fn benchCached(
name: []const u8,
allocator: std.mem.Allocator,
ast: *pugz.parser.Node,
data: anytype,
) !f64 {
var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();
var timer = try std.time.Timer.start();
for (0..iterations) |_| {
_ = arena.reset(.retain_capacity);
_ = pugz.template.renderAst(arena.allocator(), ast, data) catch |err| {
std.debug.print(" {s:<20} => ERROR: {}\n", .{ name, err });
return 0;
};
}
const ms = @as(f64, @floatFromInt(timer.read())) / 1_000_000.0;
std.debug.print(" {s:<20} => {d:>7.1}ms\n", .{ name, ms });
return ms;
}
// Benchmark without cache (parse + render every iteration)
fn benchNoCache(
name: []const u8,
allocator: std.mem.Allocator,
source: []const u8,
data: anytype,
) !f64 {
var timer = try std.time.Timer.start();
for (0..iterations) |_| {
var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();
_ = pugz.template.renderWithData(arena.allocator(), source, data) catch |err| {
std.debug.print(" {s:<20} => ERROR: {}\n", .{ name, err });
return 0;
};
}
const ms = @as(f64, @floatFromInt(timer.read())) / 1_000_000.0;
std.debug.print(" {s:<20} => {d:>7.1}ms\n", .{ name, ms });
return ms;
}

View File

@@ -0,0 +1,13 @@
const std = @import("std");
const helpers = @import("helpers.zig");
pub const Data = struct {};
pub fn render(allocator: std.mem.Allocator, _: Data) ![]const u8 {
var buf: std.ArrayListUnmanaged(u8) = .{};
defer buf.deinit(allocator);
try buf.appendSlice(allocator, "<div class=\"'friend'\"><h3>friend_name</h3><p>friend_email</p><p>friend_about</p><span class=\"'tag'\">tag_value</span></div>");
return buf.toOwnedSlice(allocator);
}

View File

@@ -0,0 +1,33 @@
// Auto-generated helpers for compiled Pug templates
// This file is copied to the generated directory to provide shared utilities
const std = @import("std");
/// Append HTML-escaped string to buffer
pub fn appendEscaped(buf: *std.ArrayListUnmanaged(u8), allocator: std.mem.Allocator, str: []const u8) !void {
for (str) |c| {
switch (c) {
'&' => try buf.appendSlice(allocator, "&amp;"),
'<' => try buf.appendSlice(allocator, "&lt;"),
'>' => try buf.appendSlice(allocator, "&gt;"),
'"' => try buf.appendSlice(allocator, "&quot;"),
'\'' => try buf.appendSlice(allocator, "&#39;"),
else => try buf.append(allocator, c),
}
}
}
/// Check if a value is truthy (for conditionals)
pub fn isTruthy(val: anytype) bool {
const T = @TypeOf(val);
return switch (@typeInfo(T)) {
.bool => val,
.int, .float => val != 0,
.pointer => |ptr| switch (ptr.size) {
.slice => val.len > 0,
else => true,
},
.optional => if (val) |v| isTruthy(v) else false,
else => true,
};
}

View File

@@ -0,0 +1,13 @@
const std = @import("std");
const helpers = @import("helpers.zig");
pub const Data = struct {};
pub fn render(allocator: std.mem.Allocator, _: Data) ![]const u8 {
var buf: std.ArrayListUnmanaged(u8) = .{};
defer buf.deinit(allocator);
try buf.appendSlice(allocator, "<p>Active</p><p>Inactive</p>");
return buf.toOwnedSlice(allocator);
}

View File

@@ -0,0 +1,13 @@
const std = @import("std");
const helpers = @import("helpers.zig");
pub const Data = struct {};
pub fn render(allocator: std.mem.Allocator, _: Data) ![]const u8 {
var buf: std.ArrayListUnmanaged(u8) = .{};
defer buf.deinit(allocator);
try buf.appendSlice(allocator, "<li><a href=\"/project\">project_name</a>: project_description</li>");
return buf.toOwnedSlice(allocator);
}

View File

@@ -0,0 +1,10 @@
// Auto-generated by pug-compile
// This file exports all compiled templates
pub const friends = @import("./friends.zig");
pub const if_expression = @import("./if-expression.zig");
pub const projects_escaped = @import("./projects-escaped.zig");
pub const search_results = @import("./search-results.zig");
pub const simple_0 = @import("./simple-0.zig");
pub const simple_1 = @import("./simple-1.zig");
pub const simple_2 = @import("./simple-2.zig");

View File

@@ -0,0 +1,13 @@
const std = @import("std");
const helpers = @import("helpers.zig");
pub const Data = struct {};
pub fn render(allocator: std.mem.Allocator, _: Data) ![]const u8 {
var buf: std.ArrayListUnmanaged(u8) = .{};
defer buf.deinit(allocator);
try buf.appendSlice(allocator, "<div><h3>result_title</h3><span>$result_price</span></div>");
return buf.toOwnedSlice(allocator);
}

View File

@@ -0,0 +1,13 @@
const std = @import("std");
const helpers = @import("helpers.zig");
pub const Data = struct {};
pub fn render(allocator: std.mem.Allocator, _: Data) ![]const u8 {
var buf: std.ArrayListUnmanaged(u8) = .{};
defer buf.deinit(allocator);
try buf.appendSlice(allocator, "<p>Hello World</p>");
return buf.toOwnedSlice(allocator);
}

View File

@@ -0,0 +1,13 @@
const std = @import("std");
const helpers = @import("helpers.zig");
pub const Data = struct {};
pub fn render(allocator: std.mem.Allocator, _: Data) ![]const u8 {
var buf: std.ArrayListUnmanaged(u8) = .{};
defer buf.deinit(allocator);
try buf.appendSlice(allocator, "<!DOCTYPE html><html><head><title>My Site</title></head><body><h1>Welcome</h1><p>This is a simple page</p></body></html>");
return buf.toOwnedSlice(allocator);
}

View File

@@ -0,0 +1,13 @@
const std = @import("std");
const helpers = @import("helpers.zig");
pub const Data = struct {};
pub fn render(allocator: std.mem.Allocator, _: Data) ![]const u8 {
var buf: std.ArrayListUnmanaged(u8) = .{};
defer buf.deinit(allocator);
try buf.appendSlice(allocator, "<h1>Header</h1><h2>Header2</h2><h3>Header3</h3><h4>Header4</h4><h5>Header5</h5><h6>Header6</h6><ul><li>item1</li><li>item2</li><li>item3</li></ul>");
return buf.toOwnedSlice(allocator);
}

View File

@@ -1,86 +0,0 @@
/**
* Pug.js Benchmark - Comparison with Pugz
*
* Run: npm install && npm run bench
*
* Both Pug.js and Pugz benchmarks read from the same files:
* ../templates/*.pug (templates)
* ../templates/*.json (data)
*/
const fs = require('fs');
const path = require('path');
const pug = require('pug');
const iterations = 2000;
const templatesDir = path.join(__dirname, '..', 'templates');
const benchmarks = [
'simple-0',
'simple-1',
'simple-2',
'if-expression',
'projects-escaped',
'search-results',
'friends',
];
// ═══════════════════════════════════════════════════════════════════════════
// Load templates and data from shared files BEFORE benchmarking
// ═══════════════════════════════════════════════════════════════════════════
console.log("");
console.log("Loading templates and data...");
const templates = {};
const data = {};
for (const name of benchmarks) {
templates[name] = fs.readFileSync(path.join(templatesDir, `${name}.pug`), 'utf8');
data[name] = JSON.parse(fs.readFileSync(path.join(templatesDir, `${name}.json`), 'utf8'));
}
// Compile all templates BEFORE benchmarking
const compiled = {};
for (const name of benchmarks) {
compiled[name] = pug.compile(templates[name], { pretty: true });
}
console.log("Templates compiled. Starting benchmark...\n");
// ═══════════════════════════════════════════════════════════════════════════
// Benchmark
// ═══════════════════════════════════════════════════════════════════════════
console.log("╔═══════════════════════════════════════════════════════════════╗");
console.log(`║ Pug.js Benchmark (${iterations} iterations) ║`);
console.log("║ Templates: benchmarks/templates/*.pug ║");
console.log("║ Data: benchmarks/templates/*.json ║");
console.log("╚═══════════════════════════════════════════════════════════════╝");
let total = 0;
for (const name of benchmarks) {
const compiledFn = compiled[name];
const templateData = data[name];
// Warmup
for (let i = 0; i < 100; i++) {
compiledFn(templateData);
}
// Benchmark
const start = process.hrtime.bigint();
for (let i = 0; i < iterations; i++) {
compiledFn(templateData);
}
const end = process.hrtime.bigint();
const ms = Number(end - start) / 1_000_000;
total += ms;
console.log(` ${name.padEnd(20)} => ${ms.toFixed(1).padStart(7)}ms`);
}
console.log("");
console.log(` ${"TOTAL".padEnd(20)} => ${total.toFixed(1).padStart(7)}ms`);
console.log("");

View File

@@ -1,576 +0,0 @@
{
"name": "pugjs-benchmark",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pugjs-benchmark",
"version": "1.0.0",
"dependencies": {
"pug": "^3.0.3"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz",
"integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==",
"license": "MIT",
"dependencies": {
"@babel/types": "^7.28.6"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/types": {
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz",
"integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.28.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"license": "MIT"
},
"node_modules/assert-never": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz",
"integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==",
"license": "MIT"
},
"node_modules/babel-walk": {
"version": "3.0.0-canary-5",
"resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz",
"integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==",
"license": "MIT",
"dependencies": {
"@babel/types": "^7.9.6"
},
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/character-parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
"integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==",
"license": "MIT",
"dependencies": {
"is-regex": "^1.0.3"
}
},
"node_modules/constantinople": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
"integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.6.0",
"@babel/types": "^7.6.1"
}
},
"node_modules/doctypes": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
"integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==",
"license": "MIT"
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-core-module": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-expression": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz",
"integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==",
"license": "MIT",
"dependencies": {
"acorn": "^7.1.1",
"object-assign": "^4.1.1"
}
},
"node_modules/is-promise": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
"integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
"license": "MIT"
},
"node_modules/is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"gopd": "^1.2.0",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/js-stringify": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
"integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==",
"license": "MIT"
},
"node_modules/jstransformer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
"integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==",
"license": "MIT",
"dependencies": {
"is-promise": "^2.0.0",
"promise": "^7.0.1"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"license": "MIT"
},
"node_modules/promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"license": "MIT",
"dependencies": {
"asap": "~2.0.3"
}
},
"node_modules/pug": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz",
"integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==",
"license": "MIT",
"dependencies": {
"pug-code-gen": "^3.0.3",
"pug-filters": "^4.0.0",
"pug-lexer": "^5.0.1",
"pug-linker": "^4.0.0",
"pug-load": "^3.0.0",
"pug-parser": "^6.0.0",
"pug-runtime": "^3.0.1",
"pug-strip-comments": "^2.0.0"
}
},
"node_modules/pug-attrs": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz",
"integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==",
"license": "MIT",
"dependencies": {
"constantinople": "^4.0.1",
"js-stringify": "^1.0.2",
"pug-runtime": "^3.0.0"
}
},
"node_modules/pug-code-gen": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz",
"integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==",
"license": "MIT",
"dependencies": {
"constantinople": "^4.0.1",
"doctypes": "^1.1.0",
"js-stringify": "^1.0.2",
"pug-attrs": "^3.0.0",
"pug-error": "^2.1.0",
"pug-runtime": "^3.0.1",
"void-elements": "^3.1.0",
"with": "^7.0.0"
}
},
"node_modules/pug-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz",
"integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==",
"license": "MIT"
},
"node_modules/pug-filters": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz",
"integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==",
"license": "MIT",
"dependencies": {
"constantinople": "^4.0.1",
"jstransformer": "1.0.0",
"pug-error": "^2.0.0",
"pug-walk": "^2.0.0",
"resolve": "^1.15.1"
}
},
"node_modules/pug-lexer": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz",
"integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==",
"license": "MIT",
"dependencies": {
"character-parser": "^2.2.0",
"is-expression": "^4.0.0",
"pug-error": "^2.0.0"
}
},
"node_modules/pug-linker": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz",
"integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==",
"license": "MIT",
"dependencies": {
"pug-error": "^2.0.0",
"pug-walk": "^2.0.0"
}
},
"node_modules/pug-load": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz",
"integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==",
"license": "MIT",
"dependencies": {
"object-assign": "^4.1.1",
"pug-walk": "^2.0.0"
}
},
"node_modules/pug-parser": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz",
"integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==",
"license": "MIT",
"dependencies": {
"pug-error": "^2.0.0",
"token-stream": "1.0.0"
}
},
"node_modules/pug-runtime": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz",
"integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==",
"license": "MIT"
},
"node_modules/pug-strip-comments": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz",
"integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==",
"license": "MIT",
"dependencies": {
"pug-error": "^2.0.0"
}
},
"node_modules/pug-walk": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz",
"integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==",
"license": "MIT"
},
"node_modules/resolve": {
"version": "1.22.11",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
"integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
"license": "MIT",
"dependencies": {
"is-core-module": "^2.16.1",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/token-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
"integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==",
"license": "MIT"
},
"node_modules/void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/with": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz",
"integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.9.6",
"@babel/types": "^7.9.6",
"assert-never": "^1.2.1",
"babel-walk": "3.0.0-canary-5"
},
"engines": {
"node": ">= 10.0.0"
}
}
}
}

View File

@@ -1,12 +0,0 @@
{
"name": "pugjs-benchmark",
"version": "1.0.0",
"description": "Pug.js benchmark for comparison with Pugz",
"main": "bench.js",
"scripts": {
"bench": "node bench.js"
},
"dependencies": {
"pug": "^3.0.3"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,7 @@
doctype html
html(lang="en")
head
meta(charset="UTF-8")
title Friends
body
div.friends
each friend in friends
div.friend
ul
li Name: #{friend.name}
li Balance: #{friend.balance}
li Age: #{friend.age}
li Address: #{friend.address}
li Image:
img(src=friend.picture)
li Company: #{friend.company}
li Email:
a(href=friend.emailHref) #{friend.email}
li About: #{friend.about}
if friend.tags
li Tags:
ul
each tag in friend.tags
li #{tag}
if friend.friends
li Friends:
ul
each subFriend in friend.friends
li #{subFriend.name} (#{subFriend.id})
each friend in friends
.friend
h3= friend.name
p= friend.email
p= friend.about
each tag in friend.tags
span.tag= tag

View File

@@ -1,28 +1,16 @@
{
"accounts": [
{
"balance": 0,
"balanceFormatted": "$0.00",
"status": "open",
"balance": 100,
"balanceFormatted": "$100",
"status": "active",
"negative": false
},
{
"balance": 10,
"balanceFormatted": "$10.00",
"status": "closed",
"negative": false
},
{
"balance": -100,
"balanceFormatted": "$-100.00",
"status": "suspended",
"balance": -50,
"balanceFormatted": "-$50",
"status": "overdrawn",
"negative": true
},
{
"balance": 999,
"balanceFormatted": "$999.00",
"status": "open",
"negative": false
}
]
}

View File

@@ -1,13 +1,4 @@
each account in accounts
div
if account.status == "closed"
div Your account has been closed!
if account.status == "suspended"
div Your account has been temporarily suspended
if account.status == "open"
div
| Bank balance:
if account.negative
span.negative= account.balanceFormatted
else
span.positive= account.balanceFormatted
if active
p Active
else
p Inactive

View File

@@ -1,41 +1,21 @@
{
"title": "Projects",
"text": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>",
"text": "My awesome projects",
"projects": [
{
"name": "<strong>Facebook</strong>",
"url": "http://facebook.com",
"description": "Social network"
"name": "Project A",
"url": "/project-a",
"description": "Description A"
},
{
"name": "<strong>Google</strong>",
"url": "http://google.com",
"description": "Search engine"
"name": "Project B",
"url": "/project-b",
"description": "Description B"
},
{
"name": "<strong>Twitter</strong>",
"url": "http://twitter.com",
"description": "Microblogging service"
},
{
"name": "<strong>Amazon</strong>",
"url": "http://amazon.com",
"description": "Online retailer"
},
{
"name": "<strong>eBay</strong>",
"url": "http://ebay.com",
"description": "Online auction"
},
{
"name": "<strong>Wikipedia</strong>",
"url": "http://wikipedia.org",
"description": "A free encyclopedia"
},
{
"name": "<strong>LiveJournal</strong>",
"url": "http://livejournal.com",
"description": "Blogging platform"
"name": "Project C",
"url": "/project-c",
"description": "Description C"
}
]
}

View File

@@ -1,11 +1,5 @@
doctype html
html
head
title #{title}
body
p #{text}
each project in projects
a(href=project.url) #{project.name}
p #{project.description}
else
p No projects
each project in projects
.project
h3= project.name
a(href=project.url) Link
p= project.description

View File

@@ -1,278 +1,36 @@
{
"searchRecords": [
{
"imgUrl": "img1.jpg",
"viewItemUrl": "http://foo/1",
"title": "Namebox",
"description": "Duis laborum nostrud consectetur exercitation minim ad laborum velit adipisicing.",
"imgUrl": "/img1.jpg",
"viewItemUrl": "/item1",
"title": "Item 1",
"description": "Desc 1",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
"L"
]
},
{
"imgUrl": "img2.jpg",
"viewItemUrl": "http://foo/2",
"title": "Arctiq",
"description": "Incididunt ea mollit commodo velit officia. Enim officia occaecat nulla aute.",
"featured": false,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img3.jpg",
"viewItemUrl": "http://foo/3",
"title": "Niquent",
"description": "Aliquip Lorem consequat sunt ipsum dolor amet amet cupidatat deserunt eiusmod.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img4.jpg",
"viewItemUrl": "http://foo/4",
"title": "Remotion",
"description": "Est ad amet irure veniam dolore velit amet irure fugiat ut elit.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img5.jpg",
"viewItemUrl": "http://foo/5",
"title": "Octocore",
"description": "Sunt ex magna culpa cillum esse irure consequat Lorem aliquip enim sit.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img6.jpg",
"viewItemUrl": "http://foo/6",
"title": "Spherix",
"description": "Duis laborum nostrud consectetur exercitation minim ad laborum velit adipisicing.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img7.jpg",
"viewItemUrl": "http://foo/7",
"title": "Quarex",
"description": "Incididunt ea mollit commodo velit officia. Enim officia occaecat nulla aute.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img8.jpg",
"viewItemUrl": "http://foo/8",
"title": "Supremia",
"description": "Aliquip Lorem consequat sunt ipsum dolor amet amet cupidatat deserunt eiusmod.",
"featured": false,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img9.jpg",
"viewItemUrl": "http://foo/9",
"title": "Amtap",
"description": "Est ad amet irure veniam dolore velit amet irure fugiat ut elit.",
"featured": false,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img10.jpg",
"viewItemUrl": "http://foo/10",
"title": "Qiao",
"description": "Sunt ex magna culpa cillum esse irure consequat Lorem aliquip enim sit.",
"featured": false,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img11.jpg",
"viewItemUrl": "http://foo/11",
"title": "Pushcart",
"description": "Duis laborum nostrud consectetur exercitation minim ad laborum velit adipisicing.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img12.jpg",
"viewItemUrl": "http://foo/12",
"title": "Eweville",
"description": "Incididunt ea mollit commodo velit officia. Enim officia occaecat nulla aute.",
"featured": false,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img13.jpg",
"viewItemUrl": "http://foo/13",
"title": "Senmei",
"description": "Aliquip Lorem consequat sunt ipsum dolor amet amet cupidatat deserunt eiusmod.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img14.jpg",
"viewItemUrl": "http://foo/14",
"title": "Maximind",
"description": "Est ad amet irure veniam dolore velit amet irure fugiat ut elit.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img15.jpg",
"viewItemUrl": "http://foo/15",
"title": "Blurrybus",
"description": "Sunt ex magna culpa cillum esse irure consequat Lorem aliquip enim sit.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img16.jpg",
"viewItemUrl": "http://foo/16",
"title": "Virva",
"description": "Duis laborum nostrud consectetur exercitation minim ad laborum velit adipisicing.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img17.jpg",
"viewItemUrl": "http://foo/17",
"title": "Centregy",
"description": "Incididunt ea mollit commodo velit officia. Enim officia occaecat nulla aute.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img18.jpg",
"viewItemUrl": "http://foo/18",
"title": "Dancerity",
"description": "Aliquip Lorem consequat sunt ipsum dolor amet amet cupidatat deserunt eiusmod.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img19.jpg",
"viewItemUrl": "http://foo/19",
"title": "Oceanica",
"description": "Est ad amet irure veniam dolore velit amet irure fugiat ut elit.",
"featured": true,
"sizes": [
"S",
"M",
"L",
"XL",
"XXL"
]
},
{
"imgUrl": "img20.jpg",
"viewItemUrl": "http://foo/20",
"title": "Synkgen",
"description": "Sunt ex magna culpa cillum esse irure consequat Lorem aliquip enim sit.",
"imgUrl": "/img2.jpg",
"viewItemUrl": "/item2",
"title": "Item 2",
"description": "Desc 2",
"featured": false,
"sizes": null
},
{
"imgUrl": "/img3.jpg",
"viewItemUrl": "/item3",
"title": "Item 3",
"description": "Desc 3",
"featured": true,
"sizes": [
"M",
"L",
"XL"
]
}
]
}

View File

@@ -1,17 +1,5 @@
.search-results.view-gallery
each searchRecord in searchRecords
.search-item
.search-item-container.drop-shadow
.img-container
img(src=searchRecord.imgUrl)
h4.title
a(href=searchRecord.viewItemUrl)= searchRecord.title
| #{searchRecord.description}
if searchRecord.featured
div Featured!
if searchRecord.sizes
div
| Sizes available:
ul
each size in searchRecord.sizes
li= size
each result in results
.result
img(src=result.imgUrl)
a(href=result.viewItemUrl)= result.title
.price= result.price

View File

@@ -1,3 +1,3 @@
{
"name": "John"
"name": "World"
}

View File

@@ -1 +1 @@
h1 Hello, #{name}
p Hello World

View File

@@ -1,19 +1,10 @@
{
"name": "George Washington",
"messageCount": 999,
"name": "Test",
"messageCount": 5,
"colors": [
"red",
"green",
"blue",
"yellow",
"orange",
"pink",
"black",
"white",
"beige",
"brown",
"cyan",
"magenta"
"green"
],
"primary": true
}

View File

@@ -1,14 +1,7 @@
.simple-1(style="background-color: blue; border: 1px solid black")
.colors
span.hello Hello #{name}!
strong You have #{messageCount} messages!
if colors
ul
each color in colors
li.color= color
else
div No colors!
if primary
button(type="button" class="primary") Click me!
else
button(type="button" class="secondary") Click me!
doctype html
html
head
title My Site
body
h1 Welcome
p This is a simple page

View File

@@ -1,20 +1,13 @@
{
"header": "Header",
"header2": "Header2",
"header3": "Header3",
"header4": "Header4",
"header5": "Header5",
"header6": "Header6",
"header": "Header 1",
"header2": "Header 2",
"header3": "Header 3",
"header4": "Header 4",
"header5": "Header 5",
"header6": "Header 6",
"list": [
"1000000000",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10"
"Item 1",
"Item 2",
"Item 3"
]
}

View File

@@ -1,10 +1,11 @@
div
h1.header #{header}
h2.header2 #{header2}
h3.header3 #{header3}
h4.header4 #{header4}
h5.header5 #{header5}
h6.header6 #{header6}
ul.list
each item in list
li.item #{item}
doctype html
html
head
title Page
body
.container
h1.header Welcome
ul
li Item 1
li Item 2
li Item 3