By default, Beetl's html tags do not support parent-child nesting. Just like jsp tags, the parent tag needs to know the information of the child tag, and the child tag also needs to know the information of the parent tag. But beetl only needs a simple extension to support nested tags.
First, let’s take a look at the final usage effect. Implement two html tags table.tag and tr.tag. They can be used like this on the page:
<#table data ="${userList}"><#tr class="3c" name="name"> 名称 </#tr></#table>
public class HTMLNestTagSupportWrapper extends HTMLTagSupportWrapper{public void render(){....}}
public class TagNestContext {private Tag tag = null;private TagNestContext parent = null;private List<TagNestContext> children = null;public Tag getTag() { return tag;}public void setTag(Tag para) { this.tag = para;}public TagNestContext getParent() { return parent;}public void setParent(TagNestContext parent) { this.parent = parent;}public List<TagNestContext> getChildren() { if(children==null) children = new ArrayList<TagNestContext>(); return children;}public void setChildren(List<TagNestContext> children) { this.children = children;}}
public void render(){ HttpServletRequest request = (HttpServletRequest)this.ctx.getGlobal("request"); TagNestContext tnc = (TagNestContext)request.getAttribute("tagContext"); if(tnc==null){ tnc = new TagNestContext(); tnc.setTag(this); request.setAttribute("tagContext", tnc); super.render(); request.removeAttribute("tagContext"); }else{ TagNestContext child = new TagNestContext(); child.setParent(tnc); child.setTag(this); tnc.getChildren().add(child); request.setAttribute("tagContext", child); super.render(); //重新设置 request.setAttribute("tagContext", child.getParent()); }}public String getTagName(){ return (String)this.args[0];}public Object get(String attr){ Map map = (Map)this.args[1]; return map.get(attr);}
<tr class="${class}">${tagBody}</tr>
<table>${tagBody}<% for(var item in data){%><tr><%var tag = getTagContext();var children = tag.children;for(var tdTagCtx in children){ print("<td>"); var tdTag = tdTagCtx.tag; var name = tdTag.tagName; var value = item[name]; print(value); println("</td>");}%></tr><%} %></table>