ofbiz中FreeMarkerWorker的makeConfiguration方法

            这个方法是说明了为什么在ftl中可以使用一些java方法

            1.代码展示

public static Configuration makeConfiguration(BeansWrapper wrapper) {
        /**
         * freemarker.template.Configuration实例并调整其设置。
         * 一个Configuration实例是存储FreeMarker应用程序级别设置的中心。
         * 另外,它处理预先解析的模板(即 对象)的创建和 缓存Template
         * */
        Configuration newConfig = new Configuration(version);

        /**
         * @author jack
         *
         * 对象包装器
         * wrapper == >freemarker.ext.beans.BeansWrapper
         * 这是一个最原始的对象包装器,主要用来映射java
         * 虽然原始,但是也有使用的时候,比如collection-s和map-s被允许修改模板时执行
         * 参考资料 http://freemarker.org/docs/pgui_misc_beanwrapper.html
         * */
        newConfig.setObjectWrapper(wrapper);

        /**
         * @author jack
         *
         * 从beanswrapper返回TemplateHashModel。
         * getstaticmodels()可以用来访问静态方法和任意一类的字段创建哈希模型。
         * */
        TemplateHashModel staticModels = wrapper.getStaticModels();

        /**
         * @author jack
         * 将TemplateHashModel通过Static注入 以后就可以直接通过Static进行访问
         * Shared variables共享变量是为所有模板定义的变量
         * 形式:statics["java.lang.System"].currentTimeMillis() 这是一种调用java方法的处理方式 ftl中的用法
         * */
        newConfig.setSharedVariable("Static", staticModels);

        /**
         * @author jack
         *
         * #assign ls = EntityQuery.use(delegator).from("DictType").()     ftl中的用法
         * 注入后就可以直接使用EntityQuery了
         * */

        try {
            newConfig.setSharedVariable("EntityQuery", staticModels.get("com.hanlin.fadp.entity.util.EntityQuery"));
        } catch (TemplateModelException e) {
            Debug.logError(e, module);
        }
        /**
         * @author jack
         *
         * 当一个模板包含另一个模板时,它试图加载以相同的本地化环境加载模板。
         * 假定你的模板以本地化en_US来加载,那就意味着是U.S. English。当你包含另外一个模板:那么引擎实际上就会寻找一些模板,并按照这个顺序:
         * footer_en_US.ftl
         * footer_en.ftl
         * footer.ftl
         * 设置成为false就不会有这些问题
         * */
        newConfig.setLocalizedLookup(false);

        //创建StringUtil这个工具类共享变量
        newConfig.setSharedVariable("StringUtil", new BeanModel(StringUtil.INSTANCE, wrapper));

        /**
         * @author jack
         *
         * 如果在这些内建的模版加载器中没有一个符合你的要求,
         * 那么你可以自己定制一个模版加载器,只需要实现freemarker.cache.TemplateLoader 接口就可以了,
         * 然后通过方法setTemplateLoader(TemplateLoader loader)把其传递给Configuration对象。
         * 主要业务处理不是很清楚
         * */
        newConfig.setTemplateLoader(new FlexibleTemplateLoader());

        /**
         * @author jack
         *
         * 导入库也就是说,它创建一个新的空命名空间 然后执行path在该命名空间中使用参数给出的模板
         * 导入法则:
         * #import "/lib/example.ftl" as e
         * <@e.copyright date="1999-2002"/>
         * 属性文件中的模板就是通过这种方式加载进去
         * 所以在调用的时候需要加入命令空间
         * */
        newConfig.setAutoImports(UtilProperties.getProperties("freemarkerImports"));

        /**
         * @author jack
         *
         * 自定义类实现TemplateExceptionHandler
         * 当ftl渲染出现异常调用这个类的handleTemplateException
         * */
        newConfig.setTemplateExceptionHandler(new FreeMarkerWorker.OFBizTemplateExceptionHandler());

        try {
            newConfig.setSetting("datetime_format", "yyyy-MM-dd HH:mm:ss.SSS");
            newConfig.setSetting("number_format", "0.##########");
        } catch (TemplateException e) {
            Debug.logError("Unable to set date/time and number formats in FreeMarker: " + e, module);
        }

        // Transforms properties file set up as key=transform name, property=transform class name

        /**
         * @author jack
         *
         * 获取上下文加载器,当前加载器在webapp,随意加载其中config的freemarkerTransforms.properties所有值
         * */
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Enumeration<URL> resources;
        try {
            resources = loader.getResources("freemarkerTransforms.properties");
        } catch (IOException e) {
            Debug.logError(e, "Could not load list of freemarkerTransforms.properties", module);
            throw UtilMisc.initCause(new InternalError(e.getMessage()), e);
        }

        /**
         * @author jack
         *
         * 创建其中资源文件值得实例并通过key用setSharedVariable设置进入共享变量
         * */
        while (resources.hasMoreElements()) {
            URL propertyURL = resources.nextElement();
            Debug.logInfo("loading properties: " + propertyURL, module);
            Properties props = UtilProperties.getProperties(propertyURL);
            if (UtilValidate.isEmpty(props)) {
                Debug.logError("Unable to locate properties file " + propertyURL, module);
            } else {
                loadTransforms(loader, props, newConfig);
            }
        }

        return newConfig;
    }

            2.用例说明

            2.1static           

