springboot+thymeleaf自定义标签
一般的标签无非就是两种,第一种是我们向标签输出内容(类似于th:each)。第二种就是根据标签是否显示标签内部的元素(类似于th:if)。
1.基于springboot1.5+thymeleaf2.1的研究
1.第一类控制标签内容是否显示的标签
这种分为两种,一种是作为标签,一种是作为属性。
如下:
<mytag:displayele name="1"> 这里看的到 </mytag:displayele> <p mytag:displayattr="false"> 这里看不到123456 </p>
步骤:
1.建立自己的dialect
package cn.qlq.myTag; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.thymeleaf.dialect.AbstractDialect; import org.thymeleaf.processor.IProcessor; public class MyAutoDialect extends AbstractDialect { private static final String PREFIX = "mytag"; private static final Set<IProcessor> processors = new HashSet<IProcessor>(); static { processors.add(new HasPermissionAttrProcessor()); processors.add(new HasPermissionElementProcessor()); } public String getPrefix() { return PREFIX; } @Override public Set<IProcessor> getProcessors() { return Collections.unmodifiableSet(processors); } }
2.建立自己的处理器
(1)属性处理器
package cn.qlq.myTag; import org.thymeleaf.Arguments; import org.thymeleaf.dom.Attribute; import org.thymeleaf.dom.Element; import org.thymeleaf.processor.attr.AbstractConditionalVisibilityAttrProcessor; /** * 作为属性判断 * * @author Administrator * */ public class HasPermissionAttrProcessor extends AbstractConditionalVisibilityAttrProcessor { private static final String ATTRIBUTE_NAME = "displayattr"; private static final int PRECEDENCE = 300; protected HasPermissionAttrProcessor() { super(ATTRIBUTE_NAME); } @Override public int getPrecedence() { return PRECEDENCE; } @Override public boolean isVisible(final Arguments arguments, final Element element, final String attributeName) { // 根据元素的name属性进行判断(name为1或者true的时候显示)==当然我们可以用其他属性,也可以用name属性做其他操作 Attribute attributeFromNormalizedName = element.getAttributeFromNormalizedName(attributeName); if (attributeFromNormalizedName != null) { String escapedValue = attributeFromNormalizedName.getEscapedValue(); if ("1".equals(escapedValue) || "true".equals(escapedValue)) { return true; } } return false; } }
(2)元素处理器(元素标签最好不用大写)
package cn.qlq.myTag; import org.thymeleaf.Arguments; import org.thymeleaf.dom.Attribute; import org.thymeleaf.dom.Element; import org.thymeleaf.processor.element.AbstractConditionalVisibilityElementProcessor; /** * 元素判断 * * @author Administrator * */ public class HasPermissionElementProcessor extends AbstractConditionalVisibilityElementProcessor { private static final String ELEMENT_NAME = "displayele"; private static final int PRECEDENCE = 300; protected HasPermissionElementProcessor() { super(ELEMENT_NAME); } // 判断元素是否可见 @Override public boolean isVisible(final Arguments arguments, final Element element) { // 根据元素的name属性进行判断(name为1或者true的时候显示)==当然我们可以用其他属性,也可以用name属性做其他操作 Attribute attributeFromNormalizedName = element.getAttributeFromNormalizedName("name"); if (attributeFromNormalizedName != null) { String escapedValue = attributeFromNormalizedName.getEscapedValue(); if ("1".equals(escapedValue) || "true".equals(escapedValue)) { return true; } } return false; } @Override public int getPrecedence() { return PRECEDENCE; } @Override public boolean removeHostElementIfVisible(final Arguments arguments, final Element element) { return true; } }
3.注册自己的方言
package cn.qlq.myTag; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyAutoDialectConfiguration { @Bean public MyAutoDialect myAutoDialect() { return new MyAutoDialect(); } }
4.界面如下:
<!doctype html> <html lang="zh_CN" xmlns:th="http://www.thymeleaf.org" xmlns:mytag="http://thymeleafexamples"> <head> <meta charset="UTF-8"/> <title>后台登录-X-admin2.0</title> </head> <body class="login-bg"> <mytag:displayele name="false"> 这里看不到 </mytag:displayele> <mytag:displayele name="1"> 这里看的到 </mytag:displayele> <p mytag:displayattr="false"> 这里看不到123456 </p> <p mytag:displayattr="1"> 这里看的到123456 </p> </body> </html>
结果:
2.自定义标签输出内容的标签
这种分为两种,一种是作为标签,一种是作为属性。
1.自定义处理器
(1)元素处理器
package cn.qlq.myTag; import java.util.ArrayList; import java.util.List; import org.thymeleaf.Arguments; import org.thymeleaf.dom.Attribute; import org.thymeleaf.dom.Element; import org.thymeleaf.dom.Node; import org.thymeleaf.dom.Text; import org.thymeleaf.processor.element.AbstractMarkupSubstitutionElementProcessor; /** * 作为元素 * * @author Administrator * */ public class SetContentElementProcessor extends AbstractMarkupSubstitutionElementProcessor { private static final String ELEMENT_NAME = "setcontentele"; private static final int PRECEDENCE = 300; protected SetContentElementProcessor() { super(ELEMENT_NAME); } /** * 相当于返回节点的信息 */ @Override protected List<Node> getMarkupSubstitutes(Arguments arguments, Element element) { final Element container = new Element("div"); String textStr = "来自后台的数据"; // 读取元素的name属性 Attribute attributeFromNormalizedName = element.getAttributeFromNormalizedName("name"); if (attributeFromNormalizedName != null) { String escapedValue = attributeFromNormalizedName.getEscapedValue(); textStr += "name = " + escapedValue; } final Text text = new Text(textStr); container.addChild(text); final List<Node> nodes = new ArrayList<>(); nodes.add(container); return nodes; } @Override public int getPrecedence() { return PRECEDENCE; } }
(2)属性处理器
package cn.qlq.myTag; import java.util.List; import org.thymeleaf.Arguments; import org.thymeleaf.dom.Attribute; import org.thymeleaf.dom.Element; import org.thymeleaf.processor.attr.AbstractTextChildModifierAttrProcessor; /** * 作为属性判断 * * @author Administrator * */ public class SetContentAttrProcessor extends AbstractTextChildModifierAttrProcessor { private static final String ATTRIBUTE_NAME = "setcontentattr"; private static final int PRECEDENCE = 300; protected SetContentAttrProcessor() { super(ATTRIBUTE_NAME); } @Override public int getPrecedence() { return PRECEDENCE; } @Override protected String getText(Arguments arguments, Element element, String attributeName) { // 读取元素的name属性 Attribute attributeFromNormalizedName = element.getAttributeFromNormalizedName(attributeName); if (attributeFromNormalizedName != null) { String escapedValue = attributeFromNormalizedName.getEscapedValue(); return "attributeName: " + attributeName + ", value: " + escapedValue; } return ""; } }
2.dialect中加入
processors.add(new SetContentElementProcessor()); processors.add(new SetContentAttrProcessor());
3.界面使用
<mytag:setcontentele name="3">
自定义标签
</mytag:setcontentele>
<div mytag:setcontentattr="3">
<p>取nameAttr</p>
</div>
结果:
【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】