struts系列學習(tiles標籤庫三)

 

Tiles的使用(三)                                    

將應用程序遷移到Tiles中
       
在前面的章節我們描述了Tiles使你的應用程序更加和諧統一,容易使用。我們也說了統一是良好設計的特點。因爲統一就意味着可複用。複用會使得應用程序穩定,容易維護。
        你也許經常希望你現有的應用程序用Tiles上技術。讓它看起來更加和諧統一,或改善它的功能和設計,或兩者都是。這被稱爲重構。
        如何你熟悉一般的重構技術,遷移一個應用程序到 Tiles中,類似於Extract Method。

建立Tiles框架
        首先要做好備份,這一步非常非常重要!

測試默認的配置
         把web.xml中debug和detail參數設置爲2,再重啓應用程序。仔細查看日誌條目,看有沒有新的錯誤產生。運行所有的單元測試,通過點擊應用程序確認運行是否正常。

Reviewing the pages
         
接下來的事情是仔細看你的頁面,確定總的佈局類型和每個佈局的區域劃分。花時間思考怎麼命名。每個組件需要自己的標識符。

1.) 確定佈局    縱觀整個應用程序,你會發現各種不同的菜單,對話框-列表頁,視圖頁,等等。重點不是頁面要包含哪些內容,而是頁面的各部分怎麼放在一起才合適。要有 header和footer嗎,要有menu嗎,menu放在邊上還是頂部?所有這些,相關位置比實際內容更重要。試着去確定一些共用的佈局,再着重處理整個應用程序中的可視化佈局(visual layouts),而不是頁面內容。
2.)標識tiles    下面要關注共用的佈局,標識出獨立tiles。每個tile的顯示代碼(presentation code)會被存儲在一個單獨的文件中。我們能在多個佈局中使用它,或者再不用觸及其它的tiles編輯它。這個過程就像是用Extract Method處理一個大的Java類。一條線索是看顯示代碼中存在的註釋,像<!-- menu starts here -- >。代碼塊的前面常會有註釋,這有可能產生一個tile,像下面的代碼塊:
<%-- messages --%>
<TR class="message">
<TD colspan="3">
<logic:messagesPresent>
<bean:message key="errors.header"/>
<html:messages id="error">
<LI><bean:write name="error"/></LI>
</html:messages>
<bean:message key="errors.footer"/>
</logic:messagesPresent>
</TD>
</TR>
 
在一個頁面中格式(style)的改變也可能預示着存在一個tile。如果設計者用格式來分離頁面的某各部分,那個部分也可以成爲一個好的tile。
        一個包含自身代碼的單獨的塊是最好的選擇。效果就像是以一個Java函數。
        如果顯示代碼像這樣沒有註釋,在提取(extract) tile前添加一些註釋很有用;如果頁面的片斷看起來像一個tile,但在每個頁面輸出不同東西的,別擔心!Tiles也可以傳輸字符串常量到一個tile 中,使得其餘的標記能被複用。這時只需設置一個能夠被替換的標籤,像${subtitle},它就可以被傳入的字符串替換。
3.)命名的選擇
        在開始時確定一個很好的命名方案很有用。我們對某個組件的命名應該能夠一幕瞭然。下面先解釋一下tiles的術語:
        Tile --  一個使用HTML標記和JSP代碼的可複用的頁面片斷。
        Layout(佈局) --  一個用來描述頁面中各個tiles位置的JSP。 
        Definition( 定義) --  一個用來表示特殊頁面的JavaBean。Definition 由一個layout 加上許多tiles ,以及其他運行時產生頁面組成。Definition可以用一個JSP或XML配置文件來表示。
       
