I’ve been recently interested in server-side Swift and stumbled upon the Vapor framework.
Vapor is a cool web-application development framework written in Swift. It’s partially inspired by Laravel / Lumen, so if you’re familiar with it, you’ll probably feel at home.
While the above information is true, there’re still some differences. As opposed to Laravel and its Blade templating engine, Vapor uses Leaf.
It’s new and sometimes lacks documentation, so I’ve decided to write this article and explain how to extend it.
What is a custom tag in Leaf?
Custom tags are basically functions which are available in templates. It’s something similar to helpers from Laravel and Rails world.
The simplest example could be a function outputting the current year.
Custom tags in Leaf are supposed to conform to BasicTag
protocol (interface) which looks like this:
public protocol BasicTag: Tag {
func run(arguments: [Argument]) throws -> Node?
}
Let’s create a class implementing this interface (I’ve created it in the Sources/ProjectName/Leaf/Tags directory
):
import Leaf
import Foundation
public class Year: BasicTag {
public func run(arguments: [Argument]) throws -> Node? {
}
}
Every single tag in Vapor has to have a name
property which will be the name of your “helper”, so you can call it within a template.
import Leaf
import Foundation
public class Year: BasicTag {
// here's the name property
public let name = "year"
public func run(arguments: [Argument]) throws -> Node? {
}
}
Finally, let’s implement the functionality itself:
import Leaf
import Foundation
public class Year: BasicTag {
// here's the name property
public let name = "year"
public func run(arguments: [Argument]) throws -> Node? {
// get the current date and time
let currentDateTime = Date()
// get the current calendar
let calendar = Calendar.current
// get the year
let dateTimeComponents = calendar.dateComponents([.year], from: currentDateTime)
// convert it to Node?, so it conforms to the protocol
return Node(dateTimeComponents.year!)
}
}
Good. Now we have our custom tag but we can’t access it in templates yet. To assess this, we have to register our new tag in a view renderer.
Register the helper in a ViewRenderer
To register the custom tag, open the main.swift
file and put the following code after the Droplet initialization:
if let leaf = drop.view as? LeafRenderer {
leaf.stem.register(Year())
}
Vapor supports many different view renderers. As our custom tag is intended to be used only with Leaf, we have to register it only when our project uses the LeafRenderer.
The above code basically means “If the current droplet’s renderer is compatible with LeafRenderer, register the Year()
tag in its stem”.
That’s it!
Now you can use the #year()
helper in your Leaf templates.