## 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的變量值
- Beetl 3 中文文檔
- 第一部分 基礎用法
- 1.1 安裝
- 1.2 快速開始
- 1.3 模板基礎配置
- 1.4 模板加載器
- 1.5 定界符與占位符
- 1.6 注釋
- 1.7 變量定義
- 1.8 屬性
- 1.9 數學表達式
- 1.10 循環語句
- 1.11 條件語句
- 1.12 異常捕獲
- 1.13 虛擬屬性
- 1.14 函數調用
- 1.15 安全輸出(重要)
- 1.16 輸出格式化
- 1.17 標簽
- 1.18 調用Java方法與屬性
- 1.19 嚴格MVC控制
- 1.20 指令
- 1.21 錯誤處理
- 1.22 Beetl小工具
- 1.23 Escape
- 第二部分 高級用法
- 2.1 配置GroupTemplate
- 2.2 自定義方法
- 2.3 自定義格式化函數
- 2.4 自定義標簽
- 2.5 自定義虛擬屬性
- 2.6 使用額外的資源加載器
- 2.7 自定義資源加載器
- 2.8 使用CompositeResourceLoader
- 2.9 自定義錯誤處理器
- 2.10 自定義安全管理器
- 2.11 注冊全局共享變量
- 2.12 自定義布局
- 2.13 性能優化
- 2.14 定制輸出
- 2.15 定制模板引擎
- 2.16 直接運行Beetl腳本
- 2.17 模板校驗
- 第三部分 Web 集成
- 3.1 Web提供的全局變量
- 3.2 集成技術開發指南
- 3.3 Servlet集成
- 3.4 SpringMVC集成
- 3.5 Spring Boot集成
- 3.6 Jodd集成
- 3.7 JFinal4 集成方案
- 3.8 Nutz集成
- 3.9 Struts2集成
- 3.10 整合ajax的局部渲染技術
- 3.11 在頁面輸出錯誤提示信息
- 附錄
- 4.1 內置方法
- 4.2 Spring相關函數
- 4.3 Spring security
- 4.4 shiro
- 4.5 內置格式化方法
- 4.6 內置標簽函數
- 4.7 內置html標簽
- 4.8 性能優化
- 4.9 Eclipse 插件
- 4.10 性能測試對比