[JAVA] Create your own dialect to convert line feed code to line feed tag in Thymeleaf3

Abstract

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.

environment

Overview

Detailed procedure

Implement the Proccessor class (the class that actually describes the operation)

Class definition

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 {
  ...
}

constructor

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.

Process execution method

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.

  1. Get the ʻIModelFactory instance from the argument context`.
  2. Create a ʻIModel instance from the obtained ʻIModelFactory instance.
  3. Add elements (character strings and tags) to be reflected in HTML to the created ʻIModel instance in order. The instance to be added is also created from the ʻIModelFactory instance.
  4. Apply the ʻIModel 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);

Implement the Dialect class (a class that collectively defines a Proccessor as a dialect)

Class definition

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 {
  ...
}

constructor

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

Processor registration

ʻ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;
  }

Set in Bean

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();
 }

Execution result

<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>

画面表示.png

Reference site

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

Create your own dialect to convert line feed code to line feed tag in Thymeleaf3
Convert line feed code to html line feed tag with Thymeleaf and output
How to specify character code and line feed code in JAXB
How to set character code and line feed code in Eclipse
How to create your own annotation in Java and get the value
Create your own shortcuts in Xcode to eliminate the hassle of pod install
Create your own Utility with Thymeleaf with Spring Boot
Sample code to convert List to List <String> in Java Stream
How to read your own YAML file (*****. Yml) in Java
[Forge] How to register your own Entity and Entity Render in 1.13.2
I wrote a code to convert numbers to romaji in TDD
Refer to enum in Thymeleaf
Create your own Java annotations
Make your own keyboard QMK in Docker. Volume unique to Windows
How to create your own Controller corresponding to / error with Spring Boot