PebbleTemplates 自定义tag&filter&function 开发简单说明
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2022-03-16 pip "Directory not empty" while pip installing or updating a package in python3 问题解决
2022-03-16 nginx 使用mime.types 解决mac safari excel xls 下载格式为xls.xlw 问题
2019-03-16 Understanding how uid and gid work in Docker containers
2019-03-16 nightwatchjs 基于nodejs&& webdriver 协议的自动化测试&&持续集成框架
2019-03-16 hasura graphql-engine graphql2chartjs 方便的graphql 转换chartjs 的类库
2018-03-16 service fabric docker 安装
2018-03-16 lets encrypt 申请nginx 泛域名