ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 1.17 标签 [TOC] ### 1.17.1 标签函数 所谓标签函数,即允许处理模板文件里的一块内容,功能等于同jsp tag。如Beetl内置的layout标签 index.html ```javascript <% layout("/inc/layout.html",{title:'主题'}){ %> Hello,this is main part <% } %> ``` layout.html ```javascript title is ${title} body content ${layoutContent} footer ``` 第1行变量title来自于layout标签函数的参数 第2行layoutContent 是layout标签体{}渲染后的结果 关于layout标签,参考高级主题布局 Beetl内置了另外一个标签是include,允许 include 另外一个模板文件 ```javascript <% include("/inc/header.html"){} %> ``` 在标签中,{} 内容将依据标签的实现而执行,layout标签将执行{}中的内容,而include标签则忽略标签体内容。 关于如何实现标签函数,请参考高级主题,如下是一个简单的的标签函数: ```java public class CompressTag extends Tag{ @Override public void render(){ BodyContent content = getBodyContent(); String content = content.getBody(); String zip = compress(conent); ctx.byteWriter.write(zip); } } ``` include, includeUrl,includeJSP,还有includeFragment(包含模板中的某一部分)都是Beetl提供的include系列标签函数,includeUrl,includeJSP考虑到需要WEB环境,并没有内置,需要手工注册,参考IncludeJSPTag.java,IncludeUrlTag.java ### 1.17.2 HTML标签 Beetl 也支持HTML tag形式的标签(但实质还是标签函数), 区分beetl的html tag 与 标准html tag。如设定`HTML_TAG_FLAG=#`,则如下html tag将被beetl解析 ```xml <#footer style=”simple”/> <#richeditor id=”rid” path="${ctxPath}/upload" name=”rname” maxlength=”${maxlength}”> ${html} …其他模板内容 </#richdeitor> <#html:input id=’aaaa’ /> ``` 也可以设置别的符号,比如`HTML_TAG_FLAG=my:`,那么如上标签则应该写成 ```java <my:footer style=”simple”/> <my:richeditor id=”rid” path="${ctxPath}/upload" name=”rname” maxlength=”${maxlength}”> ${html} …其他模板内容 </my:richdeitor> <my:html:input id=’aaaa’ /> ``` 如对于标签footer,Beetl默认会寻找WebRoot/htmltag/footer.tag(可以通过配置文件修改路径和后缀) ,内容如下: ```javascript <% if(style==’simple’){ %> 请联系我 ${session.user.name} <% }else{ %> 请联系我 ${session.user.name},phone:${session.user.phone} <% } %> ``` 如下还包含了自定义html标签一些规则 - 可以在自定义标签里引用标签体的内容,标签体可以是普通文本,beetl模板,以及嵌套的自定义标签等。如上<#richeditor 标签体里,可用“tagBody”来引用 - HTML自定义标签 的属性值均为字符串 如<#input value="123" />,在input.tag文件里 变量value的类型是字符串 - 可以在属性标签里引用beetl变量,如<#input value="${user.age}" />,此时在input.tag里,value的类型取决于user.age - 在属性里引用beetl变量,不支持格式化,如<#input value="${user.date,'yyyy-MM-dd'}"/>,如果需要格式化,需要在input.tag文件里自行格式化 - 在标签属性里传json变量需要谨慎,因为json包含了"}",容易与占位符混合导致解析出错,因此得使用"\\"符号,如<#input value="${ {*age*:25\\} }" /> - html tag 属性名将作为 其对应模板的变量名。如果属性名包含“-”,则将转为驼峰命名的变量,如data-name,转为dataName,这个是通过AttributeNameConvert类实现的,也可以实现其他转化规则 - 默认机制下,HTMLTagSupportWrapper2 实现了标签(2.8.x以前使用HTMLTagSupportWrapper) - 标签属性带有"-“符号,会自动去掉,后面的字母大写,以符合变量命名规范 - 所有的标签属性都保存在"$cols" 变量里,这是一个map,key为属性转化后的变量名,value是属性名(参考下面例子) 如果采用模板来写html标签功能不够强大,beetl支持写标签函数(参考上一节)来实现html标签,标签函数args[0]表示标签名,这通常没有什么用处,args[1] 则是标签的属性,参数是个map,key是html tag的属性,value是其属性值,如下用java完成的html 标签用于输出属性值 ```java public class SimpleHtmlTag extends Tag{ @Override public void render(){ String tagName = (String) this.args[0]; Map attrs = (Map) args[1]; String value = (String) attrs.get("attr"); //Map allColsDefine = (map)attrs.get("$cols"); try{ this.ctx.byteWriter.writeString(value); }catch (IOException e){ } } } ``` 如果注册gt.registerTag("simpleTag", SimpleHtmlTag.class); 则如下模板输出了attr属性值abc ```xml <#simpleTag attr="abc"></#simpleTag> ``` > HTML_TAG_FLAG默认为#用来区别是否是beetl的html tag,你也可以设置成其他符号,比如 "my:",这样,\<my:table\>\</my:table\> 其实是一个指向table.tag的标签实现 Beetl默认标签并不包含父子关系,如果想在标签传递参数,可以使用pageCtx函数 ~~~html <#form> <#input name="user"></#input> </#form> ~~~ form标签实现如下 ~~~html <% var a = pageCtx("formParas",{"user":"abc"}); %> <form> ${tagBody} </form> ~~~ input标签可以获取formParas参数 ~~~html <% var all = pageCtx("formParas"); var value = all[name]; %> <input name="${name}" value=${value} /> ~~~ ### 1.17.3 绑定变量的HTML标签 对于html标签(参考上一节),Beetl还 支持将标签实现类(java代码)里的对象作为临时变量,被标签体引用。此时需要实现GeneralVarTagBinding (此类是Tag的子类) 该类提供另外3个方法 - void binds(Object… array) 子类在render方法里调用此类以实现变量绑定,绑定顺序同在模板中声明的顺序 - void bind(String name, Object value) 子类在render方法里调用此类以实现变量绑定,name是模板中声明的变量名,用此方法绑定不如binds更灵活,不再推荐 - Object getAttributeValue 获得标签的属性 - Map getAttributes 获得标签的所有属性 ```java public class TagSample extends GeneralVarTagBinding{ @Override public void render(){ int limit = Integer.parseInt((String) this.getAttributeValue("limit")); for (int i = 0; i < limit; i++){ this.binds(i) this.doBodyRender(); } } } //在某处注册一下标签TagSample //gt.registerTag("tag", TagSample.class); ``` 如上例子,render方法将循环渲染标签体limit次,且每次都将value赋值为i。我们再看看模板如何写的 ```xml <#tag limit="3" var="value"> ${value} </#tag> ``` 类似于常规html标签,增加了一个var属性(可以通过配置文件改成其他属性名)。,后跟上要绑定的变量列表,如上例只绑定了一个value变量,如果需要绑定多个变量,则用逗号分开,如var1,var2 上 注意,由于标签使用因为太长可能换行或者是文本格式化导致换行,目前beetl只允许在属性之间换行,否则,将报标签解析错误。 通过var定义的变量只能在标签体中使用,如果想定义一个能在标签体外能使用的变量,需要使用export ~~~java <#define limit="3" expor="value"/> ${value} ~~~ 如果想要在整个模板都使用,可以使用$export ~~~java <% if(true){ %> <#define limit="3" $export="value"/> <% } %> ${value} ~~~ > var 和 export 这个属性名代表了特殊意义,用于申明变量。也可以通过配置使用其他属性名字 > > ``` > HTML_TAG_BINDING_ATTRIBUTE = var,export > ``` 同时export并不会导致错误,后面的export会覆盖前面export的变量值