[Solved] Vapor 3/Leaf 3: Create Custom Tag

I am trying to create a custom tag and capture the body content as well. For example:

<html>
<body>
#myTag(parameters: []) {
capture <all></all> the things here
}
</body>
</html>

I have created a class for this, and am able to render out the tag name itself, but have not figured out how to capture the body:

public final class MyTag: TagRenderer {
    public init() {}
    
    public func render(tag: TagContext) throws -> Future<TemplateData> {
        let html = "<tag>\(tag.body)</tag>"

        return Future.map(on: tag) {
            .string(html)
        }
    }
}

This ends up spitting out the raw representation of the tag (which does contain the content), but not the content itself, and I have been unable to figure out how to get the content string out of the body:

[Raw: , Raw: capture <all></all> the things here]

Does anyone have suggestions on how to achieve this? Thanks!

I found the solution, in case anyone comes across this in the future:

    public func render(tag: TagContext) throws -> Future<TemplateData> {
    let body = try tag.requireBody()

    return tag.serializer.serialize(ast: body).map(to: TemplateData.self) { body in
        let content = String(data: body.data, encoding: .utf8) ?? ""
        let html = "<myTag>\(content)</myTag>"

        return .string(html)
    }
}

@mikebronner Thank you for sharing the solution - much appreciated! :]

1 Like

This topic was automatically closed after 166 days. New replies are no longer allowed.