Plugins
En esta página
Plugins
Un plugin de BxSites no es más que otro módulo de BoxLang - su propio
box.json + ModuleConfig.bx, instalado como hermano de bx-sites en el
mismo runtime (box install en el proyecto, de la misma forma que ya lo
están bx-markdown/bx-esapi). Sin API de plugins que importar, sin
registro separado - el propio sistema de módulos de BoxLang es el
sistema de plugins.
Sin embargo, instalar un módulo por sà solo nunca lo activa como plugin -
un proyecto lo habilita explÃcitamente por nombre de módulo de BoxLang,
mediante el array plugins de
bxsites.yaml:
plugins: [ myBxSitesPlugin ]
{ "plugins": ["myBxSitesPlugin"] }
Instalar un plugin publicado
Un plugin publicado en ForgeBox se instala sin nada más que el propio
binario bxSites - no hace falta box/CommandBox. Explora lo ya
publicado bajo la categorÃa
bxsites-plugins en
ForgeBox:
bxSites install:plugin --name=bx-sites-plugin-analytics [--version=1.2.0]
Esto descarga el zip del paquete desde ForgeBox y lo extrae en
boxlang_modules/bx-sites-plugin-analytics/ en la raÃz del proyecto - la
propia convención de módulos locales autocargados de BoxLang (cualquier
carpeta de módulo ahà se detecta de la misma forma en que npm detecta un
node_modules/ local al proyecto), de modo que queda activo en el
registro de módulos de BoxLang en ejecución sin necesidad de
BOXLANG_HOME ni de ningún paso de instalación global. install:plugin
lo carga en el runtime de inmediato e imprime de vuelta el nombre real de
mapeo del módulo registrado (que, según la nota de abajo, no siempre
coincide con el slug de ForgeBox) - añade ese nombre al array plugins
de bxsites.yaml para activarlo, igual que con cualquier otro módulo
instalado. Consulta
install:plugin en la referencia de
la CLI.
Escribir un plugin
Un módulo de plugin necesita exactamente una cosa más allá del habitual
box.json/ModuleConfig.bx que ya tiene cualquier módulo de BoxLang:
una clase models/BxSitesPlugin.bx. Cada método en ella es opcional -
implementa solo los hooks que necesites, BxSites verifica cada uno antes
de llamarlo:
// models/BxSitesPlugin.bx
class {
struct function onConfig( required struct config ) {
// Mutate/return the site config, right after bxsites.yaml is loaded.
return arguments.config
}
string function onPageMarkdown( required string markdown, required struct page, required struct config ) {
// Mutate a page's raw markdown before conversion - the same
// pre-processing seam BxSites' own content tabs/math/code
// annotations use internally (TabsProcessor.bx et al.).
return arguments.markdown
}
string function onPageHtml( required string html, required struct page, required struct config ) {
// Mutate a page's rendered HTML after conversion.
return arguments.html
}
array function onNav( required array nav, required struct config ) {
// Mutate the nav tree (NavBuilder.build()'s own shape: an array of
// { title, url, order, children } nodes).
return arguments.nav
}
void function onBuildComplete( required string siteDir, required struct config ) {
// Fires once, after everything is written to siteDir - no return value.
}
}
Los hooks se ejecutan en el orden propio del array plugins de
bxsites.yaml, y (excepto onBuildComplete) el valor de retorno de cada
uno reemplaza el valor que ve el siguiente hook (o el propio BxSites) -
un plugin solo necesita devolver lo que recibió si no tiene nada que
cambiar.
onPageMarkdown/onPageHtml se ejecutan una vez por página, para cada
árbol de documentos que construye BxSites (el árbol docs/ principal y
cada árbol docs/versions/<name>/). onConfig/onNav/onBuildComplete
también se aplican mediante el verbo independiente search-index donde
sea relevante (onConfig, ya que puede cambiar markdown/otras
configuraciones de las que depende la construcción del Ãndice).
Cuándo se dispara cada hook
sequenceDiagram
participant Build as build verb
participant Plugin as your plugin
Build->>Plugin: onConfig(config)
Build->>Build: build the nav tree
Build->>Plugin: onNav(nav, config)
loop every page
Build->>Plugin: onPageMarkdown(markdown, page, config)
Build->>Build: Markdown() + built-in extensions
Build->>Plugin: onPageHtml(html, page, config)
end
Build->>Build: write site/
Build->>Plugin: onBuildComplete(siteDir, config)
Un ejemplo mÃnimo
examples/hello-plugin/ en este repositorio es un módulo de plugin
completo y funcional - instalable con box install tal cual - que añade
un comentario <!-- rendered by hello-plugin --> a cada página y agrega
una lÃnea de resumen de construcción a site/hello-plugin.txt en cuanto
finaliza la construcción. Úsalo como esqueleto de partida, o léelo como
un ejemplo trabajado de la estructura de carpetas:
hello-plugin/
├── box.json # boxlang.moduleName is what bxsites.yaml's [plugins] references
├── ModuleConfig.bx # a normal, otherwise-empty BoxLang module descriptor
└── models/
└── BxSitesPlugin.bx # onPageHtml() + onBuildComplete()
Errores
BxSites.PluginNotFound- un nombre en el arraypluginsdebxsites.yamlno es un módulo de BoxLang instalado/activado.BxSites.InvalidPlugin- el módulo existe, pero no tiene una clasemodels/BxSitesPlugin.bx.