Leaf提供的标签还算丰富,但是缺少了markdown的支持,于是根据需求我们来个markdown的自己写个,同时呢练练自定义tag,感觉真是一举两得……😀
说到自定义Tag就必须要注意一下啦
1 遵循TagRenderer
2将tag标签注册到系统server中
vapor中一切皆服务
按照这个思路先定义一个遵循TagRenderer的class
final class VaporMarkdown: TagRenderer {
func render(tag: TagContext) throws -> EventLoopFuture<TemplateData> {
if tag.parameters.count == 0 {
return tag.container.future(.string(""))
}else{
let value = tag.parameters.first?.string ?? ""
let markdown = try! skMarkdownToHTML(value)
return tag.container.future(.string(markdown))
}
}
}
注释:TagContext很简单,就是TempKit解析出的节点,我们根据需要读取节点
然后注册进系统服务中
services.register { (Container) -> (LeafTagConfig) in
var tagConfig = LeafTagConfig.default()
tagConfig.use( VaporMarkdown.init(), as: "markdown")
return tagConfig
}
当然了我们在单元测试中这么使用
let services: Services = Services.init()
/*
services.register { (Container) -> (LeafTagConfig) in
var tagConfig = LeafTagConfig.default()
tagConfig.use( VaporMarkdown.init(), as: "markdown")
return tagConfig
}
*/
let container = BasicContainer(config: .init(), environment: .testing, services: services, on: EmbeddedEventLoop())
let viewsDir = "/" + #file.split(separator: "/").dropLast(3).joined(separator: "/").finished(with: "/Views/")
var tagConfig = LeafTagConfig.default()
tagConfig.use( VaporMarkdown.init(), as: "markdown")
let config = LeafConfig(tags: tagConfig, viewsDir: viewsDir, shouldCache: false)
self.renderer = LeafRenderer(config: config, using: container)
这两个的实质都是将自定义的tag和对应的tag解析类注册到服务中
核心就是:tagConfig.use( VaporMarkdown.init(), as: "markdown")
拿单元测试作为一个example来展示使用
func testComplex(){
let readme = "/" + #file.split(separator: "/").dropLast(3).joined(separator: "/").finished(with: "/README.md")
let value = try! String.init(contentsOfFile: readme)
let markdown = "#markdown(msg)"
let data = TemplateData.dictionary(["msg":.string(value)])
let result = try! renderer.testRender(markdown, data)
print(result)
}
写到最后突然感觉 tag改名为 md 更合适☺️
网友评论