Skip to content

Custom tags with body #86

@koenpunt

Description

@koenpunt

I tried to define a custom tag that accepts a body, but the body is provided to the tag as [Syntax], which is not something that converts to the required return type of LeafData.

How can I capture the body, and return if necessary?

For context, I'm trying to create requireRole(role) tag, that returns the body if the role matches the role of the current user;

#requireRole("ADMIN"):
<a href="/projects/#(project.id)/delete">Delete</a>
#endrequireRole

In the tag class I retrieve the body using ctx.requireBody(), which, as mentioned, returns an array of Syntax elements.

final class RequireRoleTag<A>: LeafTag where A: RoleAuthenticatable {
    init(userType: A.Type) {}

    func render(_ ctx: LeafContext) throws -> LeafData {
        try ctx.requireParameterCount(1)
        let body = try ctx.requireBody()

        guard let requiredRole = ctx.parameters[0].string else {
            throw "role is not a string"
        }

        guard let req = ctx.request,
              let role = getRole(req: req)
        else {
            return .trueNil
        }

        if role == requiredRole {
            // This doesn't work
            return body
        }

        return .trueNil
    }

    private func getRole(req: Request) -> String? {
        let a = req.auth.get(A.self)
        return a?.role.description
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions