stencilproject / Stencil

Stencil is a simple and powerful template language for Swift.
https://stencil.fuller.li
BSD 2-Clause "Simplified" License
2.34k stars 224 forks source link

Question: Is there a better way to render blocks? #330

Open wombat2k opened 1 year ago

wombat2k commented 1 year ago

I'm trying to duplicate the functionality of Django-render-block. Basically I want the ability to only render a specific block in a template. I'm relatively new to Swift, so wasn't expecting much, but to my surprise, I got it to work like so

public extension Template {
    func render(block: String, _ context: Context) throws -> String {
        let context = context
        var append = false
        var collectedTokens = [Token]()

        for token in tokens {
            if token.contents.description.starts(with: "block \(block)") {
                append = true
            }

            if token.contents.description == "endblock \(block)" {
                break
            }

            if append {
                collectedTokens.append(token)
            }
        }

        let parser = TokenParser(tokens: collectedTokens, environment: context.environment)
        let nodes = try parser.parse()
        return try renderNodes(nodes, context)
    }
}

Obviously this is very crude and relies on a textual representation of the token, but it does exactly what I need and as a bonus it worked with custom tags. Is there a better more elegant way to achieve this?