Tiles --  把文本片斷和從一個現有的頁面抽取(extract)出來的標記組合在一起。
        Markup --  是放置在文件中的命令集,提供一種比可視化的文本更好的格式指令。 HTML就是一種應用。
        chrome--  是window應用程序內容區外面的那部分,像工具欄,菜單欄,標題欄。 HTML chrome用標籤創建,位於window應用程序內部,但功能相同。

       tiles能夠使用靜態的內容,標記或兩者的混合體。tiles表示導航控制,公用資源,並可以在兩個頁面間複用。公用資源可以包含一張決定logo位置或能被用於多張表單的按鈕(像Save和Cancel)。其它的tiles包含一個單個頁面的內容。這些tiles 可以在頁面的中間,常常被另外一些有菜單欄和HTML chrome功能的tiles包圍。 
       你可以把tile分類放到不同文件夾中,然後用"."號來引用,當然你也可以用"@",只要合乎邏輯。
 
 /pages
./article/Form.jsp
./channel/Channels.jsp
/tiles
./header.jsp./message.jsp
------------------------------------------------------------------------ ------------------------------------------------------------------
<definition name=".pages.Form"> . . . </definition>

使用 <tiles:insert>重構頁面
       重構剛開始要慢慢進行,儘量做很小的改動,直到第一個步驟完成。隨着工作的繼續,從以前的工作中吸取教訓,你的步伐會越來越大。
       大多數情況,使用那些在Tiles配置文件中聲明和能從ActionForward中調用的Definition的目的是減少頁面。方法是把創建的擴展列表頁面保存好,插入到tiles中。但剛開始,最簡單的是用<tiles:insert>標記創建一個頁面。整個過程如下:
        1.)選擇一個好的初始頁面
            最好是選擇一個簡單的頁面,提取共同的組件,然後把它們一個一個插入到原始頁面。你應用程序的歡迎或登陸頁面是一個好的選擇。這些頁面往往混合了能被複用和自定義的內容,相對比較簡單。一個內部(interior)頁面也是個好選擇,如果它不包含太多的chrome。看下面一個內部頁面:
Our starter page: /pages/View.jsp
--------------------------------- ------------------------------------------------------------------------------------------- ---------------
 <%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/request" prefix="req" %>
<!-- HEADER -->
<HTML>
<HEAD>
<html:base/>
<LINK rel="stylesheet" type="text/css" href="<html:rewrite forward='baseStyle'/>">
<TITLE>Artimus - Article</TITLE>
</HEAD>
<BODY>
<TABLE class="outer">
<TR>
<TD>
<TABLE class="inner">
<!-- MESSAGE -->
<TR>
<TD class="message" colspan="3" width="100%"><html:errors/></TD>
</TR>
<TR>
<TD class="heading" colspan="3">
<H2><bean:write name="articleForm" property="title"/></H2></TD>
</TR>
<TR>
<TD class="author" colspan="3">by <bean:write name="articleForm" property="creator"/>
</TD>
</TR>
<TR>
<TD class="article" colspan="3">
<bean:write name="articleForm" property="content" filter="false"/></TD>
</TR>
<%-- CONTRIBUTOR PANEL --% >
<req:isUserInRole role="contributor">
<TR>
<TD colspan="3"><HR /></TD>
</TR>
<TR>
<%-- DELETE --% >
<logic:equal name="articleForm" property="marked" value="0">
<html:form action="/admin/article/Delete">
<TD class="input"><html:submit >DELETE</html:submit></TD>
<html:hidden property="article"/>
</html:form>
</logic:equal>
<%-- RESTORE -- %>
<logic:equal name="articleForm" property="marked" value="1">
<html:form action="/admin/article/Restore">
<TD class="input">
<html:submit>RESTORE</html:submit>
</TD>
<ht ml:hidden property="article"/>
</html:form>
</logic:equal>
<html:form action="/admin/article/Edit">
<TD class="button" colspan="2">
<html:hidden property="article"/>
<html:submit>EDIT</html:submit>
<html:cancel> ;CANCEL</html:cancel>
</TD>
</html:form>
</TR>
</req: isUserInRole>
<!-- NAVBAR -- >
</TABLE>
</TD>
</TR>
<TR>
<TD class="navbar">
<html:link forward="done">DONE</html:link>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
         一旦你選擇了初始頁面,瀏覽後抽取每個邏輯塊到自己的tile中,再把這個tile插入進來。每次提取後,測試確認頁面運行正常。看下面一個被抽取到自己tile中的片斷::
