通常網頁至少會將版型切割為4個區塊, 例如下圖:
<tiles-definitions>
<definition name="indexTemplate" template="/WEB-INF/views/tiles/indexTemplate.jsp">
<put-attribute name="title" value="Welcome" />
<put-attribute name="header" value="/WEB-INF/views/tiles/header.jsp" />
<put-attribute name="category" value="/WEB-INF/views/tiles/category.jsp" />
<put-attribute name="browse" value="/WEB-INF/views/tiles/browse.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/tiles/footer.jsp" />
</definition>
</tiles-definitions>
<definition name="indexTemplate" template="/WEB-INF/views/tiles/indexTemplate.jsp">
<put-attribute name="title" value="Welcome" />
<put-attribute name="header" value="/WEB-INF/views/tiles/header.jsp" />
<put-attribute name="category" value="/WEB-INF/views/tiles/category.jsp" />
<put-attribute name="browse" value="/WEB-INF/views/tiles/browse.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/tiles/footer.jsp" />
</definition>
</tiles-definitions>
而頁面變更的時候, 通常都只是更換整頁中的某一個區塊, 其它區塊不需要變化.
例如登入時, 只需要將右邊的區塊變更為登入頁.
登入頁 tiles 的設定如下, 只要更換 title 及 browse 二個變數的定義即可.
<!-- Login Page -->
<definition name="login" extends="indexTemplate">
<put-attribute name="title" value="Login Page" />
<put-attribute name="browse" value="/WEB-INF/views/tiles/login.jsp" />
</definition>
<definition name="login" extends="indexTemplate">
<put-attribute name="title" value="Login Page" />
<put-attribute name="browse" value="/WEB-INF/views/tiles/login.jsp" />
</definition>
但考慮更複雜一點的情況呢?
例如電子商務中常見的, 點擊商品目錄.
此時商品目錄會展開, 且右邊會列出該目錄下的所有商品.
示意圖如下:
這時候就得在同一個 controller 裡處理商品及目錄的邏輯.
然後分別放入不同的 tiles 變數中.
等一下下...似乎有點奇怪, 目錄跟商品雖然有關係, 但畢竟各自有不同的處理邏輯.
放在同一個 controller 內處理似乎怪怪的...
如果再回頭看一下登入頁的例子, 目錄的頁面雖然不需變動, 但此時目錄頁應呈現第一層目錄結構.
第一層目錄結構的邏輯, 跟登入有什麼關係呢 ?
是否有辦法將各區塊的內容獨立處理, 讓彼此不相干的邏輯不要混在一起呢?
還好, tiles 提供了 View Preparer 來處理這種情況.
首先, 將tiles 的設定檔修改如下:
<tiles-definitions>
<definition name="category" template="/WEB-INF/views/tiles/category.jsp" preparer="com.example.viewpreparer.Category" />
<definition name="indexTemplate" template="/WEB-INF/views/tiles/indexTemplate.jsp">
<put-attribute name="title" value="Welcome" />
<put-attribute name="header" value="/WEB-INF/views/tiles/header.jsp" />
<put-attribute name="category" value="category" />
<put-attribute name="browse" value="/WEB-INF/views/tiles/browse.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/tiles/footer.jsp" />
</definition>
</tiles-definitions>
<definition name="category" template="/WEB-INF/views/tiles/category.jsp" preparer="com.example.viewpreparer.Category" />
<definition name="indexTemplate" template="/WEB-INF/views/tiles/indexTemplate.jsp">
<put-attribute name="title" value="Welcome" />
<put-attribute name="header" value="/WEB-INF/views/tiles/header.jsp" />
<put-attribute name="category" value="category" />
<put-attribute name="browse" value="/WEB-INF/views/tiles/browse.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/tiles/footer.jsp" />
</definition>
</tiles-definitions>
接著撰寫 com.example.viewpreparer.Category, 如下:
package com.example.viewpreparer;
import java.util.Map;
import org.apache.tiles.AttributeContext;
import org.apache.tiles.context.TilesRequestContext;
import org.apache.tiles.preparer.ViewPreparer;
import org.apache.tiles.Attribute;
public class Category implements ViewPreparer {
public void execute(TilesRequestContext tilesContext, AttributeContext attributeContext) {
// retrieve parameter
Map<String, String[]> map = tilesContext.getParamValues() ;
String[] list = map.get("cid") ;
if (list != null && list.length > 0 ) {
System.out.println("cid=" + list[0]) ;
}
// put variable
attributeContext.putAttribute("body", new Attribute("This is the value added by the ViewPreparer"));
}
}
import java.util.Map;
import org.apache.tiles.AttributeContext;
import org.apache.tiles.context.TilesRequestContext;
import org.apache.tiles.preparer.ViewPreparer;
import org.apache.tiles.Attribute;
public class Category implements ViewPreparer {
public void execute(TilesRequestContext tilesContext, AttributeContext attributeContext) {
// retrieve parameter
Map<String, String[]> map = tilesContext.getParamValues() ;
String[] list = map.get("cid") ;
if (list != null && list.length > 0 ) {
System.out.println("cid=" + list[0]) ;
}
// put variable
attributeContext.putAttribute("body", new Attribute("This is the value added by the ViewPreparer"));
}
}
category.jsp的寫法如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<tiles:insertAttribute name="body" />
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<tiles:insertAttribute name="body" />
除了用 <tiles:insertAttribute 外也可以用 jstl, 作法如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<tiles:useAttribute id="mybody" name="body" classname="java.lang.String" />
<c:out value="${mybody}" />
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<tiles:useAttribute id="mybody" name="body" classname="java.lang.String" />
<c:out value="${mybody}" />
沒有留言:
張貼留言