Custom Tags
You can extend Leaf to provide your own tags that add custom functionality. To demonstrate this, let’s look at a basic example by recreating #uppercase together. This tag will take one argument, which is the string to uppercase.
When working with custom tags, there are four important things to know:
- You should call
requireParameterCount()with the number of parameters you expect to receive. This will throw an error if your tag is used incorrectly. - If you do or do not require a body, you should use either
requireBody()orrequireNoBody(). Again, this will throw an error if your tag is used incorrectly. - You can read individual parameters using the
parametersarray. Each parameter will be of typeLeafData, which you can convert to concrete data types using properties such as.string,.dictionary, and so on. - You must return a
Future<LeafData?>containing what should be rendered. In the example below we wrap the resulting uppercase string in aLeafDatastring, then send that back wrapped in a future.
Here’s example code for a CustomUppercase Leaf tag:
import Asyncimport Leafpublic final class CustomUppercase: Leaf.LeafTag {public init() {}public func render(parsed: ParsedTag, context: LeafContext, renderer: LeafRenderer) throws -> Future<LeafData?> {// ensure we receive precisely one parametertry parsed.requireParameterCount(1)// pull out our lone parameter as a string then uppercase it, or use an empty stringlet string = parsed.parameters[0].string?.uppercased() ?? ""// send it back wrapped in a LeafDatareturn Future(.string(string))}}
We can now register this Tag in our configure.swift file with:
services.register { container -> LeafConfig in// take a copy of Leaf's default tagsvar tags = defaultTags// add our custom tagtags["customuppercase"] = CustomUppercase()// find the location of our Resources/Views directorylet directoryConfig = try container.make(DirectoryConfig.self, for: LeafRenderer.self)let viewsDirectory = directoryConfig.workDir + "Resources/Views"// put all that into a new Leaf configuration and return itreturn LeafConfig(tags: tags, viewsDir: viewsDirectory)}
Once that is complete, you can use #customuppercase(some_variable) to run your custom code.
Note: Use of non-alphanumeric characters in tag names is strongly discouraged and may be disallowed in future versions of Leaf.
