Tag Personalizzati¶
Puoi creare tag Leaf personalizzati usando il protocollo LeafTag
.
Per mostrare come funziona, diamo un'occhiata alla creazione di un tag personalizzato #now
che stampa l'attuale marca temporale. Il tag supporterà anche un singolo parametro opzionale per specificare il formato della data.
Tip
Se il tuo tag personalizzato renderizza HTML dovresti conformare il tuo tag personalizzato a UnsafeUnescapedLeafTag
così che l'HTML non sia "escaped". Ricorda di controllare o ripulire ogni input dell'utente.
LeafTag
¶
Prima creiamo una classe chiamata NowTag
e conformiamola a LeafTag
.
struct NowTag: LeafTag {
func render(_ ctx: LeafContext) throws -> LeafData {
...
}
}
Adesso implementiamo il metodo render(_:)
. Il contesto LeafContext
passato a questo metodo ha tutto quello che ci dovrebbe servire.
enum NowTagError: Error {
case invalidFormatParameter
case tooManyParameters
}
struct NowTag: LeafTag {
func render(_ ctx: LeafContext) throws -> LeafData {
let formatter = DateFormatter()
switch ctx.parameters.count {
case 0: formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
case 1:
guard let string = ctx.parameters[0].string else {
throw NowTagError.invalidFormatParameter
}
formatter.dateFormat = string
default:
throw NowTagError.tooManyParameters
}
let dateAsString = formatter.string(from: Date())
return LeafData.string(dateAsString)
}
}
Configura il Tag¶
Adesso che abbiamo implementato NowTag
, dobbiamo solo dirlo a Leaf. Puoi aggiungere qualsiasi tag così - anche se vengono da un pacchetto separato. Di solito si fa in configure.swift
:
app.leaf.tags["now"] = NowTag()
Fatto! Ora possiamo usare la nostra tag personalizzata in Leaf.
The time is #now()
Proprietà del Contesto¶
Il LeafContext
contiene due proprietà importanti: parameters
e data
, che hanno tutto quello che ci dovrebbe servire.
parameters
: Un array che contiene i parametri del tag;data
: Un dizionario che contiene i dati della view passata arender(_:_:)
come contesto.
Tag Hello di Esempio¶
Per vedere come usarlo, implementiamo un semplice tag di saluto usando entrambe le proprietà.
Usando i Parametri¶
Possiamo accedere al primo parametro che dovrebbe contenere il nome.
enum HelloTagError: Error {
case missingNameParameter
}
struct HelloTag: UnsafeUnescapedLeafTag {
func render(_ ctx: LeafContext) throws -> LeafData {
guard let name = ctx.parameters[0].string else {
throw HelloTagError.missingNameParameter
}
return LeafData.string("<p>Hello \(name)</p>")
}
}
#hello("John")
Usando i Dati¶
Possiamo accedere al valore del nome usando la chiave "name" dentro la proprietà dei dati.
enum HelloTagError: Error {
case nameNotFound
}
struct HelloTag: UnsafeUnescapedLeafTag {
func render(_ ctx: LeafContext) throws -> LeafData {
guard let name = ctx.data["name"]?.string else {
throw HelloTagError.nameNotFound
}
return LeafData.string("<p>Hello \(name)</p>")
}
}
#hello()
Controller:
return try await req.view.render("home", ["name": "John"])