An extracted tile: /tiles/header.jsp
----------------------------------------------- ------------------------------------------------------------------------------------------- -
<%@ taglib uri="/tags/struts-html" prefix="html" % >
<HTML>
<HEAD>
<html:base/>
<LINK rel="stylesheet" type="text/css" href="<html:rewrite
forward='baseStyle'/>">
<TITLE>Artimus - View Article</TITLE>
</HEAD>
<BODY onload="document.forms[0].elements [0].focus();">
<!-- OUTER TABLE -->
<TABLE class="outer">
<TR>
<TD align="center">
<!-- INNER TABLE -- >
<TABLE class="inner">
<TR>
<TD class="navbar" colspan="3">View Article</TD>
</TR>
    看下面的view.jsp頁面是怎麼包含被抽取的Header tile的:
 Inserting an extracted tile: /pages/article/View.jsp
------------------------- ------------------------------------------------------------------------------------------- -----------------------
<%@ taglib uri="/tags/struts-html" prefix="html" % >
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/tiles" prefix="tiles" %>
<%@ taglib uri="/tags/request" prefix="req" %>
<!-- HEAD -->
<tiles:insert page="/tiles/header.jsp"/>
<!-- MESSAGE -- >
<TR>
<TD class="message" colspan="3" width="100%"><html:errors/></TD>
</TR>
<!-- ... -- >
</HTML>
       
        很快你第一個抽取的tile被重新插入到頁面中,在你轉移下一個tile前,先測試頁面,確認頁面能被打開。
        處理完畢後,頁面會由一些插入的tiles組成,就像下面所示:
A refactored page: /pages/View.jsp (completed)
------------------------------------- ------------------------------------------------------------------------------------------- -----------
<%@ taglib uri="/tags/tiles" prefix="tiles" %>
<tiles:insert page="/tiles/header.jsp"/>
<tiles:insert page="/tiles/message.jsp"/>
<tiles:insert page="/tiles/view.jsp"/>
<tiles:insert page="/tiles/navbar.jsp"/>

         如果文件中有些tiles需要被自定義,你能夠使用<tiles:put>標記發送一個自定義的值給tile:

Inserting dynamic content: /pages/View.jsp (revised)
--------------------------------------------------------------------------------------------------------------------------- --------------- 
<%@ taglib uri="/tags/tiles" prefix="tiles" % >
<tiles:insert page="/tiles/header.jsp">
<tiles:put name="title" value ="Artimus - View Article"/>
<tiles:put name="subtitle" value ="View Article"/>
</tiles:insert>
<tiles:insert page="/tiles/message.jsp"/>
<tiles:insert page="/tiles/view.jsp"/>
<tiles:insert page="/tiles/navbar.jsp"/>


         下面是使用 <tiles:getAsString>標記輸出動態文本:
Writing dynamic content with getAsString
------------------------------------------- ------------------------------------------------------------------------------------------- ---- 
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/tiles" prefix="tiles" % >
<HTML>
<HEAD>
<html:base/>
<LINK rel="stylesheet" type="text/css" href="<html:rewrite
forward='baseStyle'/>">
<TITLE><tiles:getAsString name="title"/></TITLE>
</HEAD>
<BODY onload="document.forms [0].elements[0].focus();">
<!-- OUTER TABLE -->
<TABLE class="outer">
<TR>
<TD align="center">
<!-- INNER TABLE -- >
<TABLE class="inner">
<TR>
<TD class="navbar" colspan="3"><tiles:getAsString name="subtitle"/></TD>
</TR>
        如果你喜歡,可以使用<bean:write>或 <bean:message>標記取代<tiles:getAsString>.。

        2.)抽取 tiles
            重構的主要工作是決定頁面的哪個部分是tile,移動那個片斷到自己的文件中再用它來替代那個片斷。
            這個給出了每個詳細的步驟:
    • 選擇剪切塊
    • 打開一個新文件
    • 把這個塊粘貼進來
    • 作爲一個JSP(或HTML)保存
    • 插入引入tile聲明的標籤庫
    • 關閉新文件
    • 放置<tile:insert page="/path/to/new/page"/>標籤的地方片斷就會引用  

            注意:在重構前設置了Tiles Definitions的頁面已經能夠顯示。頁面被編排的不同,但內容和外觀還是和以前一樣的。Definition常常包含body或內容tile。一些頁面可以沒有自己的tile,但它們可以使用共享的tile 。在不同的情況下,你可以在一個表單中使用不同的按鈕。一個頁面可以包含創建記錄的按鈕,另一個頁面可以包含更新記錄的按鈕。這些不同的頁面可以使用含有title string和動態內容的相同Definition來創建。

