扩展用例
本页提供了一个简单示例目录,展示如何通过使用扩展功能来增强 Antora 的功能。每一部分都介绍了不同的使用案例,并提供了可作为起点的扩展代码。
您还可以参考 Antora 项目提供的官方扩展项目,学习更复杂的示例。
排除私人内容源
如果某些贡献者或 CI 作业没有权限访问 playbook 中的私有内容源,可以使用扩展来过滤它们,而不必修改 playbook 文件。
该扩展在 playbookBuilt
事件期间运行。它会检索 playbook,遍历内容源,并移除任何被检测为私有并因此需要身份验证的内容源。我们将依靠一个约定来向扩展传达哪个内容源是私有的。这个约定就是使用以 git@
开头的 SSH URL。Antora 会自动将 SSH URL 转换为 HTTP URL,因此使用这种语法只是为了提示用户和扩展,该 URL 是私有的,需要进行身份验证。
module.exports.register = function () {
this.on('playbookBuilt', function ({ playbook }) {
playbook.content.sources = playbook.content.sources
.filter(({ url }) => !url.startsWith('git@'))
this.updateVariables({ playbook })
})
}
该扩展之所以有效,是因为在该事件结束之前,游戏本都是可变的,Antora 会在事件结束时冻结游戏本。调用 this.updateVariables
替换生成器上下文中的 playbook
变量并不是必需的,但这里用来表达意图和证明扩展的未来性。
报告未列出的页面
创建新页面后,很容易忘记将其添加到导航中,以便读者访问。我们可以使用扩展来识别不在导航中的页面,并使用记录器报告它们。
该扩展在 navigationBuilt
事件期间运行。它会遍历每个组件版本,检索其内部导航条目的扁平化列表,然后检查是否有任何页面不在该列表中,并通过 URL 对页面进行比较。如果发现任何此类页面,就会创建相关报告,并将其添加到导航中。
module.exports.register = function ({ config }) {
const { addToNavigation, unlistedPagesHeading = 'Unlisted Pages' } = config
const logger = this.getLogger('unlisted-pagesAlian-extension')
this
.on('navigationBuilt', ({ contentCatalog }) => {
contentCatalog.getComponents().forEach(({ versions }) => {
versions.forEach(({ name: component, version, navigation: nav, url: defaultUrl }) => {
const navEntriesByUrl = getNavEntriesByUrl(nav)
const unlistedPages = contentCatalog
.findBy({ component, version, family: 'page' })
.filter((page) => page.out)
.reduce((collector, page) => {
if ((page.pub.url in navEntriesByUrl) || page.pub.url === defaultUrl) return collector
logger.warn({ file: page.src, source: page.src.origin }, 'detected unlisted page')
return collector.concat(page)
}, [])
if (unlistedPages.length && addToNavigation) {
nav.push({
content: unlistedPagesHeading,
items: unlistedPages.map((page) => {
return { content: page.asciidoc.navtitle, url: page.pub.url, urlType: 'internal' }
}),
root: true,
})
}
})
})
})
}
function getNavEntriesByUrl (items = [], accum = {}) {
items.forEach((item) => {
if (item.urlType === 'internal') accum[item.url.split('#')[0]] = item
getNavEntriesByUrl(item.items, accum)
})
return accum
}
您可以在 扩展教程 中阅读有关此扩展的更多信息以及如何配置它。
取消发布未列出的页面
与其报告未列出的页面,不如将这些页面从发布中删除。这也是使用导航来决定发布哪些页面的一种方法。
该扩展在 navigationBuilt
事件期间运行。它会遍历每个组件版本,检索其内部导航项的扁平化列表,然后检查是否有任何页面不在该列表中,并通过 URL 对页面进行比较。如果发现任何此类页面,就会取消发布。
module.exports.register = function ({ config }) {
this
.on('navigationBuilt', ({ contentCatalog }) => {
contentCatalog.getComponents().forEach(({ versions }) => {
versions.forEach(({ name: component, version, navigation: nav, url: defaultUrl }) => {
const navEntriesByUrl = getNavEntriesByUrl(nav)
const unlistedPages = contentCatalog
.findBy({ component, version, family: 'page' })
.filter((page) => page.out)
.reduce((collector, page) => {
if ((page.pub.url in navEntriesByUrl) || page.pub.url === defaultUrl) return collector
return collector.concat(page)
}, [])
if (unlistedPages.length) unlistedPages.forEach((page) => delete page.out)
})
})
})
}
function getNavEntriesByUrl (items = [], accum = {}) {
items.forEach((item) => {
if (item.urlType === 'internal') accum[item.url.split('#')[0]] = item
getNavEntriesByUrl(item.items, accum)
})
return accum
}
从页面中移除 out
属性后,页面将无法发布,但仍可使用 include 指令进行引用。或者,你也可以选择从内容目录中完全删除页面。