原创

freemarker自定义标签

写在前面

上节课程主要讲了在springboot上集成freemaker,本文主要介绍freemarker如何自定义标签,自定义标签的好处,可以在页面上实现复用。不多说废话,直接进入今天的主题

后台代码实现

/** * MIT License * Copyright (c) 2018 haihua.liu * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package cn.liuhaihua.web.tag; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import cn.liuhaihua.web.service.WpTermsService; import freemarker.core.Environment; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapperBuilder; import freemarker.template.TemplateDirectiveBody; import freemarker.template.TemplateDirectiveModel; import freemarker.template.TemplateException; import freemarker.template.TemplateModel; @Component public class CustomTagDirective implements TemplateDirectiveModel { private static final String METHOD_KEY = "method"; @Autowired private WpTermsService wpTermsService; @Override public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException { DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25); if (map.containsKey(METHOD_KEY)) { String method = map.get(METHOD_KEY).toString(); int pageSize = 10; if (map.containsKey("pageSize")) { String pageSizeStr = map.get("pageSize").toString(); pageSize = Integer.parseInt(pageSizeStr); } switch (method) { case "navigate": environment.setVariable("navigate", builder.build().wrap(wpTermsService.getNavigate())); break; case "tagsList": // 所有标签 environment.setVariable("tagsList", builder.build().wrap("")); break; case "parentResources": // 所有父级资源 environment.setVariable("parentResources", builder.build().wrap("")); break; case "recentComments": // 近期评论 environment.setVariable("recentComments", builder.build().wrap("")); break; case "siteInfo": // 站点属性 environment.setVariable("siteInfo", builder.build().wrap("")); break; case "menus": Integer userId = null; if (map.containsKey("userId")) { String userIdStr = map.get("userId").toString(); if(StringUtils.isEmpty(userIdStr)){ return; } userId = Integer.parseInt(userIdStr); } Map<String, Object> params = new HashMap<>(2); params.put("type", "menu"); params.put("userId", userId); environment.setVariable("menus", builder.build().wrap("")); break; default: break; } } templateDirectiveBody.render(environment.getOut()); } }
在freemaker中定义标签
@PostConstruct public void setSharedVariable(){ resolver.setSuffix(".ftl"); resolver.setCache(false); resolver.setRequestContextAttribute("request"); //为模板调用时,调用request对象的变量名</span> resolver.setOrder(0); resolver.setExposeRequestAttributes(true); resolver.setExposeSessionAttributes(true); try { //自定义标签 configuration.setSharedVariable("customTag", customTagDirective); } catch (Exception e) { e.printStackTrace(); } }

前端代码

<@customTag method="navigate"> <#if navigate?? && navigate?size gt 0> <#list navigate as item> <#if item.child?exists && item.child?size gt 0> <li class="dropdown"> <a href="#" class="dropdown-toggle menu_a" data-toggle="dropdown" aria-expanded="false"> <i class="${item.icon?if_exists}"></i>${item.name?if_exists} <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <#list item.child as node> <li><a href="/type/${node.termId?if_exists}" title="点击查看《${node.name?if_exists}》的文章">${node.name?if_exists}</a></li> </#list> </ul> </li> <#else> <li><a href="/type/${item.termId?if_exists}" class="menu_a"><i class="${item.icon?if_exists}"></i>${item.name?if_exists}</a></li> </#if> </#list> </#if> </@customTag>
最后效果是实现将目录展现在头部导航栏,并且实现父子目录展示
正文到此结束
Loading...