Makko, the people-oriented static site generator made for blogging. forge.starlightnet.work/Team/Makko
ssg static-site-generator makko starlight-network
at main 4.8 kB view raw
1const std = @import("std"); 2const datetime = @import("datetime"); 3 4const helper = @import("helper.zig"); 5const Data = @import("Data.zig"); 6const Makko = @import("Makko.zig"); 7 8const FeedGenerator = @This(); 9 10name: []const u8, 11func: fn (Makko, data: Data, writer: anytype) anyerror!void, 12 13pub const generator_list = [_]FeedGenerator{ 14 .{ .func = html, .name = "html" }, 15 .{ .func = rss, .name = "rss" }, 16 .{ .func = atom, .name = "atom" }, 17}; 18 19fn html(state: Makko, data: Data, writer: anytype) !void { 20 const allocator = state.allocator; 21 22 const json_data = try helper.valueToJson(allocator, data); 23 defer json_data.deinit(); 24 25 if (state.templates.feed == null) 26 return error.MissingTemplate; 27 28 const first_pass = try helper.template( 29 allocator, 30 state.templates.feed.?, 31 json_data.value, 32 ); 33 defer allocator.free(first_pass); 34 35 const second_pass = try helper.template( 36 allocator, 37 first_pass, 38 json_data.value, 39 ); 40 defer allocator.free(second_pass); 41 42 try writer.writeAll(second_pass); 43} 44 45fn rss(state: Makko, data: Data, writer: anytype) !void { 46 const allocator = state.allocator; 47 const website = data.website; 48 49 const general_dt = datetime.datetime.Datetime.now(); 50 const now_http = try general_dt.formatHttp(allocator); 51 defer allocator.free(now_http); 52 53 try writer.print( 54 \\<?xml version="1.0" encoding="UTF-8"?> 55 \\<rss version="2.0"> 56 \\ <channel> 57 \\ <title>{s}</title> 58 \\ <link>{s}</link> 59 \\ <description>{s}</description> 60 \\ <generator>makko</generator> 61 \\ <lastBuildDate>{s}</lastBuildDate> 62 \\ 63 , 64 .{ website.title, website.url, website.description, now_http }, 65 ); 66 67 for (data.posts.?) |post| { 68 if (post.is_secret) continue; 69 70 const post_link = try std.mem.concat( 71 allocator, 72 u8, 73 &[_][]const u8{ website.url, "/", post.url }, 74 ); 75 defer allocator.free(post_link); 76 77 const dt = datetime.datetime.Datetime.fromTimestamp(post.created.raw); 78 const pub_date = try dt.formatHttp(allocator); 79 defer allocator.free(pub_date); 80 81 try writer.print( 82 \\ <item> 83 \\ <title>{s}</title> 84 \\ <link>{s}</link> 85 \\ <pubDate>{s}</pubDate> 86 \\ <author>{s}</author> 87 \\ <description>{s}</description> 88 \\ </item> 89 \\ 90 , 91 .{ post.title, post_link, pub_date, post.author, post.description }, 92 ); 93 } 94 95 try writer.writeAll( 96 \\ </channel> 97 \\</rss> 98 \\ 99 ); 100} 101 102fn atom(state: Makko, data: Data, writer: anytype) !void { 103 const allocator = state.allocator; 104 105 const now = datetime.datetime.Datetime.now(); 106 const now_iso8601 = try now.formatISO8601(allocator, false); 107 defer allocator.free(now_iso8601); 108 109 const website = data.website; 110 111 try writer.print( 112 \\<?xml version="1.0" encoding="utf-8"?> 113 \\<feed xmlns="http://www.w3.org/2005/Atom"> 114 \\ <title>{s}</title> 115 \\ <link href="{s}"/> 116 \\ <updated>{s}</updated> 117 \\ <id>{s}</id> 118 \\ <generator>makko</generator> 119 \\ 120 , 121 .{ website.title, website.url, now_iso8601, website.url }, 122 ); 123 124 for (data.posts.?) |post| { 125 if (post.is_secret) continue; 126 127 const post_link = try std.mem.concat( 128 allocator, 129 u8, 130 &[_][]const u8{ website.url, "/", post.url }, 131 ); 132 defer allocator.free(post_link); 133 134 const upd_dt = datetime.datetime.Datetime.fromTimestamp(post.updated.raw); 135 const upd_iso8601 = try upd_dt.formatISO8601(allocator, false); 136 defer state.allocator.free(upd_iso8601); 137 138 const pub_dt = datetime.datetime.Datetime.fromTimestamp(post.created.raw); 139 const pub_iso8601 = try pub_dt.formatISO8601(allocator, false); 140 defer state.allocator.free(pub_iso8601); 141 142 try writer.print( 143 \\ <entry> 144 \\ <title>{s}</title> 145 \\ <link href="{s}"/> 146 \\ <id>{s}</id> 147 \\ <published>{s}</published> 148 \\ <updated>{s}</updated> 149 \\ <author><name>{s}</name></author> 150 \\ <summary>{s}</summary> 151 \\ </entry> 152 \\ 153 , 154 .{ 155 post.title, 156 post_link, 157 post_link, // use URL as unique ID 158 pub_iso8601, 159 upd_iso8601, 160 post.author, 161 post.description, 162 }, 163 ); 164 } 165 166 try writer.writeAll("</feed>\n"); 167}