Convert commit.ts to a mithril template

7d2ffa80003d332bc0d6f4a4ab41aa34b5b50bb4

Tucker McKnight <tucker@pangolin.lan> | Sun Jan 25 2026

Convert commit.ts to a mithril template
js_templates/commit.ts:1
Before

0
1
i⁣
⁣
mport {NavHelper} from './helpers/nav.ts'

export default async (
After
0
1
2
3
import m from 'mithril'
import render from 'mithril-node-render'
import {NavHelper} from './helpers/nav.ts'

export default async (
js_templates/commit.ts:10
Before
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28







29

30
31
32
33
34






35

36
37
38
39
40
41
42
43
44
45



46

47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65

66
67

68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
  const lineNumbers = eleventyConfig.getFilter("lineNumbers")
  const languageExtension = eleventyConfig.getFilter("languageExtension")

  return `
    <div class="row">
      <div class="col-auto">
        <div class="bezel-secondary px-3 py-2">
          <h1 class="fs-2">${data.patchInfo.commit.message.split('\n')[0]}</h2>
          <div class="input-group mb-2 flex-nowrap">
            <span class="font-monospace input-group-text border-info text-white text-bg-dark overflow-scroll">${data.patchInfo.commit.hash}</span>
            <button data-copy-text='${data.patchInfo.commit.hash}' class="btn btn-info shadow-none copy-button">Copy</button>
          </div>
          <p>${data.patchInfo.commit.author} | ${date(data.patchInfo.commit.date)}</p>
          <pre class="mb-0">${data.patchInfo.commit.message}</pre>
        </div>
      </div>
    </div>
    <div class="row my-4">
      <div class="col-auto">
        <div class="form-check">
⁣
⁣
⁣
⁣
⁣
⁣
⁣
          <input class="form-check-input" type="radio" name="unified" id="splitModeSwitch" value="split" onchange="toggleUnifiedMode(this)" checked><label class="form-check-label" for="splitModeSwitch">
            Side-by-side
          </label>
        </div>
        <div class="form-check">
⁣
⁣
⁣
⁣
⁣
⁣
          <input class="form-check-input" type="radio" name="unified" id="unifiedModeSwitch" value="unified" onchange="toggleUnifiedMode(this)"><label class="form-check-label" for="unifiedModeSwitch">
            Stacked
          </label>
        </div>
      </div>
    </div>
    <div class="row" id="diffs">
      ${data.patchInfo.commit.diffs.map((hunk) => {
        return `
          <div class=hunk>
⁣
⁣
⁣
            <span class="font-monospace fw-bold"><a href="${data.reposPath}/${slugify(data.patchInfo.repoName)}/branches/${slugify(data.patchInfo.branchName)}/files/${hunk.fileName.split('/').map((filePart) => { return filePart.split('.').map((subpart) => { return slugify(subpart)}).join('.')}).join('/')}.html">${hunk.fileName}:${hunk.lineNumber}</a></span>            <div class="diff d-flex">
              <div class="flex-grow-1 diff-left pe-2">
                <span class='font-monospace text-secondary'>Before</span>
                <div class="row">
                  <div class="col-auto border-end"><pre class="mb-0">
${lineNumbers(hunk.beforeText).map((lineNumber) => {
  return (lineNumber + hunk.lineNumber - 1).toString()
⁣
}).join('\n')}</pre></div>
                  <div class="col overflow-scroll">
                    <pre class="mb-0" data-start="${hunk.lineNumber}"><code data-type="before" class="line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}">${hunk.beforeText}</code></pre>
                  </div>
                </div>
              </div>
              <div class="diff-right flex-grow-1">
                <span class='font-monospace text-secondary'>After</span>
                <div class="row">
                  <div class="col-auto border-end"><pre class="mb-0">
${lineNumbers(hunk.beforeText).map((lineNumber) => {
  return (lineNumber + hunk.lineNumber - 1).toString()
⁣
}).join('\n')}</pre></div>
                  <div class="col overflow-scroll">                    <pre class="mb-0" data-start="${hunk.lineNumber}"><code data-type="after" class="line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}">${hunk.afterText}</code></pre>
                  </div>
                </div>
              </div>
            </div>
          </div>
        `
⁣
      }).join('')}
    </div>

    <script>
      const toggleUnifiedMode = (e) => {
        const diffs = document.getElementById('diffs')
        const afterDiffs = document.querySelectorAll('.diff-right')
        if (e.value == "unified") {
          diffs.classList.add("unified")
        }
        else {
          diffs.classList.remove("unified")
        }
      }
⁣
    </script>
  `
}
After
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38

39
40
41
42
43
44
45
46
47
48

49

50
51
52

53

54
55
56
57
58
59
60
61
62
63

64
65
66

67
68
69
70
71
72
73
74

75
76
77

78
79
80

81
82
83
84
85
86
87


88
89
90
91
92
93
94
95
96
97
98
99
100
101
  const lineNumbers = eleventyConfig.getFilter("lineNumbers")
  const languageExtension = eleventyConfig.getFilter("languageExtension")

  return render([
    m('div', {class: "row"},
      m('div', {class: "col-auto"},
        m('div', {class: "bezel-secondary px-3 py-2"}, [
          m('h1', {class: "fs-2"}, data.patchInfo.commit.message.split('\n')[0]),
          m('div', {class: "input-group mb-2 flex-nowrap"}, [
            m('span', {class: "font-monospace input-group-text border-info text-white text-bg-dark overflow-scroll"}, data.patchInfo.commit.hash),
            m('button', {'data-copy-text': data.patchInfo.commit.hash, class: "btn btn-info shadow-none copy-button"}, 'Copy')
          ]),
          m('p', `${data.patchInfo.commit.author} | ${date(data.patchInfo.commit.date)}`),
          m('pre', {class: "mb-0"}, data.patchInfo.commit.message)
        ])
      )
    ),
    m('div', {class: "row my-4"},
      m('div', {class: "col-auto"}, [
        m('div', {class: "form-check"}, [
          m('input', {
            class: "form-check-input",
            type: "radio",
            name: "unified",
            id: "splitModeSwitch",
            value: "split",
            onchange: "toggleUnifiedMode(this)",
            checked: true,
          }),
⁣
          m('label', {class: "form-check-label", for: "splitModeSwitch"}, 'Side-by-side'),]),
        m('div', {class: "form-check"}, [
          m('input', {
            class: "form-check-input",
            type: "radio",
            name: "unified",
            id: "unifiedModeSwitch",
            value: "unified",
            onchange: "toggleUnifiedMode(this)",
          }),
⁣
          m('label', {class: "form-check-label", for: "unifiedModeSwitch"}, 'Stacked')])
      ])
    ),m('div', {class: "row", id: "diffs"}, data.patchInfo.commit.diffs.map((hunk) => {
⁣
      return m('div', {class: 'hunk'}, [
        m('span', {class: "font-monospace fw-bold"},
          m('a', {
            href: `${data.reposPath}/${slugify(data.patchInfo.repoName)}/branches/${slugify(data.patchInfo.branchName)}/files/${hunk.fileName.split('/').map((filePart) => { return filePart.split('.').map((subpart) => { return slugify(subpart)}).join('.')}).join('/')}.html`
          }, `${hunk.fileName}:${hunk.lineNumber}`)
        ),
        m('div', {class: "diff d-flex"}, [
          m('div', {class: "flex-grow-1 diff-left pe-2"}, [
            m('span', {class: 'font-monospace text-secondary'}, 'Before'),
            m('div', {class: "row"}, [              m('div', {class: "col-auto border-end"}, m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
                return (lineNumber + hunk.lineNumber - 1).toString()
              }))),
⁣
              m('div', {class: "col overflow-scroll"},
                m('pre', {class: "mb-0", 'data-start': hunk.lineNumber}, m('code', {'data-type': 'before', class: `line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}`}, hunk.beforeText))
              )
            ])
          ]),
          m('div', {class: "diff-right flex-grow-1"}, [
            m('span', {class: 'font-monospace text-secondary'}, 'After'),
            m('div', {class: "row"},              m('div', {class: "col-auto border-end"}, m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
                  return (lineNumber + hunk.lineNumber - 1).toString()
              }))),
⁣
              m('div', {class: "col overflow-scroll"},
                m('pre', {class: "mb-0", 'data-start': hunk.lineNumber},
                  m('code', {'data-type': "after", class: `line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}`}, hunk.afterText))
              )
            )
          ])
        ])
      ])
    })),
⁣
⁣
    m('script', m.trust(`
const toggleUnifiedMode = (e) => {
  const diffs = document.getElementById('diffs')
  const afterDiffs = document.querySelectorAll('.diff-right')
  if (e.value == "unified") {
    diffs.classList.add("unified")
  }
  else {
    diffs.classList.remove("unified")
  }
}
`)
    )
  ])
}