Tucker McKnight <tucker@pangolin.lan> | Sun Dec 21 2025
Add bezel boxes on files nav, dropdown menu height limit, others Limit the commit message length on the readme page Make the commit sha a link to that commit Make the nav get (optionally) passed to the page from htmlPage, so that the page itself can use the NavHelper class if it needs to (like when linking to a commit).
93 94 95 96 97 98
let branches = window.branchesWithHrefs.filter((branch) => {
return branch.name.includes(searchTerm)
})
dropdownBranchesResults.innerHTML = branchesListItems(branches, window.defaultBranch)
})
const bootstrap = window.bootstrap93 94 95 96 97 98
let branches = window.branchesWithHrefs.filter((branch) => {
return branch.name.includes(searchTerm)
})
dropdownBranchesResults.innerHTML = branchesListItems(branches, window.defaultBranch, window.currentBranch)
})
const bootstrap = window.bootstrap1 2 3 4 5 6 7 8 9
import { type Repository } from '../../src/dataTypes.ts'
import { NavHelper } from '../helpers/nav.ts'
export const branchesListItems = (branches: Array<{name: string, href: string, date: string}>, defaultBranch: string): string => {
return branches.map((branch) => {
const badge = defaultBranch === branch.name ? '<div class="badge rounded-pill bg-primary ms-2">default</div>' : ''
return `<a href='${branch.href}' class='dropdown-item my-1'><span class="branch-dropdown-branch-name">${branch.name}</span>${badge}<span class="text-body d-block ms-2">updated ${branch.date}</span></a>`
}).join('')
}
1 2 3 4 5 6 7 8 9 10 11
import { type Repository } from '../../src/dataTypes.ts'
import { NavHelper } from '../helpers/nav.ts'
export const branchesListItems = (branches: Array<{name: string, href: string, date: string}>, defaultBranch: string, currentBranch: string): string => {
return branches.map((branch) => {
const currentBadge = currentBranch === branch.name ? '<div class="badge rounded-pill bg-primary mx-1">current</div>' : ''
const defaultBadge = defaultBranch === branch.name ? '<div class="badge rounded-pill bg-info text-body mx-1">default</div>' : ''
return `<a href='${branch.href}' class='dropdown-item my-1'><span class="branch-dropdown-branch-name me-1">${branch.name}</span>${currentBadge}${defaultBadge}<span class="text-body d-block ms-2">updated ${branch.date}</span></a>`
}).join('')
}
40 41 42 43 44
<script>
window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
window.defaultBranch = "${repo.defaultBranch}";
window.cloneUrl = "${repo.cloneUrl}";
</script>
<script src="${nav.rootPath()}frontend/top.js"></script>40 41 42 43 44 45
<script>
window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
window.defaultBranch = "${repo.defaultBranch}";
window.currentBranch = "${branch.name}";
window.cloneUrl = "${repo.cloneUrl}";
</script>
<script src="${nav.rootPath()}frontend/top.js"></script>89 90 91 92 93 94
</form>
<div class="dropdown-divider"></div>
<div id="dropdown-branches-results" class="dropdown-branches">
${branchesListItems(branchesWithHrefs, repo.defaultBranch)}
</div>
</div>
</div>89 90 91 92 93 94
</form>
<div class="dropdown-divider"></div>
<div id="dropdown-branches-results" class="dropdown-branches">
${branchesListItems(branchesWithHrefs, repo.defaultBranch, branch.name)}
</div>
</div>
</div>103 104 105 106 107 108
<nav class="navbar navbar-expand">
<ul class="main-nav navbar-nav flex-wrap">
<li class="nav-item">
<a class="nav-link ${data.navTab === 'home' ? 'active' : ''}" aria-current="page" href="${nav.repoCurrentBranchHome()}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link ${data.navTab === 'files' ? 'active' : ''}" href="${nav.repoCurrentBranchFiles()}">Files</a>103 104 105 106 107 108
<nav class="navbar navbar-expand">
<ul class="main-nav navbar-nav flex-wrap">
<li class="nav-item">
<a class="nav-link ${data.navTab === 'home' ? 'active' : ''}" aria-current="page" href="${nav.repoCurrentBranchHome()}">ReadMe</a>
</li>
<li class="nav-item">
<a class="nav-link ${data.navTab === 'files' ? 'active' : ''}" href="${nav.repoCurrentBranchFiles()}">Files</a>124 125 126 127 128 129
<div class="row">
<div class="col-12">
${await pageContent(eleventyConfig, data)}
</div>
</div>
124 125 126 127 128 129
<div class="row">
<div class="col-12">
${await pageContent(eleventyConfig, data, nav)}
</div>
</div>
0 1 2 3
export default async (eleventyConfig: any, data: any) => {
const getFileName = eleventyConfig.getFilter("getFileName")
const isDirectory = eleventyConfig.getFilter("isDirectory")
const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")
const getDirectoryContents = eleventyConfig.getFilter("getDirectoryContents")0 1 2
export default async (eleventyConfig: any, data: any) => {
const isDirectory = eleventyConfig.getFilter("isDirectory")
const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")
const getDirectoryContents = eleventyConfig.getFilter("getDirectoryContents")11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
const languageExtension = eleventyConfig.getFilter("languageExtension")
return `
<h3>./${data.fileInfo.file}</h3>
<p>Files snapshot from <span class="font-monospace">${data.fileInfo.branchName}</span></p>
${isDirectory(data.fileInfo.file, data.fileInfo.repoName, data.fileInfo.branchName) ?
`<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 ?
`<i class="bi bi-folder-fill"></i>`
: `<i class="bi bi-file-earmark"></i>`}
<a href="${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/files/${slugify(dir.fullPath)}.html">${getRelativePath(data.fileInfo.file, dir.name)}</a>
</li>`
}).join('')}
</ul>`
:
`<div class="row py-2">
<div class="col-auto">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
const languageExtension = eleventyConfig.getFilter("languageExtension")
return `
<div class="row my-3">
<div class="col">
<h3>
<span class="bezel-gray px-1"><a href="#">🏠 ./</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="#">${dir}</a></span>`
}
}).join('')
}
</h3>
</div>
</div>
<div class="row">
<div class="col">
<p>Files snapshot from <span class="font-monospace">${data.fileInfo.branchName}</span></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/${slugify(dir.fullPath)}.html">${getRelativePath(data.fileInfo.file, dir.name)}</a>
</li>`
}).join('')}
</ul>
</div>
</div>`
:
`<div class="row py-2">
<div class="col-auto">7 8 9 10 11 12 13
const files: SortedFileList = topLevelFilesOnly(branch.fileList, '')
return `
<h3>./</h3>
<p>Files snapshot from <span class="font-monospace">${data.branchInfo.branchName}</span></p>
<ul class="list-group">
${files.map((file) => {
return `7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
const files: SortedFileList = topLevelFilesOnly(branch.fileList, '')
return `
<div class="row my-3">
<div class="col">
<h3>
<span>🏠 ./</span>
</h3>
</div>
</div>
<div class="row">
<div class="col">
<p>Files snapshot from <span class="font-monospace">${data.branchInfo.branchName}</span></p>
</div>
</div>
<ul class="list-group">
${files.map((file) => {
return `8 9 10 11 12 13 14
const repoBasePath = `${reposPath}/${slugify(repoName)}`
const rootBasePathBranches = `${repoBasePath}/branches`
const currentBranchPath = `${rootBasePathBranches}/${slugify(branchName)}`
return {
rootPath: () => {8 9 10 11 12 13 14
const repoBasePath = `${reposPath}/${slugify(repoName)}`
const rootBasePathBranches = `${repoBasePath}/branches`
const currentBranchPath = `${rootBasePathBranches}/${slugify(branchName)}`
const repoBranchCommitsBase = `${currentBranchPath}/commits/`
return {
rootPath: () => {32 33 34 35 36 37
repoCurrentBranchFiles: () => {
return `${currentBranchPath}/files`
},
repoCurrentBranchCommits: () => `${currentBranchPath}/commits/page1`,
repoCurrentBranchBranches: () => `${currentBranchPath}/branches`,
}
}32 33 34 35 36 37 38
repoCurrentBranchFiles: () => {
return `${currentBranchPath}/files`
},
repoBranchCommitsBase: () => repoBranchCommitsBase,
repoCurrentBranchCommits: () => `${repoBranchCommitsBase}page1`,
repoCurrentBranchBranches: () => `${currentBranchPath}/branches`,
}
}0 1 2 3 4 5 6 7 8
import { type Repository } from '../src/dataTypes.ts'
export default async (eleventyConfig: any, data: any) => {
const repo: Repository = data.currentRepo
const branch: Repository['branches'][0] = data.currentBranch
const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
const getReadMe = eleventyConfig.getFilter("getReadMe")
return `
<div class="row">
<div class="col">0 1 2 3 4 5 6 7 8 9 10 11
import { type Repository } from '../src/dataTypes.ts'
import { NavHelper } from './helpers/nav.ts'
export default async (eleventyConfig: any, data: any, nav: ReturnType<typeof NavHelper>) => {
const repo: Repository = data.currentRepo
const branch: Repository['branches'][0] = data.currentBranch
const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
const getReadMe = eleventyConfig.getFilter("getReadMe")
const latestCommit = repo.commits.get(branch.head)
return `
<div class="row">
<div class="col">57 58 59 60 61 62 63
</noscript>
<div class="row mt-2">
<div class="col">
<p class="font-monospace text-white">
Latest commit: ${repo.commits.get(branch.head).hash.substr(0, 6)} ${repo.commits.get(branch.head).date.toDateString()} - ${repo.commits.get(branch.head).message}
</p>
</div>
</div>57 58 59 60 61 62 63
</noscript>
<div class="row mt-2">
<div class="col">
<p class="font-monospace text-white text-truncate">
Latest commit: ${latestCommit.date.toDateString()} <a class="fw-bold link-info" href="${nav.repoBranchCommitsBase()}${latestCommit.hash}">${latestCommit.hash.substr(0, 6)}</a> ${latestCommit.message.split('\n')[0]}
</p>
</div>
</div>155 156 157 158 159
.branch-selector .dropdown-menu {
min-width: 220px;
}
.badge {155 156 157 158 159 160 161
.branch-selector .dropdown-menu {
min-width: 220px;
max-height: 80vh;
overflow-y: scroll;
}
.badge {