spb/spbgit Public MIT
SPB Git — the platform hosting itself
JavaScript 73.9%
CSS 11.7%
Nunjucks 11.6%
Shell 2.7%
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