zoukankan      html  css  js  c++  java
  • FreeMarker <#include> 指令扩展

    什么是 FreeMarker

    FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本( HTML 网页,电子邮件,配置文件,源代码等)的通用工具。它不是面向最终用户的,而是一个 Java 类库,是一款程序员可以嵌入他们所开发产品的组件。简单说,
    FreeMarker: 模板 + 数据 = 输出

    FreeMarker 内建指令 —— include

    FreeMarker 中包含很多内建的指令,犹如 JSP 中的标签一样。这里主要讲下 include 指令。参考 Freemarker 官方文档,其语法格式如下:
    <#include path> 或 <#include path options>
    其中:

    • path: 要包含文件的路径;一个算作是字符串的表达式。(用其他话说, 它不用是一个固定的字符串,它也可以是像 profile.baseDir + "/menu.ftl" 这样的东西。)
    • options: 一个或多个这样的选项: encoding=encoding, parse=parse
      • encoding: 算作是字符串的表达式
      • parse: 算作是布尔值的表达式(为了向下兼容,也接受一部分字符串值)
      • ignore_missing: 算作是布尔值的表达式

    你可以使用它在你的模板中插入另外一个 FreeMarker 模板文件 (由 path 参数指定)。 被包含模板的输出格式是在 include 标签出现的位置插入的。被包含的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。值得注意的是,include 指令不能由被包含文件的内容所替代,它只是当 FreeMarker 每次在模板处理期间到达 include 指令时处理被包含的文件。也就是说,这边可以在执行时,动态指定需包含的 FreeMarker 模板文件。

    一个错误场景

    假设有这样一个场景,需要介绍全国的每一个省。每个省有一个对应的以省份名称命名的 FreeMarker 模板(当然,这些模板都是在一个总的模板下显示),如:js.ftl。
    一般来说,我们可以这样写总的模板,来达到动态包含省份的模板。

    <!DOCTYPE html>
    <html>
      <head>
          ...
      </head>
      <body>
        <#include "/${province}.ftl"/>
      </body>
    </html>
    

    看着上面的代码,是不是觉得 FreeMarker 还是很方便很强大的啊!但是坑来了,假设目前项目还没有开发完成,也就是说,有的省份还没有对应的 FreeMarker 模板,那么会出现什么情况呢?直接报错了。对于项目没做完这种事,我们得找个临时方案啊,给那些没有开发模板的省份来个默认页面,那么用 include 指令貌似有点力不从心。如何解决呢?FreeMarker 有自定义指令的功能,那就定义一个加强版的 include 指令吧,使得该指令在找不到指定模板的情况下,包含一个默认的模板。

    public class IncludeXMacro implements TemplateDirectiveModel {
    
        private static final String PATH_PARAM = "template";
    
        private static final String DEFALUT_PATH_PARAM = "default_template";
    
        @Override
        public void execute(Environment environment, @SuppressWarnings("rawtypes") Map params, TemplateModel[] templateModel,
                TemplateDirectiveBody directiveBody) throws TemplateException, IOException {
            TemplateLoader templateLoader = environment.getConfiguration().getTemplateLoader();
    
            String fullTemplatePath = getFullTemplatePath(environment, params, PATH_PARAM);
            if (templateLoader.findTemplateSource(fullTemplatePath) != null) {
                environment.include(environment.getTemplateForInclusion(fullTemplatePath, null, true));
            } else {
                String defaultFullTemplatePath = getFullTemplatePath(environment, params, DEFALUT_PATH_PARAM);
                if (templateLoader.findTemplateSource(defaultFullTemplatePath) == null) {
                    throw new _MiscTemplateException(environment, "Missing template file path:" + defaultFullTemplatePath);
                }
                environment.include(environment.getTemplateForInclusion(defaultFullTemplatePath, null, true));
            }
        }
    
        /**
         * Description:获取ftl完整路径 <br>
         */
        private String getFullTemplatePath(Environment environment, @SuppressWarnings("rawtypes") Map params, String templatePath)
                throws MalformedTemplateNameException {
            if (!params.containsKey(templatePath)) {
                throw new MalformedTemplateNameException("missing required parameter '" + templatePath, "'");
            }
    
            String currentTemplateName = environment.getTemplate().getName();
            final String baseName = FilenameUtils.getPath(currentTemplateName);
    
            final String targetName = params.get(templatePath).toString();
            final String fullTemplatePath = environment.toFullTemplateName(baseName, targetName);
    
            return fullTemplatePath;
        }
    }
    

    FreeMarker 在这边就不详细讲了,官网讲的很清楚。我们给这个自定义的指令起个名字:includeX,然后就可以这样使用了:
    <@includeX template="/${province}.ftl" default_template="/default.ftl"/>

  • 相关阅读:
    Thinkphp3.2.3如何加载自定义函数库
    mysql 字段引号那个像单引号的撇号用法
    php cli模式学习(PHP命令行模式)
    Django model 表与表的关系
    Django model 字段详解
    Django model 中的字段解释
    python系列-1 字符串操作
    nginx-匹配规则
    ansible系列3-pyYAML
    ansible系列2-常用命令
  • 原文地址:https://www.cnblogs.com/litterbean-chen/p/5812982.html
Copyright © 2011-2022 走看看