FreeMarker(五)宏和函数的定义

宏和函数的异同:

宏指的是<#macro>,函数指的是<#function>,都允许设置参数,内部可以包含流程控制语句。

区别如下:

  • 宏内部的Html代码会直接显示在页面上,更适合用来封装一些页面组件,宏不允许有返回值,如果设置返回值,将直接报错。
  • 函数用来写一些仅用于计算的代码块,内部即便写了Html代码,页面也是不会显示的,函数可以有返回值。

宏的定义和使用

如下列代码所示:
string的默认值是”“,marquee的默认值是false
通过<@>标签使用宏,参数设值和一般的Html标签类似

<#--定义宏-->
<#macro TextView string="" color="silver" marquee=false>
    <#if marquee>
        <marquee behavior="alternate" width="300" style="color: ${color}">${string}</marquee>
    <#else>
        <font style="color: ${color}">${string}</font>
        </#if>
    <br/>
    <#--宏不可有返回值,但是可以提前结束,如果强行设置返回值,将报错:A macro cannot return a value-->
        <#return>
</#macro>

<#--使用宏-->
<@TextView string="test"/>
<@TextView string="test" color = "red"/>
<@TextView color = "green" string="test" marquee = true/>

函数的定义和使用

<#function Add a b>
    <#--函数就算写了其它页面代码也不会显示-->
    <font>asdadadad</font>
    <#assign sum = a+b>
    <#return sum/>
</#function>
${Add(1, 2)}

在Java代码中函数

在页面调用Java代码,需要做额外配置,具体看SpringMVC的Xml配置文件

@Controller
public class MController {

    @RequestMapping("test/temp")
    public void ftlTest1(Model model) {
        //注入一个Java对象
        model.addAttribute("util", new Test());
        model.addAttribute("map", new HashMap());
    }
}
    //页面调用Java中的函数
    ${map.size()}
    ${map.getClass()}
    ${util.pr("aa")}

在Java代码中定义宏

感觉没必要在Java代码中设计,实在有些麻烦了。

Java类

package com.css.ftl.plus;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Map;
import java.util.Map.Entry;

import freemarker.core.Environment;
import freemarker.template.ObjectWrapper;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateNumberModel;
import freemarker.template.TemplateScalarModel;

public class IP implements TemplateDirectiveModel {
    /**
     * 
     * @param 传入的参数,params类型为Map<String,
     * TemplateModel>,由于历史原因没用泛型。比如传入参数“count=5”,String为count,TemplateModel为5
     * 
     * @loopVars 循环变量
     * 
     * @see freemarker.template.TemplateDirectiveModel#execute(freemarker.core.
     * Environment, java.util.Map, freemarker.template.TemplateModel[],
     * freemarker.template.TemplateDirectiveBody)
     */
    @Override
    @SuppressWarnings("deprecation")
    public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars,
            TemplateDirectiveBody body) throws TemplateException, IOException {
        @SuppressWarnings("unchecked")
        Map<String, TemplateModel> models = params;
        for (Entry<String, TemplateModel> entry : models.entrySet()) {
            if (entry.getKey().equalsIgnoreCase("count")) {
                TemplateNumberModel model = (TemplateNumberModel) entry.getValue();
                System.out.println(model);
                //TODO:int类型参数的相关处理
            }
            if (entry.getKey().equalsIgnoreCase("exclude")) {
                TemplateScalarModel model = (TemplateScalarModel) entry.getValue();
                System.out.println(model);
                //TODO:string类型参数的相关处理
            }
        }
        InetAddress address = InetAddress.getLocalHost();
        env.setVariable("rest", ObjectWrapper.BEANS_WRAPPER.wrap(address.getHostAddress()));
        if (body != null) {
            body.render(env.getOut());
        }
    }
}

SpringMVC配置文件

    <!--FreeMarker配置 -->
    <bean
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="order" value="1"></property>
        <property name="suffix" value=".ftl"></property>
        <property name="contentType" value="text/html;charset=utf-8"></property>
        <property name="viewClass">
            <value>org.springframework.web.servlet.view.freemarker.FreeMarkerView
            </value>
        </property>
    </bean>

    <!-- 以代码的方式自定义宏 -->
    <bean id="IP" class="com.css.ftl.plus.IP"/>

    <bean id="freemarkerConfig"
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <!-- 以代码的方式自定义宏 -->
        <property name="freemarkerVariables">
            <map>
                <entry key="IP" value-ref="IP"/>
            </map>
        </property> 
        <property name="templateLoaderPath">
            <value>/WEB-INF/ftl/</value>
        </property>
        <!-- 设置FreeMarker环境属性 -->
        <property name="freemarkerSettings">
            <props>
                <prop key="object_wrapper">freemarker.ext.beans.BeansWrapper</prop>
                <prop key="locale">zh_CN</prop><!--设置地区:中国 -->
                <prop key="template_update_delay">5</prop><!--刷新模板的周期,单位为秒 -->
                <prop key="default_encoding">UTF-8</prop><!--模板的编码格式 -->
                <prop key="locale">UTF-8</prop><!--本地化设置 -->
                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                <prop key="date_format">yyyy-MM-dd</prop>
                <prop key="time_format">HH:mm:ss</prop>
                <prop key="number_format">0.####</prop>
                <prop key="boolean_format">1,0</prop><!--Boolean类型默认true,false,但页面不支持默认设置-->
                <prop key="whitespace_stripping">true</prop>
                <prop key="tag_syntax">auto_detect</prop>
                <prop key="url_escaping_charset">UTF-8</prop>
            </props>
        </property>
    </bean>

页面调用

<@IP>
    本机的IP地址是:${rest}
</@IP>

posted on 2017-10-18 23:12  疯狂的妞妞  阅读(516)  评论(0编辑  收藏  举报

导航