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 条评论
登录 后参与评论

相关文章

来自专栏极客猴

Django 学习笔记之模型高级用法(上)

前面有两篇文章简单介绍 Django 的模型,这一部分算是基础知识。我自己近期也总做了下总结,将花大概两篇的篇幅来分享下模型的一些高级用法。

633
来自专栏青玉伏案

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

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

2737
来自专栏進无尽的文章

简述OC语言

对于一门语言的学习是需要时间领悟的,而对于一些原理性的问题,我们需要清楚其核心思想,知其然而知其所以然,这样才能有利于自己的后续发展。本文只是简述,没有面面具到...

1292
来自专栏Kirito的技术分享

JAVA 拾遗--Future 模式与 Promise 模式

写这篇文章的动机,是缘起于微信闲聊群的一场讨论,粗略整理下,主要涉及了以下几个具体的问题: 同步,异步,阻塞,非阻塞的关联及区别。 JAVA 中有 callb...

2.4K8
来自专栏开发与安全

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

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

2800
来自专栏Golang语言社区

理解Go语言Web编程(上)

断断续续学Go语言很久了,一直没有涉及Web编程方面的东西。因为仅是凭兴趣去学习的,时间有限,每次去学,也只是弄个一知半解。不过这两天下定决心把Go语言Web编...

36512
来自专栏Charlie's Road

<Solidity学习系列四>使用编译器

Solidity存储库的一个构建目标是solc,solidity命令行编译器。 使用solc --help为您提供所有选项的解释。 编译器可以生成各种输出,范围...

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

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

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

1182
来自专栏Java 源码分析

Java之StringBuffer

1.存储: append(data) 添加在最后 insert(index,data) 在制定位置添加2.删除: delete(start,end) 删除...

3176
来自专栏青青天空树

node封装mysql操作

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

2093

扫码关注云+社区