@@ -4,23 +4,25 @@ const Allocator = std.mem.Allocator;
44const scripty = @import ("scripty" );
55const superhtml = @import ("root.zig" ); // In your case this would be @import("superhtml")
66
7- /// A SuperHTML VM is created by giving it the Context and Value types that
8- /// make up the Scripty evaluation context. See `src/example.zig` in
9- /// https://github.com/kristoff-it/scripty for more details on how that
10- /// works.
7+ /// A SuperHTML VM is created by giving it a Value union that defines
8+ /// the Scripty evaluation context that is made available to SuperHTML
9+ /// templates.
10+ ///
11+ /// See https://github.com/kristoff-it/scripty for more details on how
12+ /// to define a Scripty evaluation context.
1113///
1214/// Note that your Scripty values must have some definitions that are
1315/// required by SuperHTML, such as Optional (used by ':if') and Iterator
1416/// (used by ':loop').
15- const ExampleVM = superhtml .VM (ExampleContext , ExampleValue );
17+ const ExampleVM = superhtml .VM (Value );
1618
1719test ExampleVM {
1820 var arena_state : std.heap.ArenaAllocator = .init (std .testing .allocator );
1921 defer arena_state .deinit ();
2022
2123 const arena = arena_state .allocator ();
2224
23- var ctx : ExampleContext = .{
25+ var ctx : Root = .{
2426 .version = "v0" ,
2527 .page = .{
2628 .title = "Home" ,
@@ -34,7 +36,10 @@ test ExampleVM {
3436 };
3537
3638 const layout_src =
37- \\<a href="$site.link()" :text="$site.name"></a>
39+ \\<ctx foo="$version">
40+ \\ <a href="$site.link()" :text="$site.name"></a>
41+ \\ <span :text="$ctx.foo"></span>
42+ \\</ctx>
3843 ;
3944
4045 const layout_html_ast : superhtml.html.Ast = try .init (arena , layout_src , .superhtml , false );
@@ -76,20 +81,23 @@ test ExampleVM {
7681
7782 try std .testing .expectEqualStrings ("" , err_writer .written ());
7883 try std .testing .expectEqualStrings (
79- \\<a href="https://example.com">Example Website</a>
84+ \\
85+ \\ <a href="https://example.com">Example Website</a>
86+ \\ <span>v0</span>
87+ \\
8088 , out_writer .written ());
8189}
8290
83- const ExampleContext = struct {
91+ const Root = struct {
8492 version : []const u8 ,
8593 page : Page ,
8694 site : Site ,
8795 _force_https : bool ,
8896
8997 // Globals specific to SuperHTML
90- ctx : superhtml .utils .Ctx (ExampleValue ) = .{},
91- loop : ? * ExampleValue .Iterator = null ,
92- @"if" : ? * const ExampleValue .Optional = null ,
98+ ctx : superhtml .utils .Ctx (Value ) = .{},
99+ loop : ? * Value .Iterator = null ,
100+ @"if" : ? * const Value .Optional = null ,
93101
94102 pub const Dot = true ;
95103 pub const PassByRef = true ;
@@ -107,10 +115,10 @@ const ExampleContext = struct {
107115 pub fn call (
108116 site : * const Site ,
109117 gpa : Allocator ,
110- ctx : * const ExampleContext ,
111- args : []const ExampleValue ,
112- ) ! ExampleValue {
113- const bad_arg : ExampleValue = .{ .err = "expected 0 arguments" };
118+ ctx : * const Root ,
119+ args : []const Value ,
120+ ) ! Value {
121+ const bad_arg : Value = .{ .err = "expected 0 arguments" };
114122 if (args .len != 0 ) return bad_arg ;
115123
116124 return .{
@@ -136,10 +144,10 @@ const ExampleContext = struct {
136144 };
137145};
138146
139- pub const ExampleValue = union (Tag ) {
140- global : * const ExampleContext ,
141- site : * const ExampleContext .Site ,
142- page : * const ExampleContext .Page ,
147+ pub const Value = union (enum ) {
148+ root : * Root ,
149+ site : * const Root .Site ,
150+ page : * const Root .Page ,
143151 string : String ,
144152 bool : Bool ,
145153 int : Int ,
@@ -148,7 +156,8 @@ pub const ExampleValue = union(Tag) {
148156 nil ,
149157
150158 // Definitions required by SuperHTML
151- ctx : superhtml .utils .Ctx (ExampleValue ),
159+
160+ ctx : superhtml .utils .Ctx (Value ),
152161 optional : ? * const Optional , // used by :if
153162 iterator : * Iterator , // used by :loop
154163 array : Array ,
@@ -173,87 +182,72 @@ pub const ExampleValue = union(Tag) {
173182
174183 pub const Bool = struct {
175184 value : bool ,
176-
177185 pub const PassByRef = false ;
178186 pub const Builtins = struct {};
179187 };
180188
181- pub const Tag = enum {
182- global ,
183- site ,
184- page ,
185- string ,
186- bool ,
187- int ,
188- float ,
189- err ,
190- nil ,
191-
192- ctx ,
193- optional ,
194- iterator ,
195- array ,
196- };
197-
198- pub const call = scripty .defaultCall (ExampleValue , ExampleContext );
199-
200- pub fn fromStringLiteral (bytes : []const u8 ) ExampleValue {
189+ pub fn fromStringLiteral (bytes : []const u8 ) Value {
201190 return .{ .string = .{ .value = bytes } };
202191 }
203192
204- pub fn fromNumberLiteral (bytes : []const u8 ) ExampleValue {
193+ pub fn fromIntegerLiteral (bytes : []const u8 ) Value {
205194 _ = bytes ;
206195 return .{ .int = .{ .value = 0 } };
207196 }
208197
209- pub fn fromBooleanLiteral (b : bool ) ExampleValue {
198+ pub fn fromFloatLiteral (bytes : []const u8 ) Value {
199+ _ = bytes ;
200+ return .{ .float = .{ .value = 0 } };
201+ }
202+
203+ pub fn fromBooleanLiteral (b : bool ) Value {
210204 return .{ .bool = .{ .value = b } };
211205 }
212206
213- pub fn from (gpa : std.mem.Allocator , value : anytype ) ! ExampleValue {
207+ pub fn from (gpa : std.mem.Allocator , value : anytype ) ! Value {
214208 _ = gpa ;
215209 const T = @TypeOf (value );
216210 switch (T ) {
217- * ExampleContext , * const ExampleContext = > return .{ .global = value },
218- ExampleValue = > return value ,
219- * const ExampleContext .Site = > return .{ .site = value },
220- * const ExampleContext .Page = > return .{ .page = value },
221- ? * const ExampleValue .Optional = > return if (value ) | v | .{ .optional = v } else .nil ,
222- ? * ExampleValue .Iterator = > return if (value ) | v | .{ .iterator = v } else .nil ,
223- superhtml .utils .Ctx (ExampleValue ) = > return .{ .ctx = value },
211+ * Root = > return .{ .root = value },
212+ Value = > return value ,
213+ * Root .Site = > return .{ .site = value },
214+ * Root .Page = > return .{ .page = value },
215+ ? * const Value .Optional = > return if (value ) | v | .{ .optional = v } else .nil ,
216+ ? * Value .Iterator = > return if (value ) | v | .{ .iterator = v } else .nil ,
217+ superhtml .utils .Ctx (Value ) = > return .{ .ctx = value },
224218 []const u8 = > return .{ .string = .{ .value = value } },
225219 usize = > return .{ .int = .{ .value = @intCast (value ) } },
226220 bool = > return .{ .bool = .{ .value = value } },
227221 else = > @compileError ("TODO: add support for " ++ @typeName (T )),
228222 }
229223 }
230224
231- pub fn renderForError (value : ExampleValue , arena : Allocator , w : * Io.Writer ) ! void {
225+ pub fn renderForError (value : Value , arena : Allocator , w : * Io.Writer ) ! void {
232226 _ = arena ;
233227 switch (value ) {
234228 else = > w .print ("{any}" , .{value }) catch return error .ErrIO ,
235229 }
236230 }
237231
238232 pub const Optional = struct {
239- value : ExampleValue ,
233+ value : Value ,
240234
241235 pub const PassByRef = false ;
242236 pub const Builtins = struct {};
243237 };
244238
245239 pub const Iterator = struct {
246- it : ExampleValue = undefined ,
240+ it : Value = undefined ,
247241 idx : usize = 0 ,
248242 first : bool = undefined ,
249243 last : bool = undefined ,
250244 len : usize ,
251245
252- _superhtml_context : superhtml .utils .IteratorContext (ExampleValue , ExampleContext ) = .{},
246+ _superhtml_context : superhtml .utils .IteratorContext (Value ) = .{},
253247 _impl : Impl ,
254248
255249 pub const Impl = union (enum ) {
256- value_it : SliceIterator (ExampleValue ),
250+ value_it : SliceIterator (Value ),
257251
258252 pub fn len (impl : Impl ) usize {
259253 switch (impl ) {
@@ -276,7 +270,7 @@ pub const ExampleValue = union(Tag) {
276270 switch (iter ._impl ) {
277271 inline else = > | * v | {
278272 const item = try v .next (gpa );
279- iter .it = try ExampleValue .from (gpa , item orelse return false );
273+ iter .it = try Value .from (gpa , item orelse return false );
280274 iter .idx += 1 ;
281275 iter .first = iter .idx == 1 ;
282276 iter .last = iter .idx == iter .len ;
@@ -296,10 +290,10 @@ pub const ExampleValue = union(Tag) {
296290 pub fn call (
297291 it : * Iterator ,
298292 _ : Allocator ,
299- _ : * const ExampleContext ,
300- args : []const ExampleValue ,
301- ) ! ExampleValue {
302- const bad_arg : ExampleValue = .{ .err = "expected 0 arguments" };
293+ _ : * const Root ,
294+ args : []const Value ,
295+ ) ! Value {
296+ const bad_arg : Value = .{ .err = "expected 0 arguments" };
303297 if (args .len != 0 ) return bad_arg ;
304298 return it ._superhtml_context .up ();
305299 }
@@ -328,17 +322,17 @@ pub const ExampleValue = union(Tag) {
328322 pub const Array = struct {
329323 len : usize ,
330324 empty : bool ,
331- _items : []const ExampleValue ,
325+ _items : []const Value ,
332326
333327 pub const Builtins = struct {
334328 pub const at = struct {
335329 pub fn call (
336330 arr : Array ,
337331 _ : Allocator ,
338- _ : * const ExampleContext ,
339- args : []const ExampleValue ,
340- ) ! ExampleValue {
341- const bad_arg : ExampleValue = .{ .err = "expected 1 integer argument" };
332+ _ : * const Root ,
333+ args : []const Value ,
334+ ) ! Value {
335+ const bad_arg : Value = .{ .err = "expected 1 integer argument" };
342336 if (args .len != 1 ) return bad_arg ;
343337
344338 const idx = switch (args [0 ]) {
0 commit comments