"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Omar Polo <op@omarpolo.com>
Subject:
breadcumbs for gotwebd
To:
gameoftrees@openbsd.org
Date:
Wed, 29 Nov 2023 17:47:57 +0100

Download raw body.

Thread
I have this, and various other things that will follow, applied on my
instance: <https://git.omarpolo.com>.

Navigating through trees in gotwebd is a bit unpleasant since there is
no '..' entry to navigate upward, so once one is inside a tree view the
only options are to either use the browser history or editing the query
string.

This adds the 'breadcumbs' in the top line, along with the repository
name.  I think it's fitting to have them there.  It also shows the user
what the current path is, something that is not showed elsewhere.

(this is not an excuse for maybe adding in the future a '..' entry in the
tree view)

ok?

diff /home/op/w/got
commit - 1267d012ff46a0020babeb79733d400a56402867
path + /home/op/w/got
blob - d04e49122cc951bb2815072249af493a694624f3
file + gotwebd/pages.tmpl
--- gotwebd/pages.tmpl
+++ gotwebd/pages.tmpl
@@ -42,6 +42,7 @@ enum gotweb_ref_tm {
 	TM_LONG,
 };
 
+static int breadcumbs(struct template *);
 static int datetime(struct template *, time_t, int);
 static int gotweb_render_blob_line(struct template *, const char *, size_t);
 static int gotweb_render_tree_item(struct template *, struct got_tree_entry *);
@@ -56,6 +57,23 @@ static inline int branch(struct template *, struct got
 static inline int rss_tag_item(struct template *, struct repo_tag *);
 static inline int rss_author(struct template *, char *);
 
+static inline char *
+nextsep(char *s, char **t)
+{
+	char *q;
+
+	while (*s == '/')
+		s++;
+	*t = s;
+	if (*s == '\0')
+		return NULL;
+
+	q = strchr(s, '/');
+	if (q == NULL)
+		q = strchr(s, '\0');
+	return q;
+}
+
 !}
 
 {{ define datetime(struct template *tp, time_t t, int fmt) }}
@@ -82,6 +100,59 @@ static inline int rss_author(struct template *, char *
 </time>
 {{ end }}
 
+{{ define breadcumbs(struct template *tp) }}
+{!
+	struct request		*c = tp->tp_arg;
+	struct querystring	*qs = c->t->qs;
+	struct gotweb_url	 url;
+	const char		*folder = qs->folder;
+	char			*t, *s = NULL, *dir = NULL;
+	char			 ch;
+
+	memset(&url, 0, sizeof(url));
+	url.index_page = -1;
+	url.page = -1;
+	url.action = TREE;
+	url.path = qs->path;
+	url.commit = qs->commit;
+
+	if (folder && *folder != '\0') {
+		while (*folder == '/')
+			folder++;
+		dir = strdup(folder);
+		if (dir == NULL)
+			return (-1);
+		s = dir;
+	}
+!}
+  {{ " / " }}
+  <a href="{{ render gotweb_render_url(c, &url) }}">tree</a>
+  {{ " / " }}
+  {{ if dir }}
+    {{ while (s = nextsep(s, &t)) != NULL }}
+      {!
+	ch = *s;
+	*s = '\0';
+	url.folder = dir;
+      !}
+
+      <a href="{{ render gotweb_render_url(c, &url) }}">
+        {{ t }}
+      </a>
+      {{ " / " }}
+
+      {! *s = ch; !}
+    {{ end }}
+  {{ end }}
+
+  {{ if qs->file }}
+    {{ qs->file }}
+  {{ end}}
+
+  {{ finally }}
+  {! free(dir); !}
+{{ end }}
+
 {{ define gotweb_render_page(struct template *tp,
     int (*body)(struct template *)) }}
 {!
@@ -132,7 +203,9 @@ static inline int rss_author(struct template *, char *
             {{ qs->path }}
           </a>
         {{ end }}
-        {{ if qs->action != INDEX }}
+        {{ if qs->action == TREE || qs->action == BLOB }}
+          {{ render breadcumbs(tp) }}
+        {{ else if qs->action != INDEX }}
           {{ " / " }}{{ gotweb_action_name(qs->action) }}
         {{ end }}
       </div>