FreeMarker(五)宏和函数的定义

x33g5p2x  于2021-12-24 转载在 其他  
字(5.3k)|赞(0)|评价(0)|浏览(305)

宏和函数的异同:

宏指的是<#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>

相关文章