vscode插件liveserver增加对thymeleaf模板的简单支持

这篇具有很好参考价值的文章主要介绍了vscode插件liveserver增加对thymeleaf模板的简单支持。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

vscode插件liveserver增加对thymeleaf模板的简单支持

背景

vscode+liveserver开发时,多个页面引用的公用静态资源在每个页面都写一个遍比较麻烦,想让liveserver支持简单的thymeleaf语法,只要能把公用资源抽出来单独放到一个文件中声明即可。

网上找了一下,没有现成的功能,为方便自己使用,修改了一个liveserver插件。

其它人也可能会遇到同样的需求,这里把代码贴出来

实用方式

只有两个简单的js文件,同时简单修改一下liveserver插件的index.js文件即可

liveserver插件的位置:
C:\Users\*\.vscode\extensions\ritwickdey.liveserver-5.7.9\node_modules\live-server(具体路径,由于机器配置以及使用的liveserver版不同,可能不一样)

  1. thymeleaf-handler.jsthymeleaf-parser.js拷到插件目录中的live-server目录中
  2. 修改index.js文件

liveserver目录结构:

vscode插件liveserver增加对thymeleaf模板的简单支持

项目结构

include.html

vscode插件liveserver增加对thymeleaf模板的简单支持

  • env.txt 用于放置环境变里,在页面中可使用th:text来引用
  • include.html 用于放置公共引用,仅支持th:fragment

index.html

vscode插件liveserver增加对thymeleaf模板的简单支持

env.txt

vscode插件liveserver增加对thymeleaf模板的简单支持

输出到浏览器的结果

vscode插件liveserver增加对thymeleaf模板的简单支持

源码

//index.js

var fs = require('fs'),
	connect = require('connect'),
	serveIndex = require('serve-index'),
	logger = require('morgan'),
	WebSocket = require('faye-websocket'),
	path = require('path'),
	url = require('url'),
	http = require('http'),
	send = require('send'),
	open = require('opn'),
	es = require("event-stream"),
	os = require('os'),
	chokidar = require('chokidar'),
	httpProxy = require('http-proxy'),
	HandlerStream = require('./thymeleaf-handler');//这里增加一行对thymeleaf-handler的引用


    ......


    //在后面找到inject函数
    function inject(stream) {
			if (injectTag) {
				// We need to modify the length given to browser
				var len = GET_INJECTED_CODE().length + res.getHeader('Content-Length');
				res.setHeader('Content-Length', len);
				var originalPipe = stream.pipe;
				stream.pipe = function (resp) {
					originalPipe.call(stream, es.replace(new RegExp(injectTag, "i"), GET_INJECTED_CODE() + injectTag))
					.pipe(new HandlerStream(root,res)).pipe(resp);// 修改这一句,把原来的 .pipe(resp) 修改为 .pipe(new HandlerStream(root,res)).pipe(resp);
				};
			}
		}

以下为thymeleaf-handler.jsthymeleaf-parser.js的源码文章来源地址https://www.toymoban.com/news/detail-849058.html

//thymeleaf-handler

const fs = require('fs');
const path = require('path')
const stream = require('stream');
let thymeleafParser = require("./thymeleaf-parser");


class HandlerStream extends stream.Transform{
    constructor (root,res) {
        super();     
        this.root = root;   
        this.body = "";
        this.res = res;
        this.byteLen = 0;
    }

    _parse(){
        return thymeleafParser(this.root,this.body);
    }

    _transform (chunk, encoding, callback){
        this.body += chunk;
        this.byteLen += chunk.byteLength;
        callback()
    }

    _getBufferLen(v){
        const buf = Buffer.from(v, 'utf8');                
        return buf.length;  
    }

    _flush (callback){        
        let newBoday = this._parse();        
        let newLen = this._getBufferLen(newBoday);
        var len = (newLen - this.byteLen) + this.res.getHeader('Content-Length');
        this.res.setHeader('Content-Length', len);        
        this.push(newBoday);
        callback();
    }
}




module.exports = HandlerStream;

//thymeleaf-parser
const fs = require('fs');
const path = require('path');


class Fragment{
    constructor(name,content){
        this.paramName = null;
        this.name = null;

        this.decodeName(name);

        //替换对上下文件的引用
        this.content = content.replace("[[@{/}]]","/");

        let parser = new Parser(this.content);

        parser.parseSrc()
        .parseHref();

        this.content = parser.value;
    }

    decodeName(name){
        let r = /"?(.+?)\((.+)\)"?/;
        let m = r.exec(name);
        if(m){
            this.name = m[1];
            this.paramName = m[2];
        }
        else if(/"(.+)"/.test(name)){        
            this.name = name.slice(1,-1);
        }
        else
            this.name = name;
    }


