🍃
Micronaut で Thymeleaf Dialectを追加する方法
以下の環境で作成
- Micronaut: 2.1.0
- Kotlin: 1.4.10
Dialectを作る
公式サイトで紹介されているDialectをそのまま使用する。
<p hello:sayto="World">Hi ya!</p>
↓に変換するDialect
<p>Hello World!</p>
HelloDialect
import org.thymeleaf.context.ITemplateContext
import org.thymeleaf.engine.AttributeName
import org.thymeleaf.model.IProcessableElementTag
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor
import org.thymeleaf.processor.element.IElementTagStructureHandler
import org.thymeleaf.templatemode.TemplateMode
import org.unbescape.html.HtmlEscape
class SayToAttributeTagProcessor(dialectPrefix: String) : AbstractAttributeTagProcessor(
TemplateMode.HTML,
dialectPrefix,
null,
false,
ATTR_NAME,
true,
PRECEDENCE,
true
) {
companion object {
private const val ATTR_NAME = "sayto"
private const val PRECEDENCE = 10000
}
override fun doProcess(
context: ITemplateContext?,
tag: IProcessableElementTag?,
attributeName: AttributeName?,
attributeValue: String?,
structureHandler: IElementTagStructureHandler?) {
structureHandler?.setBody(
"Hello, " + HtmlEscape.escapeHtml5(attributeValue) + "!", false)
}
}
import org.thymeleaf.dialect.AbstractProcessorDialect
class HelloDialect : AbstractProcessorDialect(
"Hello Dialect", "hello", 1000
) {
override fun getProcessors(dialectPrefix: String): Set<SayToAttributeTagProcessor> =
setOf(SayToAttributeTagProcessor(dialectPrefix))
}
TemplateEngineにDialectを追加する
io.micronaut.views.thymeleaf.ThymeleafFactoryでDIコンテナに登録されているTemplateEngineにDialectを追加する。
追加にはBeanCreatedEventListenerを使用する。
import io.micronaut.context.event.BeanCreatedEvent
import io.micronaut.context.event.BeanCreatedEventListener
import org.thymeleaf.TemplateEngine
import javax.inject.Singleton
@Singleton
class TemplateEngineInitializer : BeanCreatedEventListener<TemplateEngine> {
override fun onCreated(event: BeanCreatedEvent<TemplateEngine>): TemplateEngine {
val engine = event.bean
engine.addDialect(HelloDialect()) // ここでDialectを追加
return engine
}
}
HTMLの用意
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<p hello:sayto="World">Hi ya!</p>
</body>
</html>
動作確認
追加したDialectにより hello:sayto
が置き換わっていることがわかる。
$ curl localhost:8080
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<p>Hello, World!</p>
</body>
</html>%
Discussion