Skip to main content Skip to docs navigation

Template Extending

Document not reviewed yet, might be outdated. Please, let us know if you find something invalid here.
On this page

It is possible to extend KorTE with new tags, functions and filters.

Extending

By registering new extensions via TemplateConfig.register you can have more functionality in your templates.

val config = TemplateConfig()
config.register(Filter("length") { subject.dynamicLength() })

val template = Template("mytemplate", config)

Filters

Filters have an injected this with the execution context, the subject,and optionally the args of the filter call.

config.register(Filter("length") { subject.dynamicLength() })
config.register(Filter("chunked") {
    subject.toDynamicList().chunked(args[0].toDynamicInt())
})

Functions

Functions have an args argument that receives a list of parameters already evaluated:

config.register(TeFunction("cycle") { args ->
    val list = args.getOrNull(0).toDynamicList()
    val index = args.getOrNull(1).toDynamicInt()
    list[index umod list.size]
})

Tags

A tag has an associated name, several internal tag names, and a tag that ends this tag or null if it is not a block.

config.register(Tag("capture", setOf(), null) {
    data class BlockCapture(val varname: String, val content: Block) : Block {
		override suspend fun eval(context: Template.EvalContext) {
			val result = context.capture {
				content.eval(context)
			}
			context.scope.set(varname, RawString(result))
		}
	}

    val main = chunks[0]
    val tr = ExprNode.Token.tokenize(main.tag.content)
    val varname = ExprNode.parseId(tr)
    DefaultBlocks.BlockCapture(varname, main.body)
})
config.register(Tag("switch", setOf("case", "default"), setOf("endswitch")) {
    var subject: ExprNode? = null
    val cases = arrayListOf<Pair<ExprNode, Block>>()
    var defaultCase: Block? = null

    for (part in this.chunks) {
        val tagContent = part.tag.content
        val body = part.body
        when (part.tag.name) {
            "switch" -> {
                subject = ExprNode.parse(tagContent)
            }
            "case" -> {
                cases += ExprNode.parse(tagContent) to body
            }
            "default" -> {
                defaultCase = body
            }
        }
    }
    if (subject == null) error("No subject set in switch")
    //println(this.chunks)
    object : Block {
        override suspend fun eval(context: Template.EvalContext) {
            val subjectValue = subject.eval(context)
            for ((case, block) in cases) {
                if (subjectValue == case.eval(context)) {
                    block.eval(context)
                    return
                }
            }
            defaultCase?.eval(context)
            return
        }
    }
})
Was this article useful?