SPB Git

spb/spbgit Public MIT

SPB Git — the platform hosting itself

JavaScript 73.9% CSS 11.7% Nunjucks 11.6% Shell 2.7%
3.9 KB · 84 lines jinja
Raw Blame History
1{#2  ─────────────────────────────────────────────3   SPB Git — Personal Git Platform4  ─────────────────────────────────────────────5   Author  : Simon-Pierre Boucher6   Contact : contact@spboucher.ai7   File    : src/web/views/blob.njk8   Purpose : File view — sticky header, shiki code, line anchors9   License : MIT © Simon-Pierre Boucher10  ─────────────────────────────────────────────11#}{% extends "layout.njk" %}12{% block content %}13{% include "partials/repo-header.njk" %}1415<div class="blob-card">16  <div class="blob-header">17    <nav class="path-breadcrumb" aria-label="Path">18      <a href="/{{ overview.name }}">{{ overview.name }}</a>19      {% for crumb in crumbs %}20      <span class="crumb-sep">/</span>{% if loop.last %}<strong>{{ crumb.name }}</strong>{% else %}<a href="{{ crumb.href | replace('/blame/', '/tree/') | replace('/blob/', '/tree/') }}">{{ crumb.name }}</a>{% endif %}21      {% endfor %}22    </nav>23    <div class="blob-meta">24      <span class="muted">{{ blobSize | bytes }}</span>25      {% if view.lines %}<span class="muted">· {{ view.lines | num }} lines</span>{% endif %}26      {% if view.lang %}<span class="chip">{{ view.lang }}</span>{% endif %}27    </div>28    <div class="blob-actions">29      {% if view.isMarkdown %}30        {% if view.kind == 'markdown' %}31        <a class="btn btn-sm" href="?plain=1" rel="nofollow">View source</a>32        {% else %}33        <a class="btn btn-sm" href="/{{ overview.name }}/blob/{{ currentRef }}/{{ path }}" rel="nofollow">Rendered</a>34        {% endif %}35      {% endif %}36      {% if view.kind == 'code' %}37      <button class="btn btn-sm code-copy" type="button" data-code-copy data-code-target="#code-view" title="Copy file contents">38        <span class="code-copy-label">Copy file</span>39      </button>40      {% endif %}41      <a class="btn btn-sm" href="{{ rawUrl }}" rel="nofollow">Raw</a>42      <a class="btn btn-sm" href="/{{ overview.name }}/blame/{{ currentRef }}/{{ path }}" rel="nofollow">Blame</a>43      <a class="btn btn-sm" href="/{{ overview.name }}/commits/{{ currentRef }}?path={{ path | urlencode }}" rel="nofollow">History</a>44      <button class="btn btn-sm copy-btn" type="button"45              data-copy="{{ publicUrl }}/{{ overview.name }}/blob/{{ refSha }}/{{ path }}"46              title="Copy permalink (pinned to {{ refSha | truncate(7, true, '') }})">Permalink</button>47    </div>48  </div>4950  {% if view.notebookNote %}51  <p class="notice">Jupyter notebook shown as formatted JSON. Download the <a href="{{ rawUrl }}">raw file</a> to open it in Jupyter.</p>52  {% endif %}5354  {% if view.kind == 'pdf' %}55  <div class="pdf-viewer">56    <object class="pdf-frame" data="{{ rawUrl }}" type="application/pdf" aria-label="PDF viewer — {{ fileName }}">57      <div class="pdf-fallback">58        <p>Your browser cannot display PDFs inline.</p>59        <a class="btn btn-primary" href="{{ rawUrl }}" download>Download {{ fileName }}</a>60      </div>61    </object>62  </div>63  {% elif view.kind == 'binary' %}64    {% if view.isImage %}65    <div class="blob-image"><img src="{{ rawUrl }}" alt="{{ fileName }}"></div>66    {% else %}67    <div class="blob-binary">68      <p>Binary file — {{ blobSize | bytes }}.</p>69      <a class="btn btn-primary" href="{{ rawUrl }}" download>Download</a>70    </div>71    {% endif %}72  {% elif view.kind == 'toolarge' %}73  <div class="blob-binary">74    <p>This file is {{ blobSize | bytes }} — too large to display.</p>75    <a class="btn btn-primary" href="{{ rawUrl }}">View raw</a>76  </div>77  {% elif view.kind == 'markdown' %}78  <article class="markdown-body blob-markdown">{{ view.html | safe }}</article>79  {% else %}80  <div class="code-view" id="code-view">{{ view.html | safe }}</div>81  {% endif %}82</div>83{% endblock %}84