Tucker McKnight <tmcknight@instructure.com> | Sun Mar 29 2026
[WIP] starting work on a tags page Currently it's mostly a copy-paste of the branches page, with parts removed that tags don't have. Still need to do: - Changes all "branches" links to have either "branch" or "tag" in the URL, since the site is now being generated for all branches and all tags.
17 18 19 20 21 22
return branch.repoName === data.flatRel.repoName ?
m('li', [
m('a', {
href: `${data.reposPath}/${slugify(branch.repoName)}/branches/${slugify(branch.relName)}/branches`
}, branch.relName),
branch.relName === data.flatRel.relName
? m('div', {class: "badge rounded-pill bg-secondary mx-1"}, 'current') : null,17 18 19 20 21 22
return branch.repoName === data.flatRel.repoName ?
m('li', [
m('a', {
href: `${data.reposPath}/${slugify(branch.repoName)}/branch/${slugify(branch.relName)}/branches`
}, branch.relName),
branch.relName === data.flatRel.relName
? m('div', {class: "badge rounded-pill bg-secondary mx-1"}, 'current') : null,55 56 57 58 59 60
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"}, [55 56 57 58 59 60
return m('div', {class: 'hunk'}, [
m('span', {class: "font-monospace fw-bold"},
m('a', {
href: `${data.reposPath}/${slugify(data.patchInfo.repoName)}/branch/${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"}, [21 22 23 24 25 26 27 28 29 30 31 32 33 34
href: nav.repoBranchHome(branch.name) + '/' + data.nav.path,
date: repo.commits.get(branch.sha).date.toISOString(),
}
}).concat(repo.tags.map((tag) => {
return {
name: tag.name,
href: "tbd",
date: repo.commits.get(tag.sha).date.toISOString(),
}
}))
console.log(branchesWithHrefs)
return {
rootPath: nav.rootPath(),21 22 23 24 25 26 27 28 29 30 31 32
href: nav.repoBranchHome(branch.name) + '/' + data.nav.path,
date: repo.commits.get(branch.sha).date.toISOString(),
}
}).concat(repo.tags.map((tag) => {
return {
name: tag.name,
href: nav.repoTagHome(tag.name) + '/' + data.nav.path,
date: repo.commits.get(tag.sha).date.toISOString(),
}
}))
return {
rootPath: nav.rootPath(),117 118 119 120 121
),
m('li', {class: "nav-item"},
m('a', {class: `nav-link ${data.navTab === 'branches' ? 'active' : ''}`, href: nav.repoCurrentBranchBranches()}, 'Branches')
)
])
)117 118 119 120 121 122 123 124
),
m('li', {class: "nav-item"},
m('a', {class: `nav-link ${data.navTab === 'branches' ? 'active' : ''}`, href: nav.repoCurrentBranchBranches()}, 'Branches')
),
m('li', {class: "nav-item"},
m('a', {class: `nav-link ${data.navTab === 'tags' ? 'active' : ''}`, href: nav.repoCurrentBranchTags()}, 'Tags')
)
])
)30 31 32 33 34 35
m('div', {class: "col"},
m('h3', [
m('span', {class: "bezel-gray p-1 my-1 d-inline-block"},
m('a', {href: `${data.reposPath}/${fileInfo.repoName}/branches/${fileInfo.branchName}/files`}, './')
),
fileInfo.file.split('/').map((dir, index, arr) => {
if (index === arr.length - 1) {30 31 32 33 34 35
m('div', {class: "col"},
m('h3', [
m('span', {class: "bezel-gray p-1 my-1 d-inline-block"},
m('a', {href: `${data.reposPath}/${fileInfo.repoName}/branch/${fileInfo.branchName}/files`}, './')
),
fileInfo.file.split('/').map((dir, index, arr) => {
if (index === arr.length - 1) {39 40 41 42 43 44
else {
return m('span', {class: "bezel-gray p-1 my-1 d-inline-block"}, [
m('a', {
href: `${data.reposPath}/${fileInfo.repoName}/branches/${fileInfo.branchName}/files/${arr.slice(0, index + 1).map((part) => slugify(part)).join('/')}.html`}, `${dir}/`)
])
}
})39 40 41 42 43 44
else {
return m('span', {class: "bezel-gray p-1 my-1 d-inline-block"}, [
m('a', {
href: `${data.reposPath}/${fileInfo.repoName}/branch/${fileInfo.branchName}/files/${arr.slice(0, index + 1).map((part) => slugify(part)).join('/')}.html`}, `${dir}/`)
])
}
})54 55 56 57 58 59
return m('li', {class: 'list-group-item'}, [
dir.isDirectory ? m('span', m.trust('📁 ')) : null,
m('a', {
href: `${data.reposPath}/${slugify(fileInfo.repoName)}/branches/${slugify(fileInfo.branchName)}/files/${dir.fullPath.split('/').map((pathPart) => {
return pathPart.split('.').map((subPart) => {
return slugify(subPart)
}).join('.')54 55 56 57 58 59
return m('li', {class: 'list-group-item'}, [
dir.isDirectory ? m('span', m.trust('📁 ')) : null,
m('a', {
href: `${data.reposPath}/${slugify(fileInfo.repoName)}/branch/${slugify(fileInfo.branchName)}/files/${dir.fullPath.split('/').map((pathPart) => {
return pathPart.split('.').map((subPart) => {
return slugify(subPart)
}).join('.')70 71 72 73 74 75
m('div', {class: "row my-3"},
m('div', {class: "col"},
m('span', m('a', {
href: `${data.reposPath}/${slugify(fileInfo.repoName)}/branches/${slugify(fileInfo.branchName)}/raw/${fileInfo.file.split('.').map(filePart => slugify(filePart)).join('.')}`}, 'View raw file'))
)
),
(fileInfo.file.endsWith(".md") ?70 71 72 73 74 75
m('div', {class: "row my-3"},
m('div', {class: "col"},
m('span', m('a', {
href: `${data.reposPath}/${slugify(fileInfo.repoName)}/branch/${slugify(fileInfo.branchName)}/raw/${fileInfo.file.split('.').map(filePart => slugify(filePart)).join('.')}`}, 'View raw file'))
)
),
(fileInfo.file.endsWith(".md") ?125 126 127 128 129 130
m('code', {style: "white-space: pre;"}, [
m('pre', {class: "language-text"}, m.trust(
currentRel.fileList.get(fileInfo.file).fileInfo.blameLines.map((annotation) => {
return `<a href="${data.reposPath}/${slugify(fileInfo.repoName)}/branches/${slugify(fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
}).join('\n')))
])
),125 126 127 128 129 130
m('code', {style: "white-space: pre;"}, [
m('pre', {class: "language-text"}, m.trust(
currentRel.fileList.get(fileInfo.file).fileInfo.blameLines.map((annotation) => {
return `<a href="${data.reposPath}/${slugify(fileInfo.repoName)}/branch/${slugify(fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
}).join('\n')))
])
),26 27 28 29 30 31
return m('li', {class: 'list-group-item'}, [
file.isDirectory ? m.trust('<span>📁 </span>') : null,
m('a', {
href: `${data.reposPath}/${slugify(data.flatRel.repoName)}/branches/${slugify(data.flatRel.relName)}/files/${
file.fullPath.split('/')
.map((pathPart) => {
return pathPart.split('.').map((subPart) => {26 27 28 29 30 31
return m('li', {class: 'list-group-item'}, [
file.isDirectory ? m.trust('<span>📁 </span>') : null,
m('a', {
href: `${data.reposPath}/${slugify(data.flatRel.repoName)}/branch/${slugify(data.flatRel.relName)}/files/${
file.fullPath.split('/')
.map((pathPart) => {
return pathPart.split('.').map((subPart) => {6 7 8 9 10 11
// every page URL. E.g. all of them start with 'repos/my-repo-name'
// or 'repos/my-repo-name/branches.'
const repoBasePath = `${reposPath}/${slugify(repoName)}`
const rootBasePathBranches = `${repoBasePath}/branches`
const currentBranchPath = `${rootBasePathBranches}/${slugify(branchName)}`
const repoBranchCommitsBase = `${currentBranchPath}/commits/`6 7 8 9 10 11 12
// every page URL. E.g. all of them start with 'repos/my-repo-name'
// or 'repos/my-repo-name/branches.'
const repoBasePath = `${reposPath}/${slugify(repoName)}`
const rootBasePathBranches = `${repoBasePath}/branch`
const rootBasePathTags = `${repoBasePath}/tag`
const currentBranchPath = `${rootBasePathBranches}/${slugify(branchName)}`
const repoBranchCommitsBase = `${currentBranchPath}/commits/`29 30 31 32 33 34 35 36 37 38 39
repoBranchHome: (branchName: string) => {
return `${rootBasePathBranches}/${slugify(branchName)}`
},
repoCurrentBranchFiles: () => {
return `${currentBranchPath}/files`
},
repoBranchCommitsBase: () => repoBranchCommitsBase,
repoCurrentBranchCommits: () => `${repoBranchCommitsBase}page1`,
repoCurrentBranchBranches: () => `${currentBranchPath}/branches`,
repoCurrentBranchRssFeed: () => `${currentBranchPath}/commits.xml`,
homepageButtons: reposConfig.repos[repoName].defaultTemplateConfiguration?.homepageButtons || []
}29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
repoBranchHome: (branchName: string) => {
return `${rootBasePathBranches}/${slugify(branchName)}`
},
repoTagHome: (tagName: string) => {
return `${rootBasePathTags}/${slugify(tagName)}`
},
repoCurrentBranchFiles: () => {
return `${currentBranchPath}/files`
},
repoBranchCommitsBase: () => repoBranchCommitsBase,
repoCurrentBranchCommits: () => `${repoBranchCommitsBase}page1`,
repoCurrentBranchBranches: () => `${currentBranchPath}/branches`,
// TODO: change these "currentBranch"es to "currentRel"s
repoCurrentBranchTags: () => `${currentBranchPath}/tags`,
repoCurrentBranchRssFeed: () => `${currentBranchPath}/commits.xml`,
homepageButtons: reposConfig.repos[repoName].defaultTemplateConfiguration?.homepageButtons || []
}15 16 17 18 19 20 21 22 23 24 25 26 27
return (
m('div', {class: "m-2 card bezel-gray flex-grow-1", style: "flex-basis: 20rem;"},
m('div', {class: "card-header"},
m('a', {class: "card-title fs-5", href: `${data.reposPath}/${slugify(repo.name)}/branches/${repo.defaultBranch}`}, repo.name)
),
m('div', {class: "card-body"},
repo.description ? m('p', {class: "card-text"}, repo.description) : null
),
m('div', {class: "card-footer"}, [
m('a', {
href: `${data.reposPath}/${slugify(repo.name)}/branches/${repo.defaultBranch}`,
class: "ms-0 me-2 my-2 btn btn-primary text-white"
}, 'Go to site'),
m('button', {15 16 17 18 19 20 21 22 23 24 25 26 27
return (
m('div', {class: "m-2 card bezel-gray flex-grow-1", style: "flex-basis: 20rem;"},
m('div', {class: "card-header"},
m('a', {class: "card-title fs-5", href: `${data.reposPath}/${slugify(repo.name)}/branch/${repo.defaultBranch}`}, repo.name)
),
m('div', {class: "card-body"},
repo.description ? m('p', {class: "card-text"}, repo.description) : null
),
m('div', {class: "card-footer"}, [
m('a', {
href: `${data.reposPath}/${slugify(repo.name)}/branch/${repo.defaultBranch}`,
class: "ms-0 me-2 my-2 btn btn-primary text-white"
}, 'Go to site'),
m('button', {18 19 20 21 22
import commitsJsTemplate from './js_templates/commits.ts'
import indexJsTemplate from './js_templates/index.ts'
import branchesJsTemplate from './js_templates/branches.ts'
import rawJsTemplate from './js_templates/raw.ts'
import feedJsTemplate from './js_templates/feed.ts'
18 19 20 21 22 23
import commitsJsTemplate from './js_templates/commits.ts'
import indexJsTemplate from './js_templates/index.ts'
import branchesJsTemplate from './js_templates/branches.ts'
import tagsJsTemplate from './js_templates/tags.ts'
import rawJsTemplate from './js_templates/raw.ts'
import feedJsTemplate from './js_templates/feed.ts'