运行期如何动态Template

需求:将 HTML Template存在数据库里,随时修改,类似于主题模板,运行期添加新主题。

用法1:

import com.jfinal.plugin.ehcache.CacheKit;
import com.jfinal.template.source.FileSource;

public class PageSource extends FileSource {
    //...
    @Override
    public StringBuilder getContent() {
         StringBuilder ret=new StringBuilder();
         ret.append("#define ").append(this.getFileName()).append("()").append('\n');
        //从数据库里取模板
        ret.append("从数据库里取模板").append('\n');
        ret.append("#end");
    }
}

添加模板

Engine.use().addSharedFunction(new PageSource("/","testPage"));

页面中使用 找不到

#@testPage()

Caused by: com.jfinal.template.TemplateException: Template function not defined: testPage



用法2:

import com.jfinal.template.source.ISource;

public class PageSource implements ISource {
    private String fileName;
    //...
    @Override
    public StringBuilder getContent() {
         StringBuilder ret=new StringBuilder();
         ret.append("#define ").append(fileName).append("()").append('\n');
        //从数据库里取模板
        ret.append("从数据库里取模板").append('\n');
        ret.append("#end");
    }
}

添加模板

Engine.use().addSharedFunction(new PageSource("/","testPage"));

页面中使用 找不到

#@testPage()

Caused by: com.jfinal.template.TemplateException: Template function not defined: testPage

如果运行期添加模板?


评论区

JFinal

2017-12-25 23:05

将从数据库里得到的 String 在进行一下如下操作即可:
Engine.use().getTemplateByString(stringValue).render(...);

可以做一个自定义指令用上上面的代码,然后这样用:
#stringTemplate(stringValue);

无为

2017-12-26 20:38

@JFinal 我试一下

无为

2017-12-26 22:30

@JFinal 还是有问题,获取不了上层数据,Template不能render(Scope scope),自定义指令如何设置数据源为Scope ?

HTML:
#set(seoTitle="JFinal 极速开发社区")
#for(i=0;i<2;i++)
#for(j=0;j<2;j++)
#stringTemplate()
#end
#end

StringTemplateDirective:
public class StringTemplateDirective extends Directive {

private static final String stringTemplate="动态模板[#(seoTitle)] i[#(i)] j[#(j)]
";

public void exec(Env env, Scope scope, com.jfinal.template.io.Writer writer) {
Map data=new HashMap();
// 获取本层作用域 data,可能为 null 值
if(null!=scope.getData())
data.putAll(scope.getData());
// 获取顶层作用域 data,可能为 null 值
if(null!=scope.getRootData())
data.putAll(scope.getRootData());
String template=Engine.use().getTemplateByString(stringTemplate,false).renderToString(data);
// String template=Engine.use().getTemplateByString(stringTemplate,false).render(java.io.Writer);
write(writer,template);
}
}

输出:
动态模板[JFinal 极速开发社区] i[] j[0]
动态模板[JFinal 极速开发社区] i[] j[1]
动态模板[JFinal 极速开发社区] i[] j[0]
动态模板[JFinal 极速开发社区] i[] j[1]

无为

2017-12-26 22:33

https://gitee.com/g-vic/easywebsite/blob/master/src/main/webapp/test.html
https://gitee.com/g-vic/easywebsite/blob/master/src/main/java/top/oweb/index/StringTemplateDirective.java

JFinal

2017-12-26 22:38

@无为 将 Engine.buildTemplateBySource(...) 这个方法的代码拿到你的扩展指令中去,里头会 parse 出来 env、stat 这两个参数,然后你可以使用这两个对象创建 Template 这个对象

然后将当前自定义指令中已有的 scope 用于你前面创建的 Template 的 render 方法就可以了

JFinal

2017-12-26 22:38

记得搞定后回来分享一下

无为

2017-12-26 23:04

陈伟

2018-01-14 19:50

搞出来了吗?

无为

2018-01-20 20:02

@陈伟 搞出来了 http://www.jfinal.com/share/575

热门反馈

扫码入社