Variables y Funciones Mágicas
En esta página
- Variables reutilizables
- Funciones mágicas
- Llamar a una función mágica desde una sobrescritura de tema
- Variables de contexto
- Sintaxis de los argumentos
- Recetas de visualización
- Valoraciones
- Chips de estado
- Barras de progreso
- Indicadores de tendencia
- Dentro de una celda de tabla
- Mostrar la sintaxis de forma literal
- Ámbito
- Nombres reservados
- Errores
Variables y Funciones Mágicas
Dos funciones pequeñas y relacionadas para mantener fuera de tu Markdown
tanto los datos repetidos como la lógica repetida: variables
reutilizables, definidas una sola vez en bxsites.yaml e insertadas en
cualquier página con {{ }}, y funciones mágicas, pequeños ayudantes
de BoxLang que escribes una sola vez en docs/functions.bxs y llamas de
la misma forma - en todas partes, sin import, sin plugin, sin cableado
alguno.
Ambas comparten una única sintaxis:
{{ dotted.path }} # a reusable variable
{{ $name(arg1, arg2) }} # a magic function call
Variables reutilizables
Añade un bloque variables a bxsites.yaml - con la forma que prefieras,
plana o anidada:
variables:
company: "Ortus Solutions"
product:
name: "BoxLang"
supportEmail: "support@example.com"
{
"variables": {
"company": "Ortus Solutions",
"product": {
"name": "BoxLang",
"supportEmail": "support@example.com"
}
}
}
Luego referencia cualquiera de sus valores, por ruta con puntos, desde cualquier página de Markdown:
# Welcome to {{ company }}
We build {{ product.name }} tools. Need help? Write us at
{{ product.supportEmail }}.
se construye como:
<h1>Welcome to Ortus Solutions</h1>
<p>We build BoxLang tools. Need help? Write us at support@example.com.</p>
Una variable {{ }} se resuelve una sola vez, en el momento de la
construcción, contra lo que sea que tenga en ese instante el propio
bloque variables de bxsites.yaml - renombra un producto, actualiza una
dirección de soporte o cambia un año en un solo lugar, y cada página que
lo usa recoge el cambio en la siguiente construcción. Consulta
variables en la referencia de
configuración.
Funciones mágicas
Añade un archivo docs/functions.bxs (o src/functions.bxs, si tu
proyecto usa src/ - consulta Primeros Pasos) -
un script BoxLang plano. Cualquier función que nombres con un $ inicial
se convierte en una función mágica: invocable desde {{ }} en
Markdown, e invocable directamente, sin nada más, desde las propias
sobrescrituras .bxm de theme/ de un
proyecto.
function $shout( text ) {
return uCase( arguments.text ) & "!"
}
function $badge( label, kind = "info" ) {
return '<span class="badge bg-' & arguments.kind & '">' & arguments.label & '</span>'
}
{{ $shout('this is important') }}
Status: {{ $badge('Stable', 'success') }}
se construye como:
<p>THIS IS IMPORTANT!</p>
<p>Status: <span class="badge bg-success">Stable</span></p>
Una función mágica puede devolver cualquier cosa convertible con
toString() - texto plano, HTML, un número - y se empalma directamente
en el markdown de la página antes de que se convierta, así que devolver
HTML real (como $badge() arriba) funciona exactamente como cabría
esperar.
Una función declarada sin un $ inicial en ese mismo functions.bxs
es solo un ayudante privado, pensado para ser llamado únicamente desde
tus otras funciones con prefijo $ en el mismo archivo (todas se cargan
en el mismo ámbito, así que una puede llamar a otra sin prefijo) - {{ }}
nunca puede llamar a una directamente (solo un destino de llamada
$name(...) se reconoce jamás), y tampoco forma parte de la superficie
pública documentada que una sobrescritura de tema debería llamar, aunque
resulte técnicamente alcanzable también ahí:
private string function formatPrice( amount ) {
return "$" & numberFormat( arguments.amount, "9.99" )
}
function $price( amount ) {
return formatPrice( arguments.amount )
}
Llamar a una función mágica desde una sobrescritura de tema
Como una función mágica queda enlazada directamente en el ámbito de la
plantilla, el propio theme/page.bxm (o layout.bxm) de un proyecto
puede llamarla sin prefijo, exactamente de la misma forma en que ya lee
variables.page/variables.siteConfig:
<p class="build-banner">#$shout( 'built with boxlang' )#</p>
Variables de contexto
El propio cuerpo de cada función mágica también puede leer un conjunto
fijo de "variables de soporte" - sin prefijo, sin necesidad de ningún
argumento - sin importar si se invoca desde {{ }} en Markdown o sin
prefijo desde una sobrescritura de tema:
| Variable | Qué es |
|---|---|
siteConfig | La propia configuración bxsites.yaml del sitio (ya con valores por defecto/validada) |
page | La página actual (consulta la nota más abajo - no todos los campos están todavía completos cuando se llama desde Markdown) |
nav | El propio árbol de navegación de este árbol |
basePath | Ruta base relativa a la raíz, terminada en / |
versions | Entradas del selector de versiones - [ { label, url } ] |
currentVersion | Qué entrada de versions se está renderizando en este momento |
locales | Entradas del selector de idioma - [ { code, label, url, dir, flag } ] |
currentLocale | El código de qué entrada de locales se está renderizando en este momento |
currentLocaleDir | "ltr"/"rtl" para el idioma actual |
function $sitename() {
return siteConfig.name
}
function $pagetitle() {
return page.title
}
Site: {{ $sitename() }}
Page: {{ $pagetitle() }}
page no está igual de completa en ambos lugares. Llamada desde
Markdown, page es el propio struct de esta página en concreto tal como
se cargó desde disco - title/description/tags/icon/summary/
ogImage/urlPath/relativePath/body/etc. ya están ahí, pero los
campos que solo se conocen una vez que todas las páginas del árbol han
terminado de convertirse - toc, prevPage/nextPage, breadcrumbs,
editUrl/lastUpdated, iconHtml, markdownUrl, canonicalUrl - todavía
no existen en ella. Llamada sin prefijo desde page.bxm, page es el
struct totalmente enriquecido, con todos esos incluidos. Cualquier otra
variable de soporte (siteConfig, nav, basePath, versions,
currentVersion, locales, currentLocale, currentLocaleDir) es
idéntica en ambos lugares.
Sintaxis de los argumentos
Los argumentos de una llamada a función mágica son literales o referencias a variables simples, separados por comas - sin llamadas a función anidadas ni expresiones en esta primera versión:
- Números:
{{ $discount(20) }} - Cadenas entre comillas:
{{ $greet('World') }}o{{ $greet("World") }} - Booleanos:
{{ $badge('Beta', true) }} - Una referencia a variable con puntos, sin
{{ }}:{{ $greet(product.name) }}
Recetas de visualización
Una función mágica que devuelve HTML no se limita a una insignia de
estado - es una forma de propósito general de obtener celdas visuales al
estilo GitBook (una valoración con estrellas, un chip de color, una barra
de progreso) sin el propio selector de columnas respaldado por base de
datos de GitBook, del que el origen basado en git y en Markdown plano de
bx-sites no tiene equivalente alguno. Las cuatro de abajo son el propio
docs/functions.bxs
de este sitio, renderizándose en vivo justo en esta misma página.
Valoraciones
function $stars( required numeric rating, numeric max = 5 ) {
var filled = min( max( round( arguments.rating ), 0 ), arguments.max )
var stars = repeatString( "★", filled ) & repeatString( "☆", arguments.max - filled )
return '<span title="' & arguments.rating & ' out of ' & arguments.max & '" style="color:##f5a623;letter-spacing:2px">' & stars & '</span>'
}
`{{ $stars(4) }}` se renderiza como: ★★★★☆
Chips de estado
function $badge( required string label, string kind = "info" ) {
var palette = {
"info" : { "bg" : "##e0edff", "fg" : "##1d4ed8" },
"success" : { "bg" : "##dcfce7", "fg" : "##15803d" },
"danger" : { "bg" : "##fee2e2", "fg" : "##b91c1c" },
"warning" : { "bg" : "##fef9c3", "fg" : "##854d0e" }
}
var pick = palette.keyExists( arguments.kind ) ? palette[ arguments.kind ] : { "bg" : "##f1f5f9", "fg" : "##475569" }
return '<span style="display:inline-block;padding:0.1em 0.6em;border-radius:999px;font-size:0.85em;font-weight:600;background:'
& pick.bg & ";color:" & pick.fg & '">' & encodeForHTML( arguments.label ) & "</span>"
}
`{{ $badge('Stable', 'success') }}` se renderiza como: Stable - y `{{ $badge('Beta', 'info') }}`: Beta
Barras de progreso
function $progress( required numeric percent ) {
var pct = min( max( arguments.percent, 0 ), 100 )
return '<span style="display:inline-block;width:120px;height:8px;background:##e5e7eb;border-radius:999px;overflow:hidden;vertical-align:middle"><span style="display:block;height:100%;width:'
& pct & '%;background:##2563eb"></span></span> ' & pct & "%"
}
`{{ $progress(72) }}` se renderiza como: 72%
Indicadores de tendencia
function $trend( required numeric value ) {
var isUp = arguments.value >= 0
var arrow = isUp ? "▲" : "▼"
var color = isUp ? "##16a34a" : "##dc2626"
var sign = isUp ? "+" : ""
return '<span style="color:' & color & ';font-weight:600">' & arrow & " " & sign & numberFormat( arguments.value, "0.0" ) & "%</span>"
}
`{{ $trend(4.2) }}` se renderiza como: ▲ +4.2% - `{{ $trend(-1.8) }}`: ▼ -1.8%
Dentro de una celda de tabla
{{ }} se resuelve contra el Markdown en bruto antes incluso de que se
analicen las tablas, así que cualquiera de las
anteriores funciona dentro de las celdas de una tabla de pipes igual que
en cualquier otra parte de la página - lo más parecido que hay aquí a las
propias columnas de tabla Select/Rating de GitBook:
| Feature | Status | Rating |
| --- | --- | --- |
| Dark mode | {{ $badge('Stable', 'success') }} | {{ $stars(5) }} |
| Table sort | {{ $badge('Beta', 'info') }} | {{ $stars(4) }} |
Lo que se renderiza como:
| Feature | Status | Rating |
|---|---|---|
| Dark mode | Stable | ★★★★★ |
| Table sort | Beta | ★★★★☆ |
Mostrar la sintaxis de forma literal
Un {{ }} mostrado dentro de un bloque de código con fence (tres
comillas invertidas o más, como todos los ejemplos de esta página) se
deja completamente intacto en lugar de resolverse - la misma convención
que este módulo ya usa para las matemáticas $...$ y el contenido de
pestañas === "Tab". A diferencia de esos dos casos, un {{ }}
mostrado en código en línea (`{{ example }}`, con comillas
invertidas simples o dobles) también está protegido - cada punto de la
lista anterior que muestra `{{ $discount(20) }}` en línea es un
ejemplo real y funcional de ello.
Un {{ }} cuyo contenido no se parezca ni a una ruta de variable ni a
una llamada $name(...) - la propia sintaxis {{ }} de otro motor de
plantillas mostrada en el texto, por ejemplo - se deja intacto en lugar
de tratarse como un error. Solo un token que parezca una variable o una
llamada a función mágica, pero que no se resuelva, hace fallar la
construcción (consulta Errores más abajo) - eso es
deliberado, para detectar un error tipográfico real sin interpretar
erróneamente texto {{ }} no relacionado como sintaxis rota.
Ámbito
functions.bxses de todo el proyecto - un solo archivo, cargado una vez, con el mismo conjunto de funciones mágicas disponible en cada página, tanto en el árbol principal como en cada árbol de versión/idioma. No necesitas duplicarlo endocs/versions/<name>/ni endocs/i18n/<code>/.variableses igualmente un único bloque debxsites.yamlde todo el proyecto - no es traducible por idioma en sí mismo. Un proyecto multilingüe que quiera texto de variable distinto por idioma puede en su lugar recurrir a una función mágica que decida segúnsiteConfig.i18n.defaultLocale.code(o simplemente mantener el valor neutral respecto al idioma - un nombre de producto, un correo de soporte).
Nombres reservados
Una sobrescritura theme/page.bxm/layout.bxm que llama a una función
mágica sin prefijo ($name(...)) funciona porque toda función cargada -
con prefijo $ o ayudante privado por igual - se enlaza directamente en
ese mismo ámbito de renderizado de la plantilla, justo junto a los
variables.page/variables.siteConfig/etc. incorporados que ya lee
cualquier tema. Eso significa que una función de functions.bxs que
comparta nombre con uno de esos ya tiene uno propio: evita page, nav,
siteConfig, themeDir, basePath, moduleAssetsDir, versions,
currentVersion, locales, currentLocale, currentLocaleDir,
strings, requiredFiles y stringsResolver como nombre propio para un
ayudante privado (una función mágica con prefijo $ nunca puede chocar
con ninguno de estos, ya que ninguno de ellos empieza con $).
Errores
BxSites.UnknownVariable- un{{ dotted.path }}(o un argumento de$name(...)que parece una referencia a variable) no coincide con nada del bloquevariablesdebxsites.yaml.BxSites.UnknownFunction- una llamada{{ $name(...) }}no coincide con ninguna función con prefijo$endocs/functions.bxs.BxSites.InvalidFunctions-docs/functions.bxsno pudo cargarse (un error de sintaxis de BoxLang en el propio archivo).BxSites.InvalidConfig- la clavevariablesdebxsites.yamlestá presente, pero no es un objeto.