首页 > 其他分享 >PebbleTemplates 自定义tag&filter&function 开发简单说明

PebbleTemplates 自定义tag&filter&function 开发简单说明

时间:2023-03-16 20:22:20浏览次数:54  
标签:function rongfengliang return 自定义 filter tag Override new public

PebbleTemplates 的扩展能力还是很强大的,开发起来也比较方便,以下是一个简单的说明,更加复杂的推荐查看官方源码学习

filter 开发

  • 参考代码
    此filter 直接返回rongfengliang
 
public class LoginFilter implements Filter {
    public LoginFilter() {
    }
    @Override
    public Object apply(Object input, Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) throws PebbleException {
        return  "rongfengliang";
    }
 
    @Override
    public List<String> getArgumentNames() {
        return null;
    }
}

function 开发

  • 参考代码
    一个输入参数返回
 
public class MyFunction implements Function {
    private final List<String> argumentNames = new ArrayList<>();
    public MyFunction() {
        this.argumentNames.add("name");
    }
    @Override
    public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
        String name = (String) args.get("name");
        return  name;
    }
 
    @Override
    public List<String> getArgumentNames() {
      return this.argumentNames;
    }
}

tag 开发

tag 相对比较复杂,包含了tag 解析树,tag node 处理,tag node 对应业务处理,以下是一个简单的include包装,代码部分服用了现有include 的处理

  • 参考代码
    token 处理,对应tag 名称为rongfengliang
 
public class MyTokenParser implements TokenParser {
    @Override
    public String getTag() {
        return "rongfengliang";
    }
 
    @Override
    public RenderableNode parse(Token token, Parser parser) {
        TokenStream stream = parser.getStream();
        int lineNumber = token.getLineNumber();
        // skip over the 'include' token
        stream.next();
        Expression<?> includeExpression = parser.getExpressionParser().parseExpression();
        stream.expect(Token.Type.EXECUTE_END);
        return new MyIncludeNode(lineNumber, includeExpression);
    }
}

MyIncludeNode node 处理

public class MyIncludeNode extends AbstractRenderableNode {
    private final Expression<?> includeExpression;
   
    public MyIncludeNode(int lineNumber, Expression<?> includeExpression) {
        super(lineNumber);
        this.includeExpression = includeExpression;
    }
 
    @Override
    public void render(PebbleTemplateImpl self, Writer writer, EvaluationContextImpl context)
            throws IOException {
        String templateName = (String) this.includeExpression.evaluate(self, context);
        Map<?, ?> map = Collections.emptyMap();
        if (templateName == null) {
            throw new PebbleException(
                    null,
                    "The template name in an include tag evaluated to NULL. If the template name is static, make sure to wrap it in quotes.",
                    this.getLineNumber(), self.getName());
        }
       // 此处代码复用了include 部分的,需要进行include 模版的处理
        self.includeTemplate(writer, context, templateName, map);
    }
 
    @Override
    public void accept(NodeVisitor visitor) {
        visitor.visit(this);
    }
 
    public Expression<?> getIncludeExpression() {
        return this.includeExpression;
    }
 
}

扩展开发

PebbleTemplates 提供了一个方便的扩展点,可以方便进行扩展的注册,实现AbstractExtension 就可以了

  • 参考代码
public class MyExtension extends AbstractExtension {
 
    @Override
    public Map<String, Filter> getFilters() {
        Map<String, Filter> filters = new HashMap<>();
        filters.put("rongfengliang",new LoginFilter());
        return  filters;
    }
 
    @Override
    public List<TokenParser> getTokenParsers() {
        List<TokenParser> parsers = new ArrayList<>();
        parsers.add(new MyTokenParser());
        return parsers;
    }
 
    @Override
    public Map<String, Function> getFunctions() {
        Map<String, Function> functionMap = new HashMap<>();
        functionMap.put("rongfengliang",new MyFunction());
        return  functionMap;
    }
}

注册扩展

PebbleTemplates 提供了比较方便的扩展注册方法,很简洁

  • 参考代码
MinioClient minioClient =
                MinioClient.builder()
                        .endpoint("http://127.0.0.1:9000")
                        .credentials("minio", "minio123")
                        .build();
