Variabili e Funzioni Magiche
In questa pagina
- Variabili riutilizzabili
- Funzioni magiche
- Richiamare una funzione magica da una sovrascrittura di tema
- Variabili di contesto
- Sintassi degli argomenti
- Ricette per i visualizzatori
- Valutazioni
- Chip di stato
- Barre di progresso
- Indicatori di tendenza
- Dentro una cella di tabella
- Mostrare la sintassi in modo letterale
- Ambito
- Nomi riservati
- Errori
Variabili e Funzioni Magiche
Due funzionalità piccole e correlate per tenere fuori dal tuo Markdown i
fatti ripetuti e la logica ripetuta: le variabili riutilizzabili,
definite una sola volta in bxsites.yaml e inserite in qualsiasi pagina
con {{ }}, e le funzioni magiche, piccoli helper BoxLang che scrivi
una sola volta in docs/functions.bxs e richiami allo stesso modo -
ovunque, senza import, senza plugin, senza alcun collegamento da
configurare.
Entrambe condividono un'unica sintassi:
{{ dotted.path }} # a reusable variable
{{ $name(arg1, arg2) }} # a magic function call
Variabili riutilizzabili
Aggiungi un blocco variables a bxsites.yaml - con qualsiasi forma tu
preferisca, piatta o annidata:
variables:
company: "Ortus Solutions"
product:
name: "BoxLang"
supportEmail: "support@example.com"
{
"variables": {
"company": "Ortus Solutions",
"product": {
"name": "BoxLang",
"supportEmail": "support@example.com"
}
}
}
Poi fai riferimento a uno qualsiasi dei suoi valori, per percorso puntato, da qualsiasi pagina Markdown:
# Welcome to {{ company }}
We build {{ product.name }} tools. Need help? Write us at
{{ product.supportEmail }}.
viene compilata in:
<h1>Welcome to Ortus Solutions</h1>
<p>We build BoxLang tools. Need help? Write us at support@example.com.</p>
Una variabile {{ }} viene risolta una sola volta, al momento del build,
rispetto a ciò che il blocco variables proprio di bxsites.yaml
contiene in quel preciso istante - rinomina un prodotto, aggiorna un
indirizzo di supporto o cambia un anno in un unico punto, e ogni pagina
che la usa recepisce la modifica al build successivo. Vedi
variables nel riferimento di
configurazione.
Funzioni magiche
Aggiungi un file docs/functions.bxs (o src/functions.bxs, se il tuo
progetto usa src/ - vedi Per iniziare) - un
semplice script BoxLang. Ogni funzione che nomini con un $ iniziale
diventa una funzione magica: richiamabile da {{ }} nel Markdown, e
richiamabile allo stato puro, direttamente, dalle sovrascritture .bxm
del proprio theme/ di un progetto.
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') }}
viene compilata in:
<p>THIS IS IMPORTANT!</p>
<p>Status: <span class="badge bg-success">Stable</span></p>
Una funzione magica può restituire qualsiasi cosa convertibile con
toString() - testo semplice, HTML, un numero - e viene inserita
direttamente nel Markdown della pagina prima che questo venga convertito,
quindi restituire vero HTML (come $badge() sopra) funziona esattamente
come ci si aspetterebbe.
Una funzione dichiarata senza un $ iniziale nello stesso
functions.bxs è solo un helper privato, pensato per essere richiamato
unicamente dalle tue altre funzioni con prefisso $ nello stesso file
(vengono tutte caricate nello stesso scope, quindi una può richiamare
l'altra allo stato puro) - {{ }} non può mai richiamarne una
direttamente (viene riconosciuto solo un bersaglio di chiamata
$name(...)), e non fa nemmeno parte della superficie pubblica
documentata che una sovrascrittura di tema dovrebbe richiamare, anche se
tecnicamente risulta raggiungibile anche lì:
private string function formatPrice( amount ) {
return "$" & numberFormat( arguments.amount, "9.99" )
}
function $price( amount ) {
return formatPrice( arguments.amount )
}
Richiamare una funzione magica da una sovrascrittura di tema
Poiché una funzione magica viene collegata direttamente nello scope del
template, il proprio theme/page.bxm (o layout.bxm) di un progetto può
richiamarla allo stato puro, senza alcun prefisso - esattamente come giÃ
legge variables.page/variables.siteConfig:
<p class="build-banner">#$shout( 'built with boxlang' )#</p>
Variabili di contesto
Il corpo di ogni funzione magica può anche leggere un insieme fisso di
"variabili di supporto" - allo stato puro, senza bisogno di alcun
argomento - a prescindere dal fatto che venga richiamata da {{ }} nel
Markdown oppure allo stato puro da una sovrascrittura di tema:
| Variabile | Cos'è |
|---|---|
siteConfig | La configurazione bxsites.yaml propria del sito (già impostata sui valori predefiniti/validata) |
page | La pagina corrente (vedi la nota sotto - non tutti i campi sono già popolati quando viene richiamata dal Markdown) |
nav | L'albero di navigazione proprio di questo albero |
basePath | Il percorso base relativo alla radice, che termina con / |
versions | Le voci del selettore di versione - [ { label, url } ] |
currentVersion | Quale voce di versions viene renderizzata in questo momento |
locales | Le voci del selettore di lingua - [ { code, label, url, dir, flag } ] |
currentLocale | Il codice di quale voce di locales viene renderizzato in questo momento |
currentLocaleDir | "ltr"/"rtl" per il locale corrente |
function $sitename() {
return siteConfig.name
}
function $pagetitle() {
return page.title
}
Site: {{ $sitename() }}
Page: {{ $pagetitle() }}
page non è ugualmente completa in entrambi i casi. Se richiamata dal
Markdown, page è lo struct proprio di questa specifica pagina così come
caricato da disco - title/description/tags/icon/summary/
ogImage/urlPath/relativePath/body/ecc. sono già presenti, ma i
campi noti solo dopo che ogni pagina dell'albero ha terminato la
conversione - toc, prevPage/nextPage, breadcrumbs,
editUrl/lastUpdated, iconHtml, markdownUrl, canonicalUrl - non
esistono ancora su di essa. Se richiamata allo stato puro da page.bxm,
page è invece lo struct completamente arricchito, con tutti questi
campi inclusi. Ogni altra variabile di supporto (siteConfig, nav,
basePath, versions, currentVersion, locales, currentLocale,
currentLocaleDir) è identica in entrambi i casi.
Sintassi degli argomenti
Gli argomenti di una chiamata a funzione magica sono semplici letterali o riferimenti a variabili separati da virgola - nessuna chiamata a funzione annidata né espressione in questa prima versione:
- Numeri:
{{ $discount(20) }} - Stringhe tra virgolette:
{{ $greet('World') }}oppure{{ $greet("World") }} - Booleani:
{{ $badge('Beta', true) }} - Un riferimento a variabile puntato senza
{{ }}:{{ $greet(product.name) }}
Ricette per i visualizzatori
Una funzione magica che restituisce HTML non si limita a un badge di
stato - è un modo generico per ottenere celle visive in stile GitBook
(una valutazione a stelle, un chip colorato, una barra di progresso)
senza il selettore di colonne di GitBook basato su database, di cui il
codice sorgente di bx-sites, basato su git e Markdown puro, non ha un
equivalente. Le quattro funzioni qui sotto sono lo stesso
docs/functions.bxs
di questo sito, renderizzate dal vivo proprio in questa pagina.
Valutazioni
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) }}` viene renderizzato come: ★★★★☆
Chip di stato
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') }}` viene renderizzato come: Stable - e `{{ $badge('Beta', 'info') }}`: Beta
Barre di progresso
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) }}` viene renderizzato come: 72%
Indicatori di tendenza
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) }}` viene renderizzato come: â–² +4.2% - `{{ $trend(-1.8) }}`: â–¼ -1.8%
Dentro una cella di tabella
{{ }} si risolve rispetto al Markdown grezzo prima ancora che le
tabelle vengano analizzate, quindi qualsiasi
elemento tra quelli sopra funziona anche dentro le celle di una tabella a
pipe, esattamente come in qualsiasi altro punto della pagina - la cosa più
vicina qui alle colonne Select/Rating di GitBook:
| Feature | Status | Rating |
| --- | --- | --- |
| Dark mode | {{ $badge('Stable', 'success') }} | {{ $stars(5) }} |
| Table sort | {{ $badge('Beta', 'info') }} | {{ $stars(4) }} |
Che viene renderizzato così:
| Feature | Status | Rating |
|---|---|---|
| Dark mode | Stable | ★★★★★ |
| Table sort | Beta | ★★★★☆ |
Mostrare la sintassi in modo letterale
Un {{ }} mostrato dentro un blocco di codice delimitato (tre o più
backtick, come ogni esempio in questa pagina) viene lasciato del tutto
intatto invece di essere risolto - la stessa convenzione che questo
modulo usa già per la matematica $...$ e per le schede di contenuto
=== "Tab". A differenza di queste due, un {{ }} mostrato in codice
inline (`{{ example }}`, con singolo o doppio backtick) è
protetto anch'esso - ogni punto elenco più sopra che mostra
`{{ $discount(20) }}` inline è un esempio reale e funzionante di
questo.
Un {{ }} il cui contenuto non assomiglia né a un percorso di variabile
né a una chiamata $name(...) - la sintassi {{ }} propria di un altro
motore di template, mostrata in un testo discorsivo, ad esempio - viene
lasciato intatto invece di essere trattato come un errore. Solo un token
che sembra una variabile o una chiamata a funzione magica, ma che non
si risolve, fa fallire il build (vedi Errori sotto) - questo è
deliberato, per intercettare un vero errore di battitura senza
interpretare erroneamente un testo {{ }} non correlato come sintassi
rotta.
Ambito
functions.bxsè a livello di progetto - un solo file, caricato una volta, con lo stesso insieme di funzioni magiche disponibile su ogni pagina, sia nell'albero principale sia in ogni albero di versione/locale. Non è necessario duplicarlo indocs/versions/<name>/odocs/i18n/<code>/.variablesè allo stesso modo un unico blocco dibxsites.yamla livello di progetto - non è di per sé traducibile per locale. Un progetto multilingue che desideri un testo di variabile diverso per ogni lingua può invece ricorrere a una funzione magica che smisti in base asiteConfig.i18n.defaultLocale.code(oppure, semplicemente, mantenere il valore neutro rispetto alla lingua - un nome di prodotto, un indirizzo di supporto).
Nomi riservati
Una sovrascrittura theme/page.bxm/layout.bxm che richiama una
funzione magica allo stato puro ($name(...)) funziona perché ogni
funzione caricata - con prefisso $ o helper privato indifferentemente -
viene collegata direttamente nello stesso scope di rendering di quel
template, proprio accanto ai variables.page/variables.siteConfig/ecc.
integrati che ogni tema già legge. Questo significa che una funzione di
functions.bxs che condivide un nome con uno di questi ne ha già uno:
evita page, nav, siteConfig, themeDir, basePath,
moduleAssetsDir, versions, currentVersion, locales,
currentLocale, currentLocaleDir, strings, requiredFiles e
stringsResolver come nome proprio di un helper privato (una funzione
magica con prefisso $ non può mai entrare in collisione con nessuno di
questi, dato che nessuno di essi inizia con $).
Errori
BxSites.UnknownVariable- un{{ dotted.path }}(o un argomento di$name(...)che assomiglia a un riferimento a variabile) non corrisponde a nulla nel bloccovariablesdibxsites.yaml.BxSites.UnknownFunction- una chiamata{{ $name(...) }}non corrisponde a nessuna funzione con prefisso$indocs/functions.bxs.BxSites.InvalidFunctions-docs/functions.bxsnon è riuscito a caricarsi (un errore di sintassi BoxLang nel file stesso).BxSites.InvalidConfig- la chiavevariablesdibxsites.yamlè presente, ma non è un oggetto.