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>

结果:

 

posted @ 2020-03-05 13:42  QiaoZhi  阅读(4736)  评论(0编辑  收藏  举报