處理標籤屬性與本體


來考慮一個需求。網頁設計人員經常需要在 <head></head> 之間加些 <title><meta> 資訊,如果網頁設計人員發現 Web 應用程式中的 JSP 網頁,<head></head> 間除了部份資訊不同之外(例如 <title> 不同),其他要設定的訊息都是相同的,他希望將 <head></head> 間的東西製作為 Tag File,之後要修改時,只需要修改 Tag File,就可以套用至全部有引用該 Tag File 的 JSP 網頁。問題在於,如何設定 Tag File 中不同的特定資訊?

答案是透過 Tag File 屬性設定。就如同 HTML 的元素都有一些屬性可以設定,在建立 Tag File 時,也可以指定使用某些屬性,方法則是透過 attribute 指示元素來指定。直接來看範例了解如何設定。

Header.tag

<%@tag description="header 內容" pageEncoding="UTF-8"%>
<%@attribute name="title"%>
<head>
    <title>${title}</title>
    <meta charset="UTF-8">
</head> 

attribute 指示元素定義使用 Tag File 時可以設定的屬性名稱,如果有多個屬性名稱,則可以使用多個 attribute 指示元素來設定。設定名稱之後,若有人使用 Tag File 時指定屬性值,則這個值在 *.tag 檔案中,可以使用如以上範例中的 ${title} 方式來取得。下面這個網頁是個使用範例。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="html" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html>
<html>
    <html:Header title="新增書籤"/>
    <body>
        <html:Errors/>
        <form method="post" action="add">
            網址&nbsp;http:// <input name="url" value="${param.url}"><br>
            網頁名稱:<input name="title" value="${param.title}"><br>
            分  類:<input type="text" name="category" value=${param.category}"><br>
            <input value="送出" type="submit"><br>
        </form>
    </body>
</html> 

目前為止所使用的都是沒有本體內容的 Tag File,事實上 Tag File 標籤是可以有本體內容的。舉個例子來說,如果 JSP 頁面中,除了 <body></body> 之間的東西是不同的之外,其他都是相同的,那麼可以像下面的範例,撰寫一個 Tag File:

Html.tag

<%@tag description="HTML 懶人標籤" pageEncoding="UTF-8"%>
<%@attribute name="title"%>
<!DOCTYPE html>
<html>
    <head>
        <title>${title}</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <jsp:doBody/>
    </body>
</html> 

這個 Tag File 使用 attribute 指示元素宣告了 title 屬性,當中撰寫了基本的 HTML 樣版,<body></body> 出現了 <jsp:doBody/> 標籤,它可以取得使用 Tag File 標籤時的本體內容。簡單地說,可以這麼使用這個 Tag File:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib  prefix="html" tagdir="/WEB-INF/tags" %>
<html:Html title="新增書籤">
    <html:Errors/>
    <form method="post" action="add">
        網址&nbsp;http:// <input name="url" value="${param.url}"><br>
        網頁名稱:<input name="title" value="${param.title}"><br>
        分  類:<input type="text" name="category" value="${param.category}"><br>
        <input value="送出" type="submit"><br>
    </form>
</html:Html> 

注意!前一段敘述說的,Tag File 的本體內容可以撰寫 HTML、EL 或自訂標籤,但沒有提到 Scriptlet。Tag File 的標籤在使用時若有本體,預設是不允許有 Scriptlet,因為定義 Tag File 時,tag 指示元素的 body-content 屬性預設就是 scriptless,也就是不可以出現 <% %><%= %><%! %> 元素。

<%@tag body-content="scriptless" pageEncoding="UTF-8"%>

body-content 屬性還可以設定 emptytagdependentempty 表示一定沒有本體內容,也就是只能以 <html:Header/> 這樣的方式來使用標籤(非 emtpty 的設定時,你可以用 <html:Headers/>,或者是 <html:Header> 本體 </html:Header> 的方式)。tagdependent 表示將本體中的內容當作純文字處理,也就是如果本體中有出現 Scriptlet、EL 或自訂標籤,也只是當作純文字輸出,不會作任何的運算或轉譯。

結論就是,Tag File 若有本體,在其中撰寫 Scriptlet 是沒有意義的,要不就不允許出現,要不就當作純文字輸出。