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 @   QiaoZhi  阅读(4916)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2019-03-05 ActiveMQ消息存储持久化
2019-03-05 TCP通信实现对接硬件发送与接收十六进制数据 & int与byte的转换原理 & java中正负数的表示
点击右上角即可分享
微信分享提示