diff --git a/build.zig.zon b/build.zig.zon index b17abb0..98c1104 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -3,8 +3,8 @@ .version = "0.0.0", .dependencies = .{ .supermd = .{ - .url = "git+https://github.com/kristoff-it/supermd#e6acc6a80c26940f819eda0741ed16c385d7daf4", - .hash = "1220b8f73b279176b97cbe98639b49c1a5f42d5de7d233e67b1c69e5798479f00836", + .url = "git+https://github.com/kristoff-it/supermd#a034ec48c8a01b26de50f479090716d3ed2152c9", + .hash = "122058e6f4ebd493d1c7f7c1e21549d2b2e5d9a1921dba758f3558d88a34a70384be", }, .scripty = .{ .url = "git+https://github.com/kristoff-it/scripty#df8c11380f9e9bec34809f2242fb116d27cf39d6", diff --git a/src/context/Page.zig b/src/context/Page.zig index fc8ccc1..48152bd 100644 --- a/src/context/Page.zig +++ b/src/context/Page.zig @@ -83,15 +83,15 @@ pub const Translation = struct { }; pub const Alternative = struct { - name: []const u8 = "", + name: []const u8, layout: []const u8, output: []const u8, type: []const u8 = "", + _prefix: []const u8 = "", pub const dot = scripty.defaultDot(Alternative, Value, false); // pub const PassByRef = true; - pub const Builtins = struct {}; pub const description = \\An alternative version of the current page. Title and type \\can be used when generating `` elements. @@ -113,7 +113,7 @@ pub const Alternative = struct { \\Useful for example to generate RSS links: \\ \\```superhtml - \\ \\ + \\ ; - pub const examples = ""; pub fn call( - _: *const Page, - _: Allocator, - _: []const Value, + p: *const Page, + gpa: Allocator, + args: []const Value, ) !Value { - return .{ .err = "deprecated, use `link`" }; + const bad_arg = .{ + .err = "expected 1 string argument", + }; + if (args.len != 1) return bad_arg; + + const alt_name = switch (args[0]) { + .string => |s| s.value, + else => return bad_arg, + }; + + for (p.alternatives) |alt| { + if (std.mem.eql(u8, alt.name, alt_name)) { + return Value.from(gpa, alt); + } + } + + return .{ + .err = "unable to find an alertnative with the provided name", + }; } }; diff --git a/src/exes/layout/cache.zig b/src/exes/layout/cache.zig index 0c0b8e6..4d9a215 100644 --- a/src/exes/layout/cache.zig +++ b/src/exes/layout/cache.zig @@ -759,6 +759,8 @@ fn loadPage( .is_root = is_root_page, }; + for (page.alternatives) |*alt| @constCast(alt)._prefix = site._meta.url_path_prefix; + if (page.translation_key) |tk| { const tk_index_path = try join(gpa, &.{ index_dir_path, "tk", tk }); const tk_index = try std.fs.cwd().readFileAlloc( @@ -957,7 +959,33 @@ fn loadPage( inline else => |val, tag| { const res = switch (val.src.?) { .url => continue, - .self_page => context.String.init(""), + .self_page => blk: { + if (@hasField(@TypeOf(val), "alternative")) { + if (val.alternative) |alt_name| { + for (page.alternatives) |alt| { + if (std.mem.eql(u8, alt.name, alt_name)) { + const abs = try join(gpa, &.{ + "/", + site._meta.url_path_prefix, + alt.output, + "/", + }); + break :blk context.String.init(abs); + } + } else reportError( + n, + md_src, + md_rel_path, + md_path, + fm_offset, + is_section, + "the page has no alternative with this name", + ); + } + } + break :blk context.String.init(""); + }, + .page => |p| blk: { const page_site = if (p.locale) |lc| sites.get(lc) orelse reportError( @@ -1043,6 +1071,30 @@ fn loadPage( } } + if (@hasField(@TypeOf(val), "alternative")) { + if (val.alternative) |alt_name| { + for (pp.alternatives) |alt| { + if (std.mem.eql(u8, alt.name, alt_name)) { + const abs = try join(gpa, &.{ + "/", + pp._meta.site._meta.url_path_prefix, + alt.output, + "/", + }); + break :blk context.String.init(abs); + } + } else reportError( + n, + md_src, + md_rel_path, + md_path, + fm_offset, + is_section, + "the page has no alternative with this name", + ); + } + } + if (page_site == site) { break :blk try context.Page.Builtins.link.call( pp,