抽取練習
       下面是抽取過程中的注意點:
    1. 所有被tile使用的自定義標記都必須放到tile中
    2. 所有自定義標記元素的開始和結束都必須在同一個tile中
    3. 避免將HTML元素傳遞到另一個tile中
    4. 使用註釋
    5. 考慮平衡
    6. 有效的技術

1. tile能夠繼承HTML的資源,像CSS;但它不會繼承涉及JSP的資源(標籤庫等)。當頁面執行的時候web瀏覽器能解析CSS,但每個tle實際是一個單獨的JSP或servlet,它需要自己調用JSP資源。
2. 如果你使用<html:html>標記,將該元素的標籤就必須放置在一個tile佈局的開頭和結尾。這一限制不適用於HTML元素。你能夠在一個header tile中打開<body>元素,在footer tile中關閉</body>。但自定義標籤要生效的話,tile必須完整。JSP標籤元素的開始和結束必須在同一個tile中。
3. 在實際操作中,你可以決定第一個tile打開一個元素,像一個表格;第二個tile提供內容,像表格中的行;在第三個tile中關閉這個元素,這種情況是可以使用的。但你最好把許開始和結束元素放到同一個tile中,這樣更加容易發現標籤錯誤。即使只在中間的tile中提供表格的行,它也可以使用一個完全的行標籤 <TR>...</TR>。
4. 多使用註釋,讓你的代碼更清晰,更加容易維護,就像下面所示的標準的JavaDoc:

<%--
/**
* Global page header, without automatic form select.
* See headerForm.jsp for version with form select.
* Imports global style sheet.
* Opens HEAD, BODY, and TABLE. Another tile must close these.
* @author Ted Husted
* @license ASF 1.0
*/
--%>

5. 分離頁面到tiles中的工作就像是把信息存到數據庫中。你可以完全的去除多餘的信息,但如果你這樣做,某些部分會變得更加小,甚至引發維護和性能問題的矛盾。你可能有兩3個不同的內容的header或footer文件。但如果標籤要改變,顯然3個文件比30或300個文件更容易修改。因此對於很多編程任務,這種折衷代價還是適用的。
6. 如果你要同時修改引入的CSS和其它標籤,別猶豫,創建一些能夠自動完成查找替換的文件,這會讓你節約很多的時間。
 
抽取<tiles:insert>標籤到Definition
       在你完成上一節(抽取練習)的步驟到你的初始頁面確認還能正常工作後,你能夠開始本節的內容了。這是四個步驟:
    1. 移動頁面到佈局文件夾中
    2. 重命名body tile
    3. 轉換插入標記爲一個佈局和Definition
    4. 更新ActionForward

1. 移動重構的頁面到本地佈局文件夾,例如:/tiles/layouts。被重構的頁面應該變成一系列的<tile:insert>標記,而頁面的原始內容放到其它tile中而減少了。
2. 一個抽取出來的tiles有可能是原來頁面的一個body,如果是這樣,就要考慮重命名這個移動的頁面,這就是說原來頁面的核心內容仍然在原來的地方。如果你需要修改頁面內容,只要移動或重命名文件夾後再更新一下<tile:insert>標記,這樣做將使你的改動帶來的影響最小化。

 <tiles:insert page="/tiles/view.jsp"/>
