依赖:
<!--beetl模板引擎-->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>2.9.3</version>
</dependency>
两种方式:
方式一:
代码属性实现
1、 配置 beetl需要的BeetlGroupUtilConfiguration和 BeetlSpringViewResolver
package com.chy.beetl.config;
import com.chy.beetl.config.properties.BeetlConfiguration;
import com.chy.beetl.config.properties.BeetlProperties;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.beetl.ext.spring.BeetlSpringViewResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* beetl配置类
* */
@Configuration
public class BeetlConf {
@Autowired
private BeetlProperties beetlProperties;
/**
* 代码实现配置
*/
@Bean(initMethod = "init",name = "beetlConfig")
public BeetlConfiguration getBeetlConfiguration() {
BeetlConfiguration beetlConfiguration = new BeetlConfiguration();
//获取Spring Boot 的ClassLoader
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(loader==null){
loader = BeetlConf.class.getClassLoader();
}
// 设置配置的属性(类方法中设置的属性)
beetlConfiguration.setConfigProperties(beetlProperties.getProperties());
ClasspathResourceLoader cploder = new ClasspathResourceLoader(loader,
beetlProperties.getPrefix());
beetlConfiguration.setResourceLoader(cploder);
return beetlConfiguration;
}
@Bean(name = "beetlViewResolver")
public BeetlSpringViewResolver getBeetlSpringViewResolver(@Qualifier("beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
// 解析后缀为.html页面
beetlSpringViewResolver.setSuffix(".html");
beetlSpringViewResolver.setOrder(0);
beetlSpringViewResolver.setConfig(beetlGroupUtilConfiguration);
return beetlSpringViewResolver;
}
}
2、BeetlConfiguration 继续BeetlGroupUtilConfiguration:
package com.chy.beetl.config.properties;
import com.chy.beetl.func.CurrentTimeUtil;
import com.chy.beetl.func.PrintTime;
import com.chy.beetl.func.SysDicSelectTag;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
/**
* beetl拓展配置,绑定一些工具类,方便在模板中直接调用
*
*/
public class BeetlConfiguration extends BeetlGroupUtilConfiguration {
public BeetlConfiguration(){}
// beetl自定义方法注册
@Override
protected void initOther() {
groupTemplate.registerFunction("printTime", new PrintTime());
groupTemplate.registerFunctionPackage("current", new CurrentTimeUtil());
groupTemplate.registerTag("dic_select", SysDicSelectTag.class);
}
}
3、BeetlProperties.java(属性类)
package com.chy.beetl.config.properties;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/**
* beetl配置(如果需要配置别的配置可参照这个形式自己添加)
*
*/
@Data
public class BeetlProperties {
public static final String BEETLCONF_PREFIX = "beetl";
/**
* ***.yml配置文件需要有如下配置:
* beetl:
* templatesPath: templates # 页面的根路径文件夹
* */
//@Value("${beetl.templatesPath}")
//private String prefix;//模板根目录 ,比如 "templates"
/**
* ***.yml配置文件需要有如下配置:
* spring:
* mvc:
* view:
* prefix: /templates # 页面的根路径文件夹
* */
@Value("${spring.mvc.view.prefix}")
private String prefix;
// 定界符开始符号
private String delimiterStatementStart="@";
// 定界符结束符号 - 结束符留空,或者=null 表示 是以回车作为结尾
private String delimiterStatementEnd;
// 文件Root目录
private String resourceTagroot;
// 文件后缀
private String resourceTagsuffix;
private String resourceAutoCheck;
// 自定义标签定界符,默认<#></#>
private String htmlTagFlag="tag:";
// 属性赋值
public Properties getProperties() {
Properties properties = new Properties();
if (ToolUtil.isNotEmpty(delimiterStatementStart)) {
if (delimiterStatementStart.startsWith("\\")) {
delimiterStatementStart = delimiterStatementStart.substring(1);
}
properties.setProperty("DELIMITER_STATEMENT_START", delimiterStatementStart);
}
if (ToolUtil.isNotEmpty(delimiterStatementEnd)) {
properties.setProperty("DELIMITER_STATEMENT_END", delimiterStatementEnd);
} else {
properties.setProperty("DELIMITER_STATEMENT_END", "null");
}
if (ToolUtil.isNotEmpty(resourceTagroot)) {
properties.setProperty("RESOURCE.tagRoot", resourceTagroot);
}
if (ToolUtil.isNotEmpty(resourceTagsuffix)) {
properties.setProperty("RESOURCE.tagSuffix", resourceTagsuffix);
}
if (ToolUtil.isNotEmpty(resourceAutoCheck)) {
properties.setProperty("RESOURCE.autoCheck", resourceAutoCheck);
}
if (ToolUtil.isNotEmpty(htmlTagFlag)) {
properties.setProperty("HTML_TAG_FLAG", htmlTagFlag);
}
return properties;
}
}
/**
* 判断对象为空工具
* */
class ToolUtil{
/**
* 对象是否不为空(新增)
*
*/
public static boolean isNotEmpty(Object o) {
return !isEmpty(o);
}
/**
* 对象是否为空
*
* @author fengshuonan
* @Date 2018/3/18 21:57
*/
private static boolean isEmpty(Object o) {
if (o == null) {
return true;
}
if (o instanceof String) {
if (o.toString().trim().equals("")) {
return true;
}
} else if (o instanceof List) {
if (((List) o).size() == 0) {
return true;
}
} else if (o instanceof Map) {
if (((Map) o).size() == 0) {
return true;
}
} else if (o instanceof Set) {
if (((Set) o).size() == 0) {
return true;
}
} else if (o instanceof Object[]) {
if (((Object[]) o).length == 0) {
return true;
}
} else if (o instanceof int[]) {
if (((int[]) o).length == 0) {
return true;
}
} else if (o instanceof long[]) {
if (((long[]) o).length == 0) {
return true;
}
}
return false;
}
}
4、实现BeetlProperties
package com.chy.beetl.config;
import com.chy.beetl.config.properties.BeetlProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 项目中的配置
*/
@Configuration
public class WebBeanConfig {
/**
* beetl模板的配置
*
*/
@Bean
@ConfigurationProperties(prefix = BeetlProperties.BEETLCONF_PREFIX)
public BeetlProperties beetlProperties() {
return new BeetlProperties();
}
}
方式二:
静态资源属性实现
1、配置 beetl需要的BeetlGroupUtilConfiguration和 BeetlSpringViewResolver
package com.chy.beetl.config;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.beetl.ext.spring.BeetlSpringViewResolver;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
/**
* beetl配置类(***.properties)
* */
//@Configuration
public class BeetlStaticConf {
/**
* ***.yml配置文件需要有如下配置:
* beetl:
* templatesPath: templates # 页面的根路径文件夹
* */
//@Value("${beetl.templatesPath}")
//private String prefix;//模板根目录 ,比如 "templates"
/**
* ***.yml配置文件需要有如下配置:
* spring:
* mvc:
* view:
* prefix: /templates # 页面的根路径文件夹
* */
@Value("${spring.mvc.view.prefix}")
private String prefix;
@Bean(initMethod = "init",name = "beetlConfig")
public BeetlGroupUtilConfiguration getBeetlGroupUtilConfiguration() {
BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();
//获取Spring Boot 的ClassLoader
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(loader==null){
loader = BeetlStaticConf.class.getClassLoader();
}
// 读取配置文件信息
ResourcePatternResolver patternResolver = ResourcePatternUtils
.getResourcePatternResolver(new DefaultResourceLoader());
beetlGroupUtilConfiguration.setConfigFileResource(patternResolver.getResource("classpath:beetl/beetl.properties"));
ClasspathResourceLoader cploder = new ClasspathResourceLoader(loader,
prefix);
beetlGroupUtilConfiguration.setResourceLoader(cploder);
beetlGroupUtilConfiguration.init();
//如果使用了优化编译器,涉及到字节码操作,需要添加ClassLoader
beetlGroupUtilConfiguration.getGroupTemplate().setClassLoader(loader);
return beetlGroupUtilConfiguration;
}
@Bean(name = "beetlViewResolver")
public BeetlSpringViewResolver getBeetlSpringViewResolver(@Qualifier("beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
// 解析后缀为.html页面
beetlSpringViewResolver.setSuffix(".html");
beetlSpringViewResolver.setOrder(0);
beetlSpringViewResolver.setConfig(beetlGroupUtilConfiguration);
return beetlSpringViewResolver;
}
}
2、 beetl.properties配置(resources文件夹下的beetl文件夹)
#默认配置
ENGINE=org.beetl.core.engine.DefaultTemplateEngine
#占位符使用:’${’ 和 ‘}’
DELIMITER_PLACEHOLDER_START=${
DELIMITER_PLACEHOLDER_END=}
#定界符开始符号’@‘
DELIMITER_STATEMENT_START=@
DELIMITER_STATEMENT_END=null
DIRECT_BYTE_OUTPUT=FALSE
HTML_TAG_SUPPORT=true
#自定义标签定界符号<#tag ></#tag>,默认<#></#>
HTML_TAG_FLAG=tag:
NATIVE_CALL=TRUE
TEMPLATE_CHARSET=UTF-8
ERROR_HANDLER=org.beetl.ext.web.WebErrorHandler
NATIVE_SECUARTY_MANAGER=org.beetl.core.DefaultNativeSecurityManager
#资源配置,resource后的属性只限于特定ResourceLoader
RESOURCE_LOADER=org.beetl.core.resource.ClasspathResourceLoader
MVC_STRICT=FALSE
#classpath 根路径
#RESOURCE.root= /
#是否检测文件变化,开发用true合适,但线上要改为false
RESOURCE.autoCheck=true
#自定义脚本方法文件的Root目录和后缀
RESOURCE.functionRoot=functions
RESOURCE.functionSuffix=fn
#自定义标签文件Root目录和后缀
RESOURCE.tagRoot=htmltag
RESOURCE.tagSuffix=tag
FN.date=org.beetl.ext.fn.DateFunction
FN.nvl=org.beetl.ext.fn.NVLFunction
FNP.strutil=org.beetl.ext.fn.StringUtil
FN.printTime=com.chy.beetl.func.PrintTime
FNP.current=com.chy.beetl.func.CurrentTimeUtil
TAG.htmltag=com.chy.beetl.func.SysDicSelectTag
后台代码:
package com.chy.beetl.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@Controller
public class IndexController {
/**
* 方式一
* */
@RequestMapping("/index")
public String index(HttpServletRequest request){
// 日期
try {
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = format.parse("2023-10-10 10:01:01");
request.setAttribute("createTime",date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
//标题
request.setAttribute("title","标题");
// 内容
request.setAttribute("content","内容");
// 输出安全值
request.setAttribute("secure",null);
// 数字
request.setAttribute("num",3);
// 普通数组
request.setAttribute("datas",getList());
// map数组
request.setAttribute("maps",getMapList());
return "index";
}
/**
* 方式二
* */
@RequestMapping("/model")
public String index(Model model){
model.addAttribute("title","model");
model.addAttribute("content","model内容");
model.addAttribute("datas",getList());
model.addAttribute("maps",getMapList());
return "model";
}
/**
* 方式三
* */
@RequestMapping("/modelView")
public ModelAndView index(ModelAndView modelAndView){
modelAndView.addObject("title","modelViewTitle");
modelAndView.addObject("content","modelView内容");
modelAndView.addObject("datas",getList());
modelAndView.addObject("maps",getMapList());
// 指定访问的html页面名称
modelAndView.setViewName("modelView");
return modelAndView;
}
/**
* 简单数组
* */
private List<String> getList(){
List<String> list = new ArrayList<>();
list.add("绿园区");
list.add("朝阳区");
list.add("南关区");
list.add("宽城区");
list.add("二道区");
list.add("经开区");
return list;
}
/**
* 简单数组
* */
private List<HashMap<String,Object>> getMapList(){
List<HashMap<String,Object>> list = new ArrayList<>();
HashMap<String,Object> map = new HashMap<>();
map.put("username","张三");
map.put("age","23");
map.put("like","足球,篮球,乒乓球");
list.add(map);
return list;
}
}
自定义类、方法和标签
CurrentTimeUtil.java
package com.chy.beetl.func;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 需要在静态资源或者类中注册
* 定义beetl使用的标签
* */
public class CurrentTimeUtil {
public CurrentTimeUtil(){}
/**
* @return yyyy-MM-dd HH:mm:ss
* */
public static String CurrentTime(){
SimpleDateFormat format=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
Date date = new Date();
String fmt = format.format(date);
return fmt;
}
}
NowTimeUtil.java
package com.chy.beetl.func;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 不需要注册
* 定义beetl可以使用的类和方法
* */
public class NowTimeUtil {
public static String NowTime(){
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String fmt = format.format(date);
return fmt;
}
}
PrintTime.java
package com.chy.beetl.func;
import org.beetl.core.Context;
import org.beetl.core.Function;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 需要在静态资源或者类中注册
* 定义beetl使用的类和方法
* */
public class PrintTime implements Function {
/**
* @param paras 模板传入的参数
* @param ctx 模板上下文
* */
@Override
public Object call(Object[] paras, Context ctx) {
String result = null;
// paras[0] 模板传递的日期
Date date = (Date) paras[0];
Long fiveM = date.getTime() + (5*60*1000);// 过了五分钟
Long thrityM = date.getTime() + (30*60*1000);// 过了三十分钟
Long oneH = date.getTime() + (60*60*1000);// 过了一个小时
// 获取当前时间
Date currentTime = new Date();
if (currentTime.getTime() <= fiveM){
result = "刚刚";
}else if (currentTime.getTime() <= thrityM){
result = "半小时前";
}else if (currentTime.getTime() <= oneH){
result = "一个小时前";
}else {
// paras[1] 模板传递的日期格式
SimpleDateFormat sdf = new SimpleDateFormat(paras[1].toString());
result = sdf.format(date);
}
return result;
}
}
标签SysDicSelectTag.java
package com.chy.beetl.func;
import lombok.Data;
import org.beetl.core.GeneralVarTagBinding;
import java.io.IOException;
import java.util.*;
/**
* 需要在静态资源或者类中注册
* 定义beetl使用的标签
* */
@Data
public class SysDicSelectTag extends GeneralVarTagBinding {
public String id;
public String name;
public String dicCode;
public String type;
public String skin;
public String onClick;
public String onChange;
public String headName;
public String headValue;
public String headType;
public String defaultValue;
public String disabled;
public String layVerify;
public String workFlowForm;
public String itemName;
public String exclude;
public void initAttr(){
Map<String, Object> attrs = this.getAttributes();
if(attrs.size()>0){
if(StringUtils.checkValNotNull(attrs.get("id"))){
this.setId(attrs.get("id").toString());
}
if(StringUtils.checkValNotNull(attrs.get("name"))){
this.setName(attrs.get("name").toString());
}
if(StringUtils.checkValNotNull(attrs.get("dicCode"))){
this.setDicCode(attrs.get("dicCode").toString());
}
if(StringUtils.checkValNotNull(attrs.get("type"))){
this.setType(attrs.get("type").toString());
}
if(StringUtils.checkValNotNull(attrs.get("skin"))){
this.setSkin(attrs.get("skin").toString());
}
if(StringUtils.checkValNotNull(attrs.get("onClick"))){
this.setOnClick(attrs.get("onClick").toString());
}
if(StringUtils.checkValNotNull(attrs.get("onChange"))){
this.setOnChange(attrs.get("onChange").toString());
}
if(StringUtils.checkValNotNull(attrs.get("headName"))){
this.setHeadName(attrs.get("headName").toString());
}
if(StringUtils.checkValNotNull(attrs.get("headValue"))){
this.setHeadValue(attrs.get("headValue").toString());
}
if(StringUtils.checkValNotNull(attrs.get("headType"))){
this.setHeadType(attrs.get("headType").toString());
}
if(StringUtils.checkValNotNull(attrs.get("defaultValue"))){
this.setDefaultValue(attrs.get("defaultValue").toString());
}
if(StringUtils.checkValNotNull(attrs.get("disabled"))){
this.setDisabled(attrs.get("disabled").toString());
}
if(StringUtils.checkValNotNull(attrs.get("layVerify"))){
this.setLayVerify(attrs.get("layVerify").toString());
}
if(StringUtils.checkValNotNull(attrs.get("workFlowForm"))){
this.setWorkFlowForm(attrs.get("workFlowForm").toString());
}
if(StringUtils.checkValNotNull(attrs.get("itemName"))){
this.setItemName(attrs.get("itemName").toString());
}
if(StringUtils.checkValNotNull(attrs.get("exclude"))){
this.setExclude(attrs.get("exclude").toString());
}
}
}
@Override
public void render() {
initAttr();
StringBuilder sb = new StringBuilder();
if (StringUtils.checkValNotNull(dicCode)) {
sb.append("<select name='" + this.getName() + "' id='" + this.getId() + "' ");
if (this.getOnChange() != null) {
sb.append(" lay-filter='").append(this.getOnChange()).append("' ");
}else {
sb.append(" lay-filter='").append(this.getName()).append("' ");
}
if (layVerify != null) {
sb.append(" lay-verify='").append(layVerify == null ? "" : layVerify).append("' ");
}
if (workFlowForm != null) {
sb.append(" workFlowForm='").append(workFlowForm == null ? "" : workFlowForm).append("' ");
}
if (itemName != null) {
sb.append(" itemName='").append(itemName == null ? "" : itemName).append("' ");
}
sb.append(" >");
if (headName != null) {
sb.append("<option value='").append(headValue == null ? "" : headValue).append("' selected>")
.append(headName).append("</option>");
}
if (headType != null) {
if ("1".equals(headType)) {
sb.append("<option value='").append(headValue == null ? "" : headValue).append("' selected>")
.append(" - 全部 - ").append("</option>");
}
if ("2".equals(headType)) {
sb.append("<option value='").append(headValue == null ? "" : headValue).append("' selected>")
.append(" - 请选择 - ").append("</option>");
}
if ("3".equals(headType)) {
sb.append("<option value='").append(headValue == null ? "" : headValue).append("' selected>")
.append(" - 无 - ").append("</option>");
}
}
List<Map<String,Object>> dictList = ArrayUtils.getSelList();
if (dictList != null && dictList.size()>0) {
Collections.sort(dictList, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> t0, Map<String, Object> t1) {
Object t00 = t0.get("sort");
int it0=0;
if(t00!=null){
if(t00 instanceof Integer){
it0 = (Integer)t00;
} else if(t00 instanceof String){
it0 = Integer.valueOf(t00.toString().trim());
}
}
Object t01 = t1.get("sort");
int it1=0;
if(t01!=null){
if(t01 instanceof Integer){
it1 = (Integer)t01;
} else if(t01 instanceof String){
it1 = Integer.valueOf(t01.toString().trim());
}
}
return it0 - it1;
}
});
String paramValue = this.getDefaultValue();
int index = 0;
String exclude = this.getExclude();
if (exclude == null) {
exclude = "";
}
String code;
String name;
for (Map<String,Object> option : dictList) {
code = option.get("code").toString();
name = option.get("name").toString();
if (exclude.indexOf(code) >= 0) {
continue;
}
sb.append("<option value='").append(code).append("'");
if (paramValue != null) {
if (paramValue.equals(code)) {
sb.append(" selected ");
}
} else {
if (index == 0 && headName == null && headType == null) {
sb.append(" selected ");
}
}
sb.append(">").append(name).append("</option>");
index++;
}
}
}
sb.append("</select>");
try {
this.ctx.byteWriter.writeString(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 集合数组
* */
class ArrayUtils {
public static List<Map<String,Object>> getSelList(){
List<Map<String,Object>> mapList = new ArrayList<>();
HashMap<String,Object> map1 = new HashMap<>();
map1.put("dictId","1");
map1.put("dictTypeId","1");
map1.put("sort","1");
map1.put("code","vue");
map1.put("name","VUE");
mapList.add(map1);
HashMap<String,Object> map2 = new HashMap<>();
map2.put("dictId","2");
map2.put("dictTypeId","2");
map2.put("sort","2");
map2.put("code","java");
map2.put("name","JAVA");
mapList.add(map2);
HashMap<String,Object> map3 = new HashMap<>();
map3.put("dictId","3");
map3.put("dictTypeId","3");
map3.put("sort","3");
map3.put("code","php");
map3.put("name","PHP");
mapList.add(map3);
return mapList;
}
}
/**
* 判断字符串是否为空
* */
class StringUtils{
/**
* 判断对象是否为空
*
* @param object ignore
* @return ignore
*/
public static boolean checkValNotNull(Object object) {
if (object instanceof CharSequence) {
return isNotBlank((CharSequence) object);
}
return object != null;
}
public static boolean isNotBlank(final CharSequence cs) {
return !isBlank(cs);
}
public static boolean isBlank(final CharSequence cs) {
if (cs == null) {
return true;
}
int l = cs.length();
if (l > 0) {
for (int i = 0; i < l; i++) {
if (!Character.isWhitespace(cs.charAt(i))) {
return false;
}
}
}
return true;
}
}
前端代码:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${title}</title>
</head>
<body>
<!--beetl自定义类和方法-->
<div>
<span>(自定义)发布时间:${printTime(createTime!,"yyyy-MM-dd HH:mm:ss")}</span><br/>
<span>(自定义)当前时间:${@com.chy.beetl.func.NowTimeUtil.NowTime()}</span><br/>
<span>(自定义)当前时间:${current.CurrentTime()}</span><br/>
<div>
<tag:dic_select id="postType" name="postType" type="select" dicCode="postType" headName="-请选择岗位性质-" ></tag:dic_select>
</div>
</div>
<!--beetl模板layout布局-->
@layout("/header.html",{content:"页面头"}){
<div>页面布局111</div>
@}
<!-- beetl模板引入其他页面作为一部分 -->
@include("/part.html",{part_content:"include引入的页面","part_one":"N","part_two":"Y"}){}
<!--beetl模板赋值-->
<h2>${content}</h2>
<!--
beetl模板安全输出
变量后面加一个感叹号标识安全输出,占位符,定界符都可以使用,感叹号后面可以写默认值
-->
<h3>安全输出</h3>
<div>${secure!"测试"}</div>
<!--
#beetl模板循环(简单数组)
#因为重新设置了定位符
# 默认定位符:<% * %>,现在定位符:@
-->
<h3>简单循环</h3>
@for(item in datas){
<span>${item} </span>
@}
<!--beetl模板循环(HashMap数组)-->
<h3>HashMap数组循环</h3>
@for(idx in maps){
<div>姓名:${idx.username}</div>
<div>年龄:${idx.age}</div>
<div>
喜好:${idx.like}
</div>
@}
<!--beetl模板内置函数与if else-->
<!--<h3>内置函数与if else</h3>
<%
if(isNotEmpty(num) && num >= 5){
%>
<div>num:${num}</div>
<% } %>
<%else{%>
<div>num:为空或者小于5</div>
<% } %>-->
<h3>内置函数与if else</h3>
@if(isNotEmpty(num) && num >= 5){
<div>num:${num}</div>
@}
@else{
<div>num:为空或者小于5</div>
@}
</body>
</html>
header.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Header</title>
</head>
<body>
<div style="height: 200px;width: 100%;background: aqua">
<h1>${content!}</h1>
</div>
</body>
</html>
part.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Header</title>
</head>
<body>
<table style="height: 200px;width: 100%;background: brown">
<tr>
<h3>${part_content}</h3>
</tr>
<!--默认显示该行,不需要显示时,需要引入时设置part_one为"N" - 例如:index.html-->
@if(part_one! != "N"){
<tr>
<td></td>
<td></td>
<td>
<div>第一个part</div>
</td>
</tr>
@}
<!--默认不显示该行,需要引入的时设置part_two为"Y" - 例如:index.html-->
@if(part_two! == "Y"){
<tr>
<td></td>
<td></td>
<td>
<div>第二个part</div>
</td>
</tr>
@}
</table>
</body>
</html>
model.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${title}</title>
</head>
<body>
<h1>hello,world!</h1> <br/>
<!--beetl模板取值-->
<h2>${content}</h2>
<!--beetl模板循环(简单数组)-->
<%
for(item in datas){
%>
<div>${item}</div><br/>
<% } %>
<!--beetl模板循环(HashMap数组)-->
<%
for(idx in maps){
%>
<div>姓名:${idx.username}</div>
<div>年龄:${idx.age}</div>
<div>
喜好:${idx.like}
</div>
<% } %>
</body>
</html>
modelView.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${title}</title>
</head>
<body>
<h1>hello,world!</h1> <br/>
<!--beetl模板取值-->
<h2>${content}</h2>
<!--beetl模板循环(简单数组)-->
<%
for(item in datas){
%>
<div>${item}</div><br/>
<% } %>
<!--beetl模板循环(HashMap数组)-->
<%
for(idx in maps){
%>
<div>姓名:${idx.username}</div>
<div>年龄:${idx.age}</div>
<div>
喜好:${idx.like}
</div>
<% } %>
</body>
</html>