Tucker McKnight <tmcknight@instructure.com> | Sun Sep 28 2025
Skip things that can't be done if plugins are missing RSS feed creationg, syntax highlighting, and readme display rely on other 11ty plugins being installed in order for them to work. If those plugins are not installed, skip those parts of the site generation.
14 15 16 17 18 19 20 21
const ajv = new Ajv()
const exec = util.promisify(childProcess.exec)
// TODO: check if the render plugin is available and throw an error otherwise
// TODO: check if the highlight function is available
// TODO: throw an error if reposConfiguration is undefined
export default async function repoViewer(eleventyConfig, reposConfiguration: ReposConfiguration) {
const validator = ajv.compile(ConfigSchema)
const valid = validator(reposConfiguration)14 15 16 17 18
const ajv = new Ajv()
const exec = util.promisify(childProcess.exec)
export default async function repoViewer(eleventyConfig, reposConfiguration: ReposConfiguration) {
const validator = ajv.compile(ConfigSchema)
const valid = validator(reposConfiguration)108 109 110 111 112 113
})
eleventyConfig.addFilter("highlightCode", (code, language) => {
return eleventyConfig.javascript.functions.highlight(language, code)
})
eleventyConfig.addFilter("languageExtension", (filename, repoName) => {108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
})
eleventyConfig.addFilter("highlightCode", (code, language) => {
const highlighter = eleventyConfig?.javascript?.functions?.highlight
if (highlighter) {
return highlighter(language, code)
}
else {
return code
}
})
eleventyConfig.addAsyncFilter("renderContentIfAvailable", async (contentString, contentType) => {
const renderer = eleventyConfig?.javascript?.functions?.renderContent
if (renderer) {
return await renderer.bind({})(contentString, contentType)
}
else {
return `<pre>${contentString}</pre>`
}
})
eleventyConfig.addFilter("languageExtension", (filename, repoName) => {0 1 2 3 4
<div class="row">
<div class="col-md-8 col-sm-12 order-md-1 order-sm-2">
{{ branch.repoName | getReadMe(branch.branchName) | renderContent("md") | safe }}
</div>
<div class="col-md-4 col-sm-12 order-md-2 order-sm-1">
<div class="row">0 1 2 3 4
<div class="row">
<div class="col-md-8 col-sm-12 order-md-1 order-sm-2">
{{ branch.repoName | getReadMe(branch.branchName) | renderContentIfAvailable("md") | safe }}
</div>
<div class="col-md-4 col-sm-12 order-md-2 order-sm-1">
<div class="row">8 9 10 11 12 13 14 15
<div class="col-auto">
<h2 class="fs-6 my-0">Recent patches in {{branch.branchName}}</h2>
</div>
<div class="col-auto">
<a href="{{reposPath}}/{{ branch.repoName | slugify }}/branches/{{ branch.branchName | slugify }}/patches.xml" class="initialism">RSS<i class="bi bi-rss-fill ms-2" style="color: orange;"></i></a>
</div>
</div>
{% for patch in repos[branch.repoName].branches[branch.branchName].patches | batch(3) | first %}
<div class="card mt-2 mb-4">8 9 10 11 12 13 14 15 16 17
<div class="col-auto">
<h2 class="fs-6 my-0">Recent patches in {{branch.branchName}}</h2>
</div>
{% if rssAvailable %}
<div class="col-auto">
<a href="{{reposPath}}/{{ branch.repoName | slugify }}/branches/{{ branch.branchName | slugify }}/patches.xml" class="initialism">RSS<i class="bi bi-rss-fill ms-2" style="color: orange;"></i></a>
</div>
{% endif %}
</div>
{% for patch in repos[branch.repoName].branches[branch.branchName].patches | batch(3) | first %}
<div class="card mt-2 mb-4">