自定义标签¶
你可以遵循 LeafTag
协议来创建自定义的 Leaf 标签。
为了演示这一点,让我们看看创建一个 #now
标签来打印当前时间戳。标签还支持一个可选参数来指定日期格式。
建议
如果你的自定义标签用来渲染 HTML,你应该使你的自定义标记符合 UnsafeUnescapedLeafTag
,这样 HTML 就不会被转义。别忘了检查或清除用户的任何输入。
LeafTag
¶
首先创建一个名为 NowTag
的类并遵循 LeafTag
协议。
struct NowTag: LeafTag {
func render(_ ctx: LeafContext) throws -> LeafData {
...
}
}
现在我们来实现 render(_:)
方法。传递给该方法的 LeafContext
参数包含了我们需要的所有内容。
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)
}
}
配置标签¶
现在我们已经实现了 NowTag
,我们只需要告诉 Leaf 就可以了。你可以像这样添加任何标签 - 即使它们来自一个单独的包。你通常在configure.swift
中做如下配置:
app.leaf.tags["now"] = NowTag()
就是这样!现在可以在 Leaf 中使用我们的自定义标签了。
The time is #now()
上下文属性¶
LeafContext
包含两个重要的属性。parameters
和 data
有我们需要的一切。
parameters
: 包含标签参数的数组。data
:一个字典,包含传递给render(_:_:)
方法作为上下文视图的数据。
Hello 标签示例¶
要了解如何使用它,让我们使用这两个属性实现一个简单的 hello 标签。
使用 Parameters¶
我们可以访问包含名称的第一个参数。
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")
使用 Data¶
我们可以通过使用 data 属性中的 ”name“ 键来访问 name 值。
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()
控制器:
return try await req.view.render("home", ["name": "John"])