1. 程式人生 > >FreeMarker(五)巨集和函式的定義

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程式碼中函式

具體看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>