a73x

55f49a0e

add tree and blob file browser pages

a73x   2026-03-30 19:07

Adds TreeTemplate/tree/tree_root handlers for directory listing and
BlobTemplate/blob handler for file content. split_ref_path() helper
splits "ref/path" input. Routes: /{repo}/tree, /{repo}/tree/{*rest},
/{repo}/blob/{*rest}.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

diff --git a/src/server/http/templates/blob.html b/src/server/http/templates/blob.html
new file mode 100644
index 0000000..148f187
--- /dev/null
+++ b/src/server/http/templates/blob.html
@@ -0,0 +1,13 @@
{% extends "repo_base.html" %}

{% block title %}{{ file_path }} — {{ repo_name }} — {{ site_title }}{% endblock %}

{% block content %}
<h2>{{ file_path }}</h2>
<p style="color: var(--text-muted);">Ref: <span class="mono">{{ ref_name }}</span> &nbsp; Size: {{ size_display }}</p>
{% if is_binary %}
<p style="color: var(--text-muted); font-style: italic;">Binary file</p>
{% else %}
<pre>{{ content }}</pre>
{% endif %}
{% endblock %}
diff --git a/src/server/http/templates/tree.html b/src/server/http/templates/tree.html
new file mode 100644
index 0000000..487b650
--- /dev/null
+++ b/src/server/http/templates/tree.html
@@ -0,0 +1,34 @@
{% extends "repo_base.html" %}

{% block title %}Tree — {{ repo_name }} — {{ site_title }}{% endblock %}

{% block content %}
<h2>Tree: {{ ref_name }}{% if !path_display.is_empty() %} / {{ path_display }}{% endif %}</h2>
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    {% if show_parent %}
    <tr>
      <td class="mono"><a href="/{{ repo_name }}/tree/{{ ref_name }}/{{ parent_path }}">..</a></td>
      <td style="color: var(--text-muted);">dir</td>
    </tr>
    {% endif %}
    {% for entry in entries %}
    <tr>
      {% if entry.is_dir %}
      <td class="mono"><a href="/{{ repo_name }}/tree/{{ ref_name }}/{{ entry.full_path }}">{{ entry.name }}/</a></td>
      <td style="color: var(--text-muted);">dir</td>
      {% else %}
      <td class="mono"><a href="/{{ repo_name }}/blob/{{ ref_name }}/{{ entry.full_path }}">{{ entry.name }}</a></td>
      <td style="color: var(--text-muted);">file</td>
      {% endif %}
    </tr>
    {% endfor %}
  </tbody>
</table>
{% endblock %}