to
<tiles:insert page="/pages/view.jsp"/>
 
3.爲每個插入的標記添加一個名稱屬性。通常匹配JSP名稱,除了表示原是內容的tile。通常也使用一個非常普通的名稱,像content。拷貝重構頁面的<tiles:insert>聲明到這章開始定義的xml配置文件中,放在<definition>元素中,如果你使用了一些<tiles:put>元素,你可以將它們放在元素開頭:
<definition>
<tiles:insert put="title" value ="Artimus - View Article"/>
<tiles:insert put="subtitle" value ="View Article"/>
<tiles:insert name="header" page="/tiles/header.jsp"/>
<tiles:insert name="message" page="/tiles/message.jsp"/>
<tiles:insert name="content" page="/pages/view.jsp"/>
<tiles:insert name="navbar" page="/tiles/navbar.jsp"/>
</definition>
然後把 <tiles:insert>標記改爲<tiles:put>,把page屬性名改爲value,在<definition>元素內添加name和path屬性名。path屬性應該是你的佈局頁面,name 屬性對應的是你的原始頁面的名稱,只是將斜槓替換爲點號。見下面修改後的文件:
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration//EN"
"
http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
<tiles-definitions>
<definition name=".article.view" path="/pages/tiles/layouts/Base.jsp>
<tiles:put name="title" value ="Artimus - View Article"/>
<tiles:put name="subtitle" value="View Article"/>
<tiles:put name="header" value="/tiles/header.jsp"/>
<tiles:put name="message" value="/tiles/message.jsp"/>
<tiles:put name="content" value="/pages/view.jsp"/>
<tiles:put name="navbar" value="/tiles/navbar.jsp"/>
</definition>
</tiles-definitions> 

 現在到佈局頁面中,把<tiles:insert>標記改爲<tiles:get>,然後刪除page屬性(因爲現在它是Definition 的一部分),任何的<tiles:put>標記都能變爲<tiles:useAttribute>。保留name屬性,但要刪除value屬性(因爲value 也是Definition 的一部分了),操作見下:
A Tiles layout page: /tiles/layouts/Base.jsp
--------------------------------------- ------------------------------------------------------------------------------------------- ---------
<%@ taglib uri="/tags/tiles" prefix="tiles" %>
<tiles:useAttribute name="title"/>
<tiles:useAttribute name="subtitle"/>
<tiles:get name="header">
<tiles:get name="message"/>
<tiles:get name="content"/>
<tiles:get name="navbar"/>

4.最後,用Tiles Definition替代ActionForward中相關的JSP:
<action
path="/article/View"
type="org.apache.scaffold.struts.ProcessAction"
parameter="org.apache.artimus.article.FindByArticle"
name="articleForm"
scope="reques t"
validate="false">
<forward
name="success"
path=".article.View"/>
</action>

下面的圖表示Tiles ActionServlet截獲Definition到佈局頁面的流程:

       titles(JSP/HTML/text)  [<header fragment>  <content fragment>  <footer fragment>]  
                                                     |                              |                       |   
                                                    /|/                            /|/                     /|/
request -- > definition(XML)  [   <put header>            <put content>    <put footer>] 
                                                     |                              |                       |
                                                    /|/                            /|/                     /|/
                  layout(JSP)     [        <ge theader>           <get content>    <get footer>]  -->  response

(做的真爛!~_~)