    getContent(param){
        if(param && this.paramName){
            return this.content.replace(`\${${this.paramName}}`,param)
        }        
        else
            return this.content;

    }

}

class Parser{
    constructor(value){
        this.value = value;
    }
    parseSrc(){
        this.value = this.value.replace(/th:src="@\{(.+?)\}"/g,'src="$1"');

        return this;
    }

    parseHref(){
        this.value = this.value.replace(/th:href="@\{(.+?)\}"/g,'href="$1"');

        return this;
    }

    parseText(env){
        let reg = /<(div|a|input|span|button|p|title)(.*?) th:text="(.+?)"(.*?)><\/\1>/g;

        let textBlocks = [];

        let m = reg.exec(this.value);
        while(m){
            m[0];
            m[2];
            textBlocks.push({
                tagContent: m[0],
                tagName: m[1],
                attrs:[m[2],m[4]],
                value: m[3]
            });

            m = reg.exec(this.value);
        }


        reg = /\$\{(.+)\}/;

        for(let b of textBlocks){
            m = reg.exec(b.value);
            if(m && env.getValue(m[1])){
                b.value = env.getValue(m[1]);
            }
            
            let tag = `<${b.tagName}${b.attrs[0]}${b.attrs[1]}>${b.value}</${b.tagName}>`;
            this.value = this.value.replace(b.tagContent,tag);
           
        }

        return this;
    }

    parseBlock(fragments){
     
        function removeBrackets(v){
            if(!v) return v;
            
            let m = /\('(.+)'\)/.exec(v);
            if(m){
                return m[1];
            }
            else{
                return "";
            }
        }
        //<th:block th:include="include :: header('示例')"/>
        let reg = /<th:block th:include="include\s*::\s*([a-zA-z0-9_]+?)(\(.+\))?"\s*\/>/g;


        let blocks = [];

        let m = reg.exec(this.value);
        while(m){
        
            blocks.push({
                tag: m[0],
                name: m[1],
                param: removeBrackets(m[2])
            });
            m = reg.exec(this.value);
        }


        for(let block of blocks){
            let fragment = fragments[block.name];
            if(fragment){
                this.value = this.value.replace(block.tag,fragment.getContent(block.param));
            }
         
        }
        return this;
    }
}

class Evn{
    constructor(){
        this.values = {};
    }

    load(root){        
        let envString = readFile(path.resolve(root,"env.txt"))

        let lines = envString.split('\n');

        let r = /(.+?)=(.+)/;

        for(let l of lines){
            l = l.trim();
            if(l.startsWith("#") || !l) continue;

            let m = r.exec(l);
            if(m){
                this.values[m[1].trim()] = m[2].trim();
            }               
        }
    }

    getValue(key){
        if(this.values[key]){
            return this.values[key];
        }
        else
            return null;
    }

}

function parseTemplate(template){{
    let fragmentReg = /<(div|head|section)\s+th:fragment=(.*?)>(.*?)<\/\1>/gs;

    let fragments = {};

    let m = fragmentReg.exec(template);

    while(m){
        let fragment = new Fragment(m[2],m[3]);
        fragments[fragment.name] = fragment;
     
        m = fragmentReg.exec(template);
    }

    return fragments;
}}

function readFile(fileName){
    if(fs.existsSync(fileName)){
        return fs.readFileSync(fileName).toString("utf8");
    }
    else
        return "";
}

function readTemplate(root){    
    return readFile(path.resolve(root,"include.html"));
}

function parse(root,html){
    
    let fragments = parseTemplate(readTemplate(root));

    let env = new Evn();
    env.load(root);


    let parser = new Parser(html);

    parser.parseSrc()
    .parseHref()
    .parseBlock(fragments)
    .parseText(env);


    return parser.value;
}



module.exports = parse

