From 5b647b7b848aa1200d8e4ceef1d25ba365be8fc1 Mon Sep 17 00:00:00 2001
From: tri <tri@thac.loan>
Date: Sun, 5 Oct 2025 12:50:40 +0700
Subject: [PATCH] add opengraph tags

---
 src/main.zig      | 48 ++++++++++++++++++++++++++++++++++++++++++-----
 src/templates.zig | 19 ++++++++++++++-----
 2 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/src/main.zig b/src/main.zig
index cbf5e23..3fcc753 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -151,7 +151,13 @@ pub fn writeHomePage(arena: mem.Allocator, dir: fs.Dir, repos: []RepoSummary) !v
     try templates.base_start(
         arena,
         writer,
-        .{ .breadcrumbs = &.{.{ .text = "repos" }} },
+        .{
+            .breadcrumbs = &.{.{ .text = "repos" }},
+            .opengraph = .{
+                .title = "all repos",
+                .description = try fmt.allocPrint(arena, "repo count: {d}", .{repos.len}),
+            },
+        },
     );
 
     try writer.print(
@@ -258,6 +264,14 @@ pub fn writeRepoPage(
 
     try templates.base_start(arena, writer, .{
         .title = args.repo_name,
+        .opengraph = .{
+            .title = try fmt.allocPrint(
+                arena,
+                "{s}: repo details",
+                .{args.repo_name},
+            ),
+            .description = "",
+        },
         .breadcrumbs = &.{ .{
             .href = "/",
             .text = "repos",
@@ -350,8 +364,18 @@ pub fn writeReadmePage(
     var file_writer = readme_file.writer(&writerBuf);
     const writer = &file_writer.interface;
 
+    const readme_text = try git.readFileAlloc(arena, args.in_repo_dir, readme_filename);
+
     try templates.base_start(arena, writer, .{
         .title = args.repo_name,
+        .opengraph = .{
+            .title = try fmt.allocPrint(
+                arena,
+                "{s}/{s}",
+                .{ args.repo_name, readme_filename },
+            ),
+            .description = readme_text[0..@min(256, readme_text.len)],
+        },
         .breadcrumbs = &.{ .{
             .href = "/",
             .text = "repos",
@@ -377,7 +401,6 @@ pub fn writeReadmePage(
 
     try templates.repo_content_start(writer);
 
-    const readme_text = try git.readFileAlloc(arena, args.in_repo_dir, readme_filename);
     const is_markdown = (ascii.endsWithIgnoreCase(readme_filename, ".md") or
         ascii.endsWithIgnoreCase(readme_filename, ".markdown"));
 
@@ -428,6 +451,10 @@ pub fn writeCommitsPage(
 
     try templates.base_start(arena, writer, .{
         .title = args.repo_name,
+        .opengraph = .{
+            .title = try fmt.allocPrint(arena, "{s}/commits", .{args.repo_name}),
+            .description = try fmt.allocPrint(arena, "{d} commits", .{args.commits.len}),
+        },
         .breadcrumbs = &.{ .{
             .href = "/",
             .text = "repos",
@@ -551,6 +578,10 @@ pub fn writeCommitPage(
 
     try templates.base_start(arena, writer, .{
         .title = commit_label,
+        .opengraph = .{
+            .title = try fmt.allocPrint(arena, "{s}/objects/{s}", .{ args.repo_name, commit_label }),
+            .description = "",
+        },
         .breadcrumbs = &.{
             .{ .href = "/", .text = "repos" },
             .{
@@ -681,6 +712,7 @@ pub fn writeBlobPage(
         "{s}: {s}",
         .{ src_file.hash[0..10], src_file.path },
     );
+    const human_readable_size = try utils.humanReadableSize(arena, src_file.size);
 
     try templates.base_start(arena, writer, .{
         .title = try std.fmt.allocPrint(
@@ -688,6 +720,14 @@ pub fn writeBlobPage(
             "{s} - {s}",
             .{ file_label, args.repo_name },
         ),
+        .opengraph = .{
+            .title = try fmt.allocPrint(
+                arena,
+                "{s}/objects/{s}",
+                .{ args.repo_name, file_label },
+            ),
+            .description = try fmt.allocPrint(arena, "size: {s}", .{human_readable_size}),
+        },
         .breadcrumbs = &.{ .{
             .href = "/",
             .text = "repos",
@@ -701,9 +741,7 @@ pub fn writeBlobPage(
 
     try writer.print(
         \\<p>size: {0s}</p>
-    , .{
-        try utils.humanReadableSize(arena, src_file.size),
-    });
+    , .{human_readable_size});
 
     try writer.writeAll(
         \\<pre class="blob-content">
diff --git a/src/templates.zig b/src/templates.zig
index 831957d..1e70597 100644
--- a/src/templates.zig
+++ b/src/templates.zig
@@ -11,13 +11,15 @@ pub const Crumb = struct {
     text: []const u8,
 };
 
-pub const BaseArgs = struct {
+// Remember to close with base_end()
+pub fn base_start(arena: mem.Allocator, writer: *Io.Writer, args: struct {
     title: ?[]const u8 = null,
     breadcrumbs: []const Crumb,
-};
-
-// Remember to close with base_end()
-pub fn base_start(arena: mem.Allocator, writer: *Io.Writer, args: BaseArgs) !void {
+    opengraph: struct {
+        title: []const u8,
+        description: []const u8,
+    },
+}) !void {
     try writer.print(
         \\<!doctype html>
         \\<html lang="en">
@@ -25,6 +27,11 @@ pub fn base_start(arena: mem.Allocator, writer: *Io.Writer, args: BaseArgs) !voi
         \\    <meta charset="utf-8" />
         \\    <title>{0s}</title>
         \\    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+        \\
+        \\    <meta property="og:site_name" content="khoe" />
+        \\    <meta property="og:title" content="{1s}" />
+        \\    <meta property="og:description" content="{2s}" />
+        \\
         \\    <link rel="stylesheet" href="/_/_khoe-hang/style.css">
         \\    <script src="/_/_khoe-hang/script.js"></script>
         \\  </head>
@@ -40,6 +47,8 @@ pub fn base_start(arena: mem.Allocator, writer: *Io.Writer, args: BaseArgs) !voi
             )
         else
             "khoe",
+        try html.escapeAlloc(arena, args.opengraph.title),
+        try html.escapeAlloc(arena, args.opengraph.description),
     });
 
     for (args.breadcrumbs) |crumb| {
-- 
2.47.3