<#assign displayApps = Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security, userLogin, ofbizServerName, "main")>

           2.2StringUtil

 <link rel="shortcut icon" href="<@ofbizContentUrl>${StringUtil.wrapString(shortcutIcon)}</@ofbizContentUrl>" />

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏犀利豆的技术空间

徒手撸框架--实现 RPC 远程调用

微服务已经是每个互联网开发者必须掌握的一项技术。而 RPC 框架,是构成微服务最重要的组成部分之一。趁最近有时间。又看了看 dubbo 的源码。dubbo 为了...

1532
来自专栏LhWorld哥陪你聊算法

【Linux篇】--awk的使用

awk是一个强大的文本分析工具。相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。 简单来说awk就是把文件逐行的读入,(空格...

1432
来自专栏青玉伏案

iOS逆向工程之Hopper中的ARM指令

虽然前段时间ARM被日本软银收购了,但是科技是无国界的,所以呢ARM相关知识该学的学。现在看ARM指令集还是倍感亲切的,毕竟大学里开了ARM这门课,并且做了不少...

3357
来自专栏Java 源码分析

NioEventLoopGroup 源码分析

NioEventLoopGroup 源码分析 1. 在阅读源码时做了一定的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限。为了方便 IDE 查看...

3867
来自专栏青青天空树

node封装mysql操作

        node是基于异步的,因此在进行数据库查询操作的通常是通过回调来操作查询结果。但是在有了es7的async/await,基本不再需要回调了,所以...

2813
来自专栏坚毅的PHP

my php & mysql FAQ

php中文字符串长度及定长截取问题使用str_len("中国") 结果为6,php系统默认一个中文字符长度为3,可改用mb_strlen函数获得长度,mb_su...

3946
来自专栏Java 源码分析

NioEventLoopGroup 源码分析

NioEventLoopGroup 源码分析 1. 在阅读源码时做了一定的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限。为了方便 IDE 查看...

3496
来自专栏Python研发

Django之Model世界

django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM)

1292
来自专栏IT杂记

通过Java程序提交通用Mapreduce任务并获取Job信息

背景 我们的一个业务须要有对MR任务的提交和状态跟踪的功能,须要通过Java代码提交一个通用的MR任务(包括mr的jar、配置文件、依赖的第三方jar包),并且...

1.1K5
来自专栏开发与安全

linux网络编程之socket(一):socket概述和字节序、地址转换函数

一、什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口。 socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程...

3170

扫码关注云+社区

领取腾讯云代金券