到了这里,关于vscode插件liveserver增加对thymeleaf模板的简单支持的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【Spring Boot】Thymeleaf模板引擎 — Thymeleaf入门

    主要介绍什么是Thymeleaf以及Spring Boot如何集成使用Thymeleaf模板,最后介绍Spring Boot支持的Thymeleaf的一些常用的配置参数。 Thymeleaf是一款非常优秀的服务器端页面模板引擎,适用于Web和独立环境,具有丰富的标签语言和函数,能够处理HTML、XML、JavaScript甚至文本。 Thymeleaf相较于

    2024年02月05日
    浏览(11)
  • 【工具】Vscode翻译插件推荐(不用谷歌翻译api、支持短句英汉互译、支持查词、支持自动补全、不需要浏览器)

    【工具】Vscode翻译插件推荐(不用谷歌翻译api、支持短句英汉互译、支持查词、支持自动补全、不需要浏览器)

    需求: 1)偶尔需要查英文生词; 2)有时候想不起来中文对应的英文; 3)不想回到浏览器打开一堆网页; 4)谷歌翻译挂了。 偶尔需要的需求: 1)短句翻译。 因为谷歌翻译挂了,首先,排除最热门的翻译插件Vscode Google Translate,以及一系列衍生产品。 由于搜索“translate”

    2023年04月08日
    浏览(13)
  • SpringBoot Thymeleaf模板引擎

    SpringBoot Thymeleaf模板引擎

    前端交给我们的页面,是 html 页面。如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。 jsp支持非常强大的功能,包括能写Java代码,但是呢,我们现在的这种情况,SpringBoot这

    2024年02月13日
    浏览(32)
  • thymeleaf模板引擎

    thymeleaf模板引擎

    ThymeleafProperties 配置类 1.默认编码 2.前缀 3.后缀 相当于视图解析器    这是学SpringBoot的必经之路,非常重要!!!(除非你是学前端的)   只改了前端代码点一下这个就可以刷新    传值过来了  th:text=\\\"${msg}\\\"爆红,但是可以显示,File-Settings-Editor-Inspection  取消“Expression

    2024年02月14日
    浏览(10)
  • 【SpringBoot】| Thymeleaf 模板引擎

    【SpringBoot】| Thymeleaf 模板引擎

    目录 Thymeleaf 模板引擎 1. 第一个例子 2. 表达式 ①标准变量表达式 ②选择变量表达式(星号变量表达式) ③链接表达式(URL表达式) 3. Thymeleaf的属性 ①th:action ②th:method ③th:href ④th:src ⑤th:text ⑥th:style ⑦th:each (重点) ⑧条件判断 if-unless ⑨switch-case 判断语句 ⑩th:inline内联

    2024年02月08日
    浏览(9)
  • Thymeleaf SSTI模板注入分析

    Thymeleaf SSTI模板注入分析

    先搭建一个SpringMVC项目,参考这篇文章,或者参考我以前的spring内存马分析那篇文章 https://blog.csdn.net/weixin_65287123/article/details/136648903 简单写个servlet 这样就是访问到index.jsp 路由解析流程主要就是 Model 和 View 以及最后 Render 。return处打个断点,看怎么处理的 先进入 invokeAndHa

    2024年04月12日
    浏览(12)
  • SpringBoot整合模板引擎Thymeleaf(4)

    SpringBoot整合模板引擎Thymeleaf(4)

    本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 在之前的教程中,我们介绍了Thymeleaf的基础知识。在此,以案例形式详细介绍Thymeleaf的基本使用。 要点概述: 1、在static下创建css文件夹用于存放css文件 2、在static下创建img文件夹用于存放图片文件 请在pom.xml文

    2024年02月10日
    浏览(9)
  • 【SpringBoot学习笔记】04. Thymeleaf模板引擎

    【SpringBoot学习笔记】04. Thymeleaf模板引擎

     所有的html元素都可以被thymeleaf替换接管  th:元素名 templates下的只能通过Controller来跳转,templates前后端分离,需要模板引擎thymeleaf支持    模板引擎的作用就是我们来写一个页面模板,比如有些值呢,是动态的,我们写一些表达式。而这些值,从哪来呢,就是我们在后台封

    2024年02月13日
    浏览(9)
  • 前端模板引擎Thymeleaf的整合和使用

    目录 一、添加依赖 1.1首先,在项目的构建文件中(比如 Maven 或 Gradle)添加 Thymeleaf 的依赖。例如,对于 Maven 项目,在 pom.xml 文件中添加以下依赖 1.2保存并更新项目依赖 二、配置Thymeleaf 2.1模板位置配置 2.2模板缓存配置 2.3自定义标签配置 三、创建模板文件 3.1创建一个HTML文

    2024年04月27日
    浏览(16)
  • SpringBoot自带模板引擎Thymeleaf使用详解①

    SpringBoot自带模板引擎Thymeleaf使用详解①

    目录 前言 一、SpringBoot静态资源相关目录 二、变量输出 2.1 在templates目录下创建视图index.html 2.2 创建对应的Controller 2.3 在视图展示model中的值 三、操作字符串和时间 3.1 操作字符串 3.2 操作时间         Thymeleaf是一款用于渲染XML/HTML5内容的模板引擎,类似JSP。它可以轻易的

    2024年02月08日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包