DelegatingLoader delegatingLoader = new DelegatingLoader(Arrays.asList(new S3Loader(minioClient,"demoapp")));
// 初始化PebbleEngine, 并进行扩展的注册
PebbleEngine engine = new PebbleEngine.Builder().loader(delegatingLoader).extension(new MyExtension()).build();
PebbleTemplate compiledTemplate = engine.getTemplate("home.html");
Map<String, Object> context = new HashMap<>();
context.put("name", "Mitchell");
Writer writer = new StringWriter();
compiledTemplate.evaluate(writer, context);
String output = writer.toString();
System.out.println(output);

使用

  • 参考模版
// rongfengliang tag 使用
{%  rongfengliang "100/footer.html" %}
// rongfengliang 函数使用
this is demo  {{ rongfengliang('dalongdemoapp') }}
// filter 使用
 <div> {{ "demoapp" | rongfengliang }} <div>

说明

以上代码都放GitHub 上了,具体可以参考github ,PebbleTemplate实现提供的一些能力参考如下类图

 

 

参考资料

https://github.com/PebbleTemplates/pebble
https://pebbletemplates.io/
https://github.com/rongfengliang/pebbletemplates-learning.git

标签:function,rongfengliang,return,自定义,filter,tag,Override,new,public
From: https://www.cnblogs.com/rongfengliang/p/17224022.html

相关文章

  • leaflet 自定义事件
    leaflet 自定义事件主要使用fire()方法,如下图所示,我在区域热力层点击方法中自定义一个handClick方法,并传值。  再去进行监听  预览单击就会触发我们自定义的方......
  • 五、自定义登录逻辑
    ​ 当进行自定义登录逻辑时需要用到之前讲解的UserDetailsService和PasswordEncoder。但是SpringSecurity要求:当进行自定义登录逻辑时容器内必须有PasswordEncoder实例......
  • 五、自定义登录逻辑
    ​ 当进行自定义登录逻辑时需要用到之前讲解的UserDetailsService和PasswordEncoder。但是SpringSecurity要求:当进行自定义登录逻辑时容器内必须有PasswordEncoder实例......
  • cnblogs 博客园自定义样式
    在博客园搜索资料时,发现很多博友的园子装饰的非常炫酷。想着也装饰一下自己的园子,搜索后发现一个不错的插件,记录一下。使用、配置教程:https://bndong.github.io/Cnblog......
  • wpf自定义控件库(二)——伪3D按钮
    1、以学习wpf为目的,同时也为了增加控件代码的复用性,开始建立自己的自定义控件库;2、目前主要是根据项目需求去增加,完善控件库。希望之后能一步步扩展更多更丰富的控件;3、......
  • wpf 自定义控件库(一)
    1、以学习wpf为目的,同时也为了增加控件代码的复用性,开始建立自己的自定义控件库;2、目前主要是根据项目需求去增加,完善控件库。希望之后能一步步扩展更多更丰富的控件;3、......
  • QT5笔记: 22. 自定义代理
    代理作用:在界面发生编辑时可以指定编辑所用的组件,可以沟通Model和View自定义代理需要继承的基类和需要实现的方法使用步骤:继承QStyledItemDelegate,实现上面的四个......
  • C语言编程>第五周 ③ 编写一个程序,用于求m的n次幂。m 和n 由用户输入, 调用自定义的求m
    例题:编写一个程序,用于求m的n次幂。m和n由用户输入,调用自定义的求m的n次幂的函数,并输出计算结果。​​代码如下:​​#include<stdio.h>intpower(intm,intn);intm,n,a=......
  • 自定义TCP协议,私有TCP协议以及TCP协议安全性提高升级
    tcp协议是最底层的,一般来说无需修改,直接使用。但是在某些场景下,直接使用会带来一些安全性的问题:比如物联网设备。物联网设备需要经常的发送消息到服务器,如果直接使用标准T......
  • .net core自定义使用FluentValidation
    本篇实使用FluentValidation时自动注册以及在注册后自动验证,无须在接口中添加验证代码的功能。1.相应开发环境.netcore3.1Nuget包FluentValidation10.0.02.原校验过程......