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>

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM