在Beetl页面中可以使用自定义的函数从后台新闻列表中获取新闻数据展示到页面上。例如我们可以从后台新闻表中获取新闻按照下面的格式展示:
<li><a href="#">东亚非遗展即将盛妆亮相 揭起盖头先睹为快</a></li><li><a href="#">上海之春国际音乐节启幕在即 凸显“一带一路”时代主题</a></li>
使用Beetl自定义函数时,我们需要在后台实现一个类,继承Beetl的Function,见下面的代码:
package org.openjweb.core.service;import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONArray;
import lombok.extern.slf4j.Slf4j;
import org.beetl.core.Context;
import org.beetl.core.Function;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Component
@Slf4j
public class BeetlService implements Function {public List<Map<String,Object>> getCateInfoListDemo(String treeCode ){List<Map<String,Object>> list = new ArrayList<>();Map<String,Object> map = new HashMap<>();map.put("infTitle","国庆节来了"+treeCode);map.put("infUrl","http://www.sohu.com");map.put("Image","");list.add(map);map = new HashMap<>();map.put("infTitle","2025年春节放假通知"+treeCode);map.put("infUrl","http://www.sohu.com");map.put("Image","");list.add(map);return list;}@Overridepublic Object call(Object[] objects, Context context) {if(objects.length>1){log.info("第二个参数pageNo:"+String.valueOf(objects[1]));}if(objects.length>2){log.info("第三个参数pageSize:"+String.valueOf(objects[2]));}if(1==2) {return this.getCateInfoListDemo((String )objects[0]);}else {log.info("传入的栏目编码为:::::");log.info(String.valueOf(objects[0]));return this.getCateInfoList((String) objects[0], 1, 10);}}public Object getCateInfoList(String treeCode ,int pageNo,int pageSize){HttpRequest request = HttpRequest.get("http://localhost:8001/api/cms/pub/getCateInfoList?treeCode="+treeCode+"&pageNo="+pageNo+"&pageSize="+pageSize);HttpResponse response = request.execute();String result = response.body();log.info("请求返回的内容:");log.info(result);return JSONArray.parseArray(result) ;}}
在上面的代码中,call方法接收Beetl网页前端传入的参数,参数分别是栏目编码、页面、每页行数,然后调用this.getCateInfoListDemo((String )objects[0]); 这个是个简单的示例,封装了2条Map数据返回给前端页面。
另外需要在以前的BeetlConf中注册函数,我们就把BeetlService类作为一个函数,下面是BeetlConf的代码:
package org.openjweb.core.config;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.core.resource.FileResourceLoader;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.beetl.ext.spring.BeetlSpringViewResolver;
import org.openjweb.core.service.BeetlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.WebApplicationContext;@Configuration
@Slf4j
public class BeetlConf {@Autowiredprivate WebApplicationContext wac;//@Value("${beetl.templatesPath}") String templatesPath;//模板根目录 ,比如 "templates"String templatesPath = "templates";//这个给类定义使用的@Value("${beetl.fileTemplatesPath:}") String fileTemplatesPath;//模板根目录 ,比如 "templates"String templateFilePath = "";@Bean(name = "beetlConfig")public BeetlGroupUtilConfiguration getBeetlGroupUtilConfiguration() {BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();//获取Spring Boot 的ClassLoaderClassLoader loader = Thread.currentThread().getContextClassLoader();if(loader==null){loader = BeetlConf.class.getClassLoader();}//log.info("当前指定的Beetl模板文件路径:"+String.valueOf(fileTemplatesPath));//beetlGroupUtilConfiguration.setConfigProperties(extProperties);//额外的配置,可以覆盖默认配置,一般不需要if(StringUtils.isNotEmpty(fileTemplatesPath)){log.info("使用文件模版路径...........");FileResourceLoader floader = new FileResourceLoader(fileTemplatesPath);beetlGroupUtilConfiguration.setResourceLoader(floader);}else{log.info("使用类模版路径...........");ClasspathResourceLoader cploder = new ClasspathResourceLoader(loader, templatesPath);beetlGroupUtilConfiguration.setResourceLoader(cploder);}beetlGroupUtilConfiguration.init();//如果使用了优化编译器,涉及到字节码操作,需要添加ClassLoaderbeetlGroupUtilConfiguration.getGroupTemplate().setClassLoader(loader);//注册国际化函数beetlGroupUtilConfiguration.getGroupTemplate().registerFunction("i18n", new I18nFunction(wac));//注册cms相关的方法beetlGroupUtilConfiguration.getGroupTemplate().registerFunction("cmsUtil",new BeetlService());return beetlGroupUtilConfiguration;}@Bean(name = "beetlViewResolver")public BeetlSpringViewResolver getBeetlSpringViewResolver(@Qualifier("beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");beetlSpringViewResolver.setOrder(0);beetlSpringViewResolver.setConfig(beetlGroupUtilConfiguration);return beetlSpringViewResolver;}}
注意在上面的代码中,将BeetlService注册为一个名为cmsUtil 的函数:
beetlGroupUtilConfiguration.getGroupTemplate().registerFunction("cmsUtil",new BeetlService());
然后在前端页面(D:\tmp\beetl\templates\cms\site\wenhua\china.html)中,使用下面的代码来调用后台BeetlService函数(此函数传入3个参数,在后台的call方法中通过Object[]参数接收):
<%for(item in cmsUtil("001001",1,10)){
%><li><a href="${item.infUrl}">${item.infTitle}</a></li>
<% }
%>
测试: http://localhost:8001/front/china
显示效果,在界面上显示了BeetlService中的演示数据:
另外如果调用后台新闻表cms_info的新闻,在BeetlService中使用了
public Object getCateInfoList(String treeCode ,int pageNo,int pageSize){HttpRequest request = HttpRequest.get("http://localhost:8001/api/cms/pub/getCateInfoList?treeCode="+treeCode+"&pageNo="+pageNo+"&pageSize="+pageSize);HttpResponse response = request.execute();String result = response.body();log.info("请求返回的内容:");log.info(result);return JSONArray.parseArray(result) ;}
因为在OpenJweb工程中,openjweb-cms内容管理模块是依赖openjweb-core模块,所以在openjweb-core模块里的BeetlService中,如果调用CMS的API方法,不能直接引用openjweb-cms的Service类,只能通过Http的方式调用openjweb-cms里的API接口(/api/cms/pub/getCateInfoList
),这里通过Hutool进行了get调用。下面是CmsInfoV3Api的获取栏目信息接口代码:
package org.openjweb.cms.api;import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.openjweb.cms.entity.CmsInfo;
import org.openjweb.cms.module.params.CmsInfoParam;
import org.openjweb.cms.service.CmsInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@Api(tags = "内容管理V3")
@Slf4j
@RestController
@RequestMapping("/api/cms/pub")
public class CmsInfoV3Api {@Autowiredprivate CmsInfoService cmsInfoService;@RequestMapping("/getCateInfoList")public List<CmsInfo> getCateCmsInfo(String treeCode, int pageNo, int pageSize){log.info("getCateInfoList传入的参数:");log.info(treeCode);log.info(String.valueOf(pageNo));log.info(String.valueOf(pageSize));CmsInfoParam param = new CmsInfoParam();param.setPage(pageNo);param.setPageSize(pageSize);param.setCateTreeCode(treeCode);List<CmsInfo> list = this.cmsInfoService.queryList(param);if(list!=null&&list.size()>0){//${myService.sayHello('World')}log.info("查询到栏目的信息......");}else{log.info("没查到栏目下的信息.....");}return list;//List<CmsInfo> cmsInfo}
}
在SpringSecurity中,配置/api/cms/pub为免登录可以访问。我们在BeetlService中改为调用这个接口:
if(1==2) {return this.getCateInfoListDemo((String )objects[0]);
}
else {log.info("传入的栏目编码为:::::");log.info(String.valueOf(objects[0]));return this.getCateInfoList((String) objects[0], 1, 10);
}
上面的代码调用this.getCateInfoList,然后重新运行SpringBoot,访问http://localhost:8001/front/china:
上面是从cms_info表获取的新闻列表的标题。