Even if Thymeleaf outputs a character string including a line feed code, it only breaks in the HTML source and does not break on the display.
Create your own dialect with the function of converting the line feed code to a line feed tag and outputting a character string, and use it as an alternative dialect of th: text
.
Although the implementation is different between Thymeleaf 2 and 3, this paper deals with Thymeleaf3.
From the Proccessor type abstract classes provided by Thymeleaf, select the one that is close to what you want to do and create a class that inherits it.
This time, we will create something similar to the Standard Dialect th: text
, so we will inherit ʻAbstractStandardExpressionAttributeTagProcessor`.
public class BreakLineProccessor extends AbstractStandardExpressionAttributeTagProcessor {
...
}
Be sure to create a constructor and define how the Proccessor will be used.
private static final String ATTR_NAME = "brtext";
public BreakLineProccessor(String dialectPrefix, int precedence) {
super(TemplateMode.HTML, dialectPrefix, ATTR_NAME, precedence, true);
}
In addition, each argument of the constructor of ʻAbstractStandardExpressionAttributeTagProcessor` which is the inheritance source class is as follows.
Variable name | class | role | |
---|---|---|---|
1 | templateMode | TemplateMode(enum) | Template type(HTML etc.) |
2 | dialectPrefix | String | Dialect prefix(Left side of the colon) |
3 | attrName | String | Attribute name of dialect(Right side of the colon) |
4 | precedence | int | Processor processing execution priority(The smaller the value, the higher the priority) |
5 | removeAttribute | boolean | Whether to remove the dialect attribute after Processor processing(If true, remove) |
This time, only the prefix and priority were received from outside, and the rest were fixed values.
Describe the process by overriding the abstract method doProcess
.
In the case of doProcess
of ʻAbstractStandardExpressionAttributeTagProcessor, the result of interpreting the EL expression is stored in the argument ʻexpressionResult
.
The outline of the whole process is as follows.
instance from the argument
context`. instance from the obtained ʻIModelFactory
instance. instance in order. The instance to be added is also created from the ʻIModelFactory
instance. instance to the argument
structureHandler`. @Override
protected void doProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName,
String attributeValue, Object expressionResult, IElementTagStructureHandler structureHandler) {
//If null, nothing is output and processing ends
if (expressionResult == null) return;
IModelFactory factory = context.getModelFactory();
IModel model = factory.createModel();
ITemplateEvent brTag = factory.createOpenElementTag("br");
//Split by line feed code
String[] lines = expressionResult.toString().split("\r\n|\r|\n", -1);
for (String line : lines) {
// <br>+Add one line of string to model
model.add(brTag);
model.add(factory.createText(line));
}
//At the beginning<br>Remove tag
model.remove(0);
structureHandler.setBody(model, false);
Create a class that inherits (implements) the dialect processing created from the Dialect abstract class and interface provided by Thymeleaf. Since this process was implemented by Processor this time, it inherits the abstract class ʻAbstractProcessorDialect`.
public class KurukuruzDialect extends AbstractProcessorDialect {
...
}
Be sure to create a constructor and define how the Dialect will be used.
private static final String NAME = "kurukuruz original dialect";
private static final String PREFIX = "krz";
public KurukuruzDialect() {
super(NAME, PREFIX, StandardDialect.PROCESSOR_PRECEDENCE);
}
In addition, each argument of the constructor of ʻAbstractProcessorDialect` which is the inheritance source class is as follows.
Variable name | class | role | |
---|---|---|---|
1 | name | String | Name of dialect(?),I don't use it in particular |
2 | prefix | String | Dialect prefix,It becomes an argument of the Procedureor registration method described later. |
3 | processorPrecedence | int | Number used to prioritize Processor processing execution |
ʻThe instance of each Procedureor registered in the dialect in getProcessors
, which is the abstract method of AbstractProcessorDialect`, is collected as a Set and returned.
@Override
public Set<IProcessor> getProcessors(String dialectPrefix) {
Set<IProcessor> proccessors = new HashSet<>();
proccessors.add(new BreakLineProccessor(dialectPrefix, getDialectProcessorPrecedence()));
return proccessors;
}
Create a Bean definition method as shown below in an appropriate class with the @Bean
annotation enabled, and register the Dialect instance.
@Bean
KurukuruzDialect kurukuruzDialect() {
return new KurukuruzDialect();
}
<body>
<div krz:brtext="${text1}"></div>
<div krz:brtext="${text2}"></div>
<div krz:brtext="${text3}"></div>
<div krz:brtext="${text4}"></div>
<div krz:brtext="${text5}"></div>
</body>
model.addAttribute("text1", "No line breaks");
model.addAttribute("text2", "CRLF line break\r\n Yes\r\n\r\n ↑ 2 consecutive line breaks");
model.addAttribute("text3", "CR line break\with r");
model.addAttribute("text4", "LF line break\n Yes");
model.addAttribute("text5", null);
↓↓↓↓↓
<body>
<div>No line breaks</div>
<div>CRLF line break<br>Yes<br><br>↑ 2 consecutive line breaks</div>
<div>CR line break<br>Yes</div>
<div>LF line break<br>Yes</div>
<div></div>
</body>
Thymeleaf converts line feed code to html line feed tag and outputs --Qiita Make your own Dialect with Thymeleaf3 --Qiita [Implement Dialect in thymeleaf3 --abcdefg .....](http: //pppurple.hatenablog.com/entry/2017/03/22/225114)
Recommended Posts