如果你先前是直接轉發到JSP,你可以用標準的框架的SuccessAction來控制路由,Definition會選擇和呈現佈局。在任何地方你都可以把Definition作爲JSP的系統路徑。如果有很多的引用要修改,你能夠使用帶有查找替代的編輯器自動完成它們。
       在運行時,Tiles ActionServlet會截獲ActionForward,再次在Tiles配置文件的Definition中檢查它的路徑。如果發現有一個匹配的,它會在response中包含Definition的每個tile。容器然後處理包含的每個tile,HTML tiles被容器的HTML服務實現,JSP tiles被容器的JSP服務實現。
       如果ActionForward路徑不是一個Definition的名稱,ActionServlet會把它作爲普通的URL處理。
       注意:如果你重構的頁面不能顯示原來的內容,首先確定在tiles你已經引入了所有需要的標籤庫。如果標籤庫沒有被包含,瀏覽器會忽略這種標籤,標籤就不會正常顯示。如果這個沒問題,創建一個新的頁面,一步一步把頁面放到新的頁面來找出錯誤。你會發現一個tile的問題常常是一個元素的打開和關閉不符合規定。另一個規定是檢查關於ActionMapping的輸入參數的路徑,你應更仔細的檢查Definition的名稱。在改爲Tiles後如果你得到的錯誤爲:必須爲絕對路徑(Path must be absolute),意思是說你試着用一個Definition作爲定向的路徑但它在Tiles配置文件中沒有被找到。在檢查完Definition後,Tiles把路徑傳遞給父類的方法,Structs創建它作爲系統路徑。點號用來指明目錄的相對路徑,因此會提示"Path must be absolute"。
       測試你的更改時,要重載應用程序以便當前的Structs和Tiles配置能夠裝載到內存中。
       當你用<tiles:insert>重構頁面並把它轉變爲一個Definition的步驟都處理完,通過測試後,你可以期待把其它的頁面直接改爲Definition了。你要做下列步驟:
    • 拷貝一個已有的Definition ,並使用相同的佈局.,再給它取個新名稱。
    • 粘貼和保存你重構頁面的代碼片斷。
    • 修改新的Definition,引用剛剛存儲和轉換的代碼片斷。
    • 測試,重複上面的步驟。

       注意:當你第一次把一個頁面塊轉變爲一個Tiles時,也許還要爲它花一些時間,因爲你還要爲新的tiles創建一些JSP頁面,以及一些額外的內容。一旦爲每個tile的JSP創建好後,只有到下次修改JSP時纔會被重新創建,一切又都會恢復正常。以後如果你要編輯tile的內容,只有那個JSP會被重新編譯。

使你的基礎佈局規範化
       在上面的例子中,我們在佈局文件中列出了一串<tiles:insert>標記。如果你喜歡,也可以在你的佈局頁面中使用HTML和JSP代碼,放置頂級標記是個好主意,像<HTML>或<html:html>,以便它們不會被放入需要做其它事情tiles之中。
        在下面的例子中,從header和navbar tiles中抽取了頂級元素,然後把它們放到了基本佈局中。我們可以把
Base.jsp重命名爲Article.jsp,更清楚的表達這個tile的功能。在應用程序中的其它頁面也能使用一個不同的佈局。

Revised layout tile (/tiles/layouts/Article.jsp)
--------------------------------------------------------------------------------------- ---------------------------------------------------
<%@ taglib uri="/tags/tiles" prefix="tiles" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<html:html>
<HEAD>
<html:base/>
<LINK rel="stylesheet" type="text/css" href="<html:rewrite
forward='baseStyle'/>">
<TITLE>Artimus - <bean:write name="title"/></TITLE>
</HEAD>
<tiles:useAttribute name="title"/>
<tiles:get name="header"/>
<tiles:get name="message"/>
<tiles:get name="content"/>
<tiles:get name="navbar"/>
</BODY>
</html:html> 
 
提取你的Definitions到基類或擴展類中
       在將頁面轉換爲佈局和Definition時, 最後可能很容易成爲這樣:
<definition name=".article.View" path="/tiles/layouts/Article.jsp">
<put name="title" value="View Article" />
<put name="header" value="/tiles/header.jsp" />
<put name="messages" value="/tiles/messages.jsp" />
<put name="content" value="/pages/articles/view.jsp" />
<put name="navbar" value="/tiles/navbar.jsp" />
</definition>
<definition name=".article.View" path="/tiles/layouts/Article.jsp">
<put name="title" value="Search Result" />
<put name="header" value="/tiles/header.jsp" />
<put name="messages" value="/tiles/messages.jsp" />
<put name="content" value="/pages/articles/result.jsp" />
<put name="navbar" value="/tiles/navbar.jsp" />
</definition>
仔細看,你會發現只有第一和第四個條目不同。一個更好的書寫方法是創建一個基本的Definitions。Tiles Definition支持擴展特性,讓一個Definition繼承屬性,在需要改變的時候重載它。這裏,我們擴展了.article.Base,重載了title和content:
<definition name=".article.Base" path="/tiles/layouts/Article.jsp">
<put name="title" value="${title}"/>
<put name="header" value="/tiles/header.jsp"/>
<put name="message" value="/tiles/message.jsp"/>
<put name="content" value="${content}"/>
<put name="navbar" value="/tiles/navbar.jsp"/>
</definition>
<definition name=".article.View" extends=".article.Base">
<put name="title" value="View Article"/>
<put name="content" value="/pages/article/view.jsp"/>
</definition>
<definition name=".article.Result" extends=".article.Base">
<put name="title" value ="Article Search Result"/>
<put name="content" value="/pages/article/result.jsp"/>
</definition>
 
這樣就減小了改變的影響。
       有個約定,我們在第一和第四個條目(title和content)放置標記,作爲子類Definition需要去重載的擴展點。如果基本的Definition被直接使用,這些標籤會被直接打印出來。對Tiles來說${}標籤沒有特殊的意思。
       另一個慣例佈局JSP首字母大寫,tile JSP首字母小寫。這表明佈局頁面能被直接使用,因爲它是一個完整的JSP,佈局JSP就像調用方法一樣來使用tile頁面。但這只是一個慣例,其它的命名方式也能工作的很好。
 
開發的常規過程
    1. 通常會拷貝一個相似的文件,在tag.xml中創建一個新的Definition。
    2. 用存在頁面、tile和其它自定義信息更新Definition的路徑。
    3. 打開一個現有的頁面。
    4. 刪除頭和尾內容,留下核心的內容和tag導入語句。
    5. 檢查和修正核心內容,在Definition確認標籤是否符合規定。一個tile可以打開一個元素,像<TABLE>,在另一個tile中務必要關閉它。移除所有不必要的tag引入聲明。隨意的添加一些註釋。
    6. 更新Struts配置文件(struts-config.xml))中新Definition的路徑,包括所有的input屬性。
    7. 重載tag和Struts配置文件。
    8. 檢查頁面。
    9. 反覆直至滿意。

首先,你可能先用一些頁面來呈現應用程序的輪廓。一旦你構造好程序框架,通過頁面的關聯(page tree)依次完成和重構每個頁面並不困難。這確保你不會失去任何東西。它也能發現以前開發過程中的一些無用的頁面。

管理遷移
         遷移一個應用程序爲Tiles結構並不困難但也不要小看它。對項目要確保有足夠的時間規劃。開始少數的頁面可能會花去幾個小時,一旦確定了結構,添加每個頁面就只需幾分鐘了。
       如果你在網站要採用一個新的界面,最好是先把它轉換成Tiles結構,再修改界面,免得同時進行兩項新的任務。一旦遷移到Tiles後,改變一個界面將更快速簡單。
       開始遷移的最好的時間是在你知道將要對站點進行改版,而手頭有沒有新設計要去修改時。如果你已經把應用程序遷移到Tiles中,即使新設計最後才定下來,改變工作將非常順利。不推薦一次做兩個步驟--尤其是你第一次遷移的時候。
       那麼遷移的底線是什麼呢?一個有25個表達頁面的小型的應用程序,大約有140000 kbytes個標記代碼,可能被遷移到55個tiles中,而代碼減少到120000 kbytes,15%的多餘代碼被去除。
       現在新的頁面創建更加快速,容易和現有的頁面保持一致。要改變整個站定的佈局時,只要修改整體佈局或少數幾個tiles,而不是站點的每個頁面了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章