Tucker McKnight <tucker@pangolin.lan> | Sun Feb 01 2026
Changes file.ts to mithril template Also fix a small problem with files.ts where it was showing the "view raw file" link on a directory's page.
0 1
export default async (eleventyConfig: any, data: any) => {
const isDirectory = eleventyConfig.getFilter("isDirectory")
const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")0 1 2 3 4
import m from 'mithril'
import render from 'mithril-node-render'
export default async (eleventyConfig: any, data: any) => {
const isDirectory = eleventyConfig.getFilter("isDirectory")
const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")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 102 103 104 105 106 107 108 109 110 111 112 113 114 115
const languageExtension = eleventyConfig.getFilter("languageExtension")
const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
return `
<div class="row mt-3 mb-1">
<div class="col">
<p>Files snapshot from <span class="font-monospace">${data.fileInfo.branchName}</span></p>
</div>
</div>
<div class="row my-1">
<div class="col">
<h3>
<span class="bezel-gray px-1"><a href="${data.reposPath}/${data.fileInfo.repoName}/branches/${data.fileInfo.branchName}/files">./</a></span>${
data.fileInfo.file.split('/').map((dir, index, arr) => {
if (index === arr.length - 1) {
return `<span class="px-2">${dir}</span>`
}
else {
return `<span class="bezel-gray px-1"><a href="${data.reposPath}/${data.fileInfo.repoName}/branches/${data.fileInfo.branchName}/files/${arr.slice(0, index + 1).map((part) => slugify(part)).join('/')}.html">${dir}/</a></span>`
}
}).join('')
}
</h3>
</div>
</div>
<div class="row">
<div class="col">
<p><a href="${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/raw/${data.fileInfo.file.split('.').map(filePart => slugify(filePart)).join('.')}">View raw file</a></p>
</div>
</div>
${isDirectory(data.fileInfo.file, data.fileInfo.repoName, data.fileInfo.branchName) ?
`<div class="row">
<div class="col">
<ul class="list-group">
${topLevelFilesOnly(getDirectoryContents(data.fileInfo.repoName, data.fileInfo.branchName, data.fileInfo.file), data.fileInfo.file + '/').map((dir) => {
return `<li class="list-group-item">
${dir.isDirectory ? `<span>📁</span>` : ''}
<a href="${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/files/${dir.fullPath.split('/').map((pathPart) => {
return pathPart.split('.').map((subPart) => {
return slugify(subPart)
}).join('.')
}).join('/')}.html">${getRelativePath(data.fileInfo.file, dir.name)}</a>
</li>`
}).join('')}
</ul>
</div>
</div>`
:
`
${data.fileInfo.file.endsWith(".md")
? `
<div class="row">
<div class="col">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="showRenderedContent" checked />
<label class="form-check-label" for="showRenderedContent">Show rendered markdown</label>
</div>
</div>
</div>
<div class="row rendered-content py-4">
<div class="col">
${await renderContentIfAvailable(await getFileContents(
data.fileInfo.repoName,
data.fileInfo.branchName,
data.fileInfo.file
), data.fileInfo.branchName)}
</div>
</div>
`
: ''
}
<div class="row code-content ${data.fileInfo.file.endsWith('.md') ? 'd-none' : ''}">
<div class="col">
<div class="row py-2">
<div class="col-auto">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="showLastTouch">
<label class="form-check-label" for="showLastTouch">Show last line change</label>
</div>
</div>
</div>
<div class="row">
<div class="col-auto p-0">
<code style="white-space: pre;"><pre class="language-text">${lineNumbers(await getFileContents(data.fileInfo.repoName, data.fileInfo.branchName, data.fileInfo.file)).map((lineNumber) => {
return lineNumber
}).join('\n')}</pre></code>
</div>
<div id="annotations" class="col-auto d-none p-0">
<code style="white-space: pre;"><pre class="language-text">${
(await getFileLastTouchInfo(
data.fileInfo.repoName,
data.fileInfo.branchName,
data.fileInfo.file
)).map(
(annotation) => {
return `<a href="${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
}
).join('\n')
}</pre></code>
</div>
<div class="col overflow-scroll p-0">
<code>
${
highlightCode(
await getFileContents(
data.fileInfo.repoName,
data.fileInfo.branchName,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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
const languageExtension = eleventyConfig.getFilter("languageExtension")
const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
return render([
m('div', {class: "row mt-3 mb-1"},
m('div', {class: "col"},
m('p', [
'Files snapshot from ',
m('span', {class: "font-monospace"}, data.fileInfo.branchName)
])
)
),
m('div', {class: "row my-1"},
m('div', {class: "col"},
m('h3', [
m('span', {class: "bezel-gray px-1"},
m('a', {href: `${data.reposPath}/${data.fileInfo.repoName}/branches/${data.fileInfo.branchName}/files`}, './')
),
data.fileInfo.file.split('/').map((dir, index, arr) => {
if (index === arr.length - 1) {
return m('span', {class: "px-2"}, dir)
}
else {
return m('span', {class: "bezel-gray px-1"}, [
m('a', {
href: `${data.reposPath}/${data.fileInfo.repoName}/branches/${data.fileInfo.branchName}/files/${arr.slice(0, index + 1).map((part) => slugify(part)).join('/')}.html`}, dir)
])
}
})
])
)
),
(isDirectory(data.fileInfo.file, data.fileInfo.repoName, data.fileInfo.branchName) ?
m('div', {class: "row"},
m('div', {class: "col"},
m('ul', {class: "list-group"},
topLevelFilesOnly(getDirectoryContents(data.fileInfo.repoName, data.fileInfo.branchName, data.fileInfo.file), data.fileInfo.file + '/').map((dir) => {
return m('li', {class: 'list-group-item'}, [
dir.isDirectory ? m('span', m.trust('📁')) : null,
m('a', {
href: `${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/files/${dir.fullPath.split('/').map((pathPart) => {
return pathPart.split('.').map((subPart) => {
return slugify(subPart)
}).join('.')
}).join('/')}.html`},
getRelativePath(data.fileInfo.file, dir.name)
)
])
})
)
)
)
: [
m('div', {class: "row"},
m('div', {class: "col"},
m('p', m('a', {
href: `${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/raw/${data.fileInfo.file.split('.').map(filePart => slugify(filePart)).join('.')}`}, 'View raw file'))
)
),
(data.fileInfo.file.endsWith(".md") ?
[
m('div', {class: "row"},
m('div', {class: "col"},
m('div', {class: "form-check form-switch"}, [
m('input', {
class: "form-check-input",
type: "checkbox",
role: "switch",
id: "showRenderedContent",
checked: true
}),
m('label', {
class: "form-check-label",
for: "showRenderedContent"
}, 'Show rendered markdown')
])
)
),
m('div', {class: "row rendered-content py-4"},
m('div', {class: "col"},
m.trust(await renderContentIfAvailable(await getFileContents(
data.fileInfo.repoName,
data.fileInfo.branchName,
data.fileInfo.file
), data.fileInfo.branchName)
))
)
]
: null),
m('div', {class: `row code-content ${data.fileInfo.file.endsWith('.md') ? 'd-none' : ''}`},
m('div', {class: "col"}, [
m('div', {class: "row py-2"},
m('div', {class: "col-auto"},
m('div', {class: "form-check form-switch"}, [
m('input', {class: "form-check-input", type: "checkbox", role: "switch", id: "showLastTouch"}),
m('label', {class: "form-check-label", for: "showLastTouch"}, 'Show last line change'),
])
)
),
m('div', {class: "row"}, [
m('div', {class: "col-auto p-0"},
m('code', {style: "white-space: pre;"},
m('pre', {class: "language-text"},
lineNumbers(await getFileContents(data.fileInfo.repoName, data.fileInfo.branchName, data.fileInfo.file)).map((lineNumber) => {
return lineNumber
}).join('\n')
)
)
),
m('div', {id: "annotations", class: "col-auto d-none p-0"},
m('code', {style: "white-space: pre;"}, [
m('pre', {class: "language-text"}, m.trust(
(await getFileLastTouchInfo(
data.fileInfo.repoName,
data.fileInfo.branchName,
data.fileInfo.file
)).map((annotation) => {
return `<a href="${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
}).join('\n')))
])
),
m('div', {class: "col overflow-scroll p-0"},
m('code', m.trust(highlightCode(
await getFileContents(
data.fileInfo.repoName,
data.fileInfo.branchName,120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
data.fileInfo.file,
data.fileInfo.repoName
)
)
}
</code>
</div>
</div>
</div>
</div>
`}
<script type="text/javascript">
const toggleLastTouch = (event) => {
const isOn = event.target.checked
const annotations = document.getElementById("annotations")
if (isOn) {
annotations.classList.remove("d-none")
} else {
annotations.classList.add("d-none")
}
}
document.getElementById("showLastTouch")?.addEventListener('click', toggleLastTouch)
</script>
`
}120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
data.fileInfo.file,
data.fileInfo.repoName
)
)))
)
])
])
),
m('script', {type: "text/javascript"},
`
const toggleLastTouch = (event) => {
const isOn = event.target.checked
const annotations = document.getElementById("annotations")
if (isOn) {
annotations.classList.remove("d-none")
} else {
annotations.classList.add("d-none")
}
}
document.getElementById("showLastTouch")?.addEventListener('click', toggleLastTouch)
`
)
]
)
])
}23 24 25 26 27 28 29
)
),
m('ul', {class: "list-group"}, files.map((file) => {
return m('li', [
file.isDirectory ? '<span>📁</span>' : null,
m('a', {
href: `${data.reposPath}/${slugify(data.branchInfo.repoName)}/branches/${slugify(data.branchInfo.branchName)}/files/${
file.fullPath.split('/')23 24 25 26 27 28 29
)
),
m('ul', {class: "list-group"}, files.map((file) => {
return m('li', {class: 'list-group-item'}, [
file.isDirectory ? m.trust('<span>📁</span>') : null,
m('a', {
href: `${data.reposPath}/${slugify(data.branchInfo.repoName)}/branches/${slugify(data.branchInfo.branchName)}/files/${
file.fullPath.split('/')