kapok

          垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            455 隨筆 :: 0 文章 :: 76 評(píng)論 :: 0 Trackbacks
          http://dev2dev.bea.com.cn/techdoc/wlportal/2004102804.html

          標(biāo)題:門戶用戶界面:讓應(yīng)用程序更吸引人
          ——使用WebLogic Portal輕松創(chuàng)建引人注目的用戶界面
          瀏覽次數(shù): 961 時(shí)間:2004-10-29
          作者:David Hritz

            任何沒有清晰的、易用的界面的應(yīng)用程序都是不完整的。如果用戶無法使用或不愿意使用您的應(yīng)用程序,那么就算應(yīng)用程序中集成了再多吸引人的邏輯也無濟(jì)于事。BEA WebLogic Portal的特性之一就是它豐富的用戶界面框架。它們?cè)试S開發(fā)人員和門戶管理員輕松地構(gòu)造引人注目的用戶界面,同時(shí)還允許他們定制樣式和結(jié)構(gòu)。

            門戶用戶界面框架組件
            用戶界面框架有很多組件。BEA開箱即用地實(shí)現(xiàn)了的所有用戶界面組件。這些缺省的組件對(duì)某些應(yīng)用程序來說已經(jīng)足夠了,但我們還是很可能需要某個(gè)級(jí)別的定制。在深入討論框架和定制之前,先讓我們簡(jiǎn)略地看一下每個(gè)用戶界面組件以及它們之間的關(guān)系。

            觀感(look and feel) 觀感文件控制著門戶應(yīng)用程序的樣式和結(jié)構(gòu)。這些文件都是引用特定皮膚(即look)和骨架(即feel)的簡(jiǎn)單XML文件。一個(gè)門戶的觀感是應(yīng)用在桌面級(jí)別上的。雖然門戶開發(fā)人員會(huì)先選擇一個(gè)門戶的觀感,但最終還是由門戶管理員來做最后的決定。

            皮膚(skin) 門戶皮膚就是門戶的外觀。這個(gè)外觀由圖像、級(jí)聯(lián)樣式表(CSS)和JavaScript函數(shù)組成。這些文件一起描述了門戶的樣式和行為。皮膚還為移動(dòng)設(shè)備包含特定于設(shè)備的樣式。

            Portal皮膚由位于skin目錄下的skin.properties文件來配置。這個(gè)配置文件可用來定義圖像、CSS以及JavaScript文件和路徑。另外,skin.properties文件還能用于定義與該皮膚一起使用的骨架(skeleton)名稱和路徑、添加方法到主體onload 和onunload 事件,以及定義附加信息。

            當(dāng)定制任何默認(rèn)的安裝皮膚時(shí),建議不要把額外的配置更改放在skin.properties文件中,而是放在一個(gè)可選的skin_custom.properties文件里。這樣做的原因是門戶升級(jí)的安裝程序會(huì)覆蓋掉skin.properties和skin文件所做的修改,也就覆蓋掉了您所做的配置更改。

            骨架(Skeleton) 門戶的感覺取決于它的骨架。門戶的結(jié)構(gòu)由背后的XML決定,即到底是.portal XML文件格式還是數(shù)據(jù)庫(kù)本身。這個(gè)XML文件可以像可從桌面添加和刪除的組件一樣被修改。每個(gè)門戶組件都與負(fù)責(zé)顯示它的JavaServer Pages (JSP)頁面相關(guān)。這些JSP頁面的集合就構(gòu)成了門戶骨架。骨架也可包含特定于設(shè)備的JSP,這些JSP指明用于查看移動(dòng)設(shè)備上的Web應(yīng)用程序的結(jié)構(gòu)。

            門戶骨架還能使用skeleton目錄下skeleton.properties文件中的額外配置信息。通常情況下,該文件在創(chuàng)建定制骨架時(shí)使用。您可以設(shè)置JSP的搜索路徑,這樣就能在試圖查找JSP時(shí)使用其他一個(gè)或一系列路徑。例如,假如您想修改book.jsp,只需簡(jiǎn)單地給修改后的book.jsp創(chuàng)建一個(gè)定制的skeleton目錄,并設(shè)置JSP搜索路徑屬性,jsp.search.path: ., ../default。這樣,當(dāng)門戶框架不能在當(dāng)前目錄下找到指定文件時(shí),它就會(huì)嘗試在默認(rèn)的skeleton目錄下去找。

            這使得骨架的定制變得很簡(jiǎn)單。定制的骨架可以僅修改一個(gè)單獨(dú)的骨架JSP頁面。該定制目錄將只包含這一個(gè)文件,而其他的功能則依賴一個(gè)獨(dú)立的骨架。

            主題(Themes) 骨架和皮膚能共享一個(gè)公共的觀感子集,也就是一個(gè)主題。主題為特殊門戶組件使用不同樣式和結(jié)構(gòu)提供了一種機(jī)制,以便覆蓋當(dāng)前選擇的觀感。

            Shell 門戶的shell控制著門戶原則功能部分的位置和對(duì)齊,以及任何附加的內(nèi)容窗口。大多數(shù)門戶至少會(huì)顯示一個(gè)頁眉和一個(gè)頁腳,但是shell可以被定制成以任何必要的方式包裝主窗口。

            布局(Layout)和占位符(placeholder) 門戶的頁面結(jié)構(gòu)基于它的布局。布局是一種簡(jiǎn)單的表結(jié)構(gòu),用來把門戶中的組件置入到稱為占位符的獨(dú)立單元中。當(dāng)創(chuàng)建您自己的布局時(shí),BEA會(huì)提供布局樣式供您使用。這些樣式會(huì)描述門戶如何放置占位符。

            布局由兩個(gè)文件定義,一個(gè)是<layout_name>.layout文件,另一個(gè)是<layout_name>.html.txt文件。.layout文件是用于實(shí)際布局組件的XML文件。它就是包含著占位符的文件。而.html.txt文件僅僅是一個(gè)被Workshop和administration portal使用的模板。這些工具把.html.txt文件當(dāng)作一個(gè)模板,使開發(fā)人員知道這個(gè)布局的效果,并為添加組件到占位符提供了方法。

            菜單(Menus) 兩個(gè)菜單之一可以在目錄導(dǎo)航的門戶中使用。這些菜單提供了稍微有點(diǎn)不同的導(dǎo)航級(jí)別。這些菜單系統(tǒng)的缺省功能可以通過修改相關(guān)的skeleton文件來定制。

            選擇皮膚和骨架
            盡管我提到觀感(look-and-feel)文件會(huì)引用要使用的皮膚和骨架,但是這也不是必要條件。因?yàn)槎x了皮膚和骨架名稱以及路徑的觀感屬性是可選的。那么如何才能使觀感文件既不包含外觀也不包含感覺呢?答案是無法做到。嘗試不用容器來顯示內(nèi)容,就好像嘗試把水倒進(jìn)一個(gè)虛構(gòu)的玻璃杯中。假如觀感文件中的一些或所有屬性并沒有被指定,那么框架就只有依賴于配置好的設(shè)置或用戶默認(rèn)的值。以下是選擇皮膚和骨架的規(guī)則:

            皮膚的命名:

          • 如果沒有指定,就使用/framework/skins/default皮膚。
            皮膚的路徑:
          • 如果沒有指定,就使用/framework/skins/。

            骨架的命名:

          • 如果沒有指定,就使用skin.properties中的default.skeleton.id。
          • 如果沒有指定default.skeleton.id屬性,就使用/framework/skeletons/default。
             骨架的路徑:

          • 如果沒有指定,就使用skin.properties中的default.skeleton.path。
          • 如果沒有指定skin.properties中的default.skeleton.path,就使用/framework/skeletons/。
            門戶骨架呈現(xiàn)標(biāo)簽庫(kù)
            門戶從選擇的骨架中呈現(xiàn)出來。每個(gè)門戶 XML組件會(huì)映射到一個(gè)骨架JSP文件。骨架JSP文件根據(jù)一個(gè)門戶標(biāo)簽庫(kù)來呈現(xiàn)這些組件。這個(gè)標(biāo)簽庫(kù)就是門戶骨架呈現(xiàn)標(biāo)簽庫(kù),它包含在render_taglib.jar中。知道庫(kù)中所有可用標(biāo)簽的工作原理對(duì)理解門戶的呈視過程和骨架定制很重要。用得最多的呈現(xiàn)標(biāo)簽是<render:beginRender>與<render:endRender>、<render:writeAttribute>,以及<render:renderChild>與<render:pageUrl>。

            <render:beginRender>和<render:endRender>標(biāo)簽用于啟動(dòng)和結(jié)束一個(gè)門戶組件的呈現(xiàn)過程。門戶組件在層次上互相相關(guān)。例如,桌面包含頂級(jí)目錄。而該目錄又能包含任何數(shù)量的頁面或子目錄,子目錄又可以包含自己的portlet、頁面或者子目錄。門戶組件呈現(xiàn)就依據(jù)了這種層次結(jié)構(gòu)。嵌套在門戶 XML中的子組件被呈現(xiàn)在它們雙親的<render:beginRender>和 <render:endRender>標(biāo)簽之間。這兩個(gè)標(biāo)簽包含了開放和封閉的HTML元素,而在這些元素中嵌套的組件會(huì)呈現(xiàn)它們自己的HTML。

            <render:writeAttribute>標(biāo)簽要與<render:beginRender>標(biāo)簽一同使用。因?yàn)?lt;render:beginRender>標(biāo)簽呈現(xiàn)了組件的開放HTML,而<render:writeAttribute>標(biāo)簽則添加屬性到這個(gè)開放的HTML標(biāo)簽中。

            帶有子組件的組件,比如標(biāo)題欄和標(biāo)題欄按鈕,用<render:renderChild>標(biāo)簽呈現(xiàn)這些子組件。

            在呈現(xiàn)標(biāo)簽庫(kù)中,標(biāo)簽可以用來創(chuàng)建URL。雖然這些標(biāo)簽在骨架呈現(xiàn)時(shí)很有用,但是它們實(shí)際上可以在應(yīng)用程序的任何必要的地方使用。

            <render:pageUrl>標(biāo)簽用于生成一個(gè)能導(dǎo)航到特定頁面或目錄的URL,而<render:windowUrl>標(biāo)簽則是在指定了特定portel模式和/或狀態(tài)的情況下,生成一個(gè)能導(dǎo)航到特定portel的URL。<render:resourceUrl>標(biāo)簽則用于為資源建立一個(gè)URL,比如JavaScript文件或圖像。要生成一個(gè)允許提交請(qǐng)求的URL,則要用到<render:postbackUrl>標(biāo)簽。

            呈現(xiàn)順序和過程
            當(dāng)定制一個(gè)現(xiàn)有的骨架或創(chuàng)建自己的骨架時(shí),不僅理解骨架JSP的呈現(xiàn)順序非常重要,而且還要知道引用這些JSP的頻度。當(dāng)一個(gè)組件被呈現(xiàn)時(shí),就要引用到與它相關(guān)的骨架JSP文件。在這個(gè)JSP文件中,<render:beginRender>標(biāo)簽封裝了所有的用于呈現(xiàn)該組件開放部分的邏輯。記住,門戶組件是嵌套的,所有嵌套組件的骨架JSP文件的<render:beginRender>部分是合為一體的。這個(gè)過程一直延續(xù)到最后嵌套的組件的<render:beginRender>部分被呈現(xiàn)為止。到那時(shí),隨著層次的上移,每個(gè)骨架JSP文件再次被引用,而在此時(shí)就呈現(xiàn)位于<render:endRender>標(biāo)簽之間的內(nèi)容。由于這個(gè)原因,您會(huì)發(fā)現(xiàn)骨架JSP文件中的大部分邏輯都是被封裝在這些呈現(xiàn)標(biāo)簽中的。否則,每個(gè)組件的邏輯就會(huì)運(yùn)行兩次,而這種情況幾乎不可能是我們想要的結(jié)果。

            定制布局
            BEA提供了三種布局樣式,應(yīng)該可以包括絕大多數(shù)需要的布局樣式。然而,有時(shí)您還是需要?jiǎng)?chuàng)建定制布局,以獲得缺省情況下未能提供的結(jié)構(gòu)。要?jiǎng)?chuàng)建一個(gè)定制布局,首先需要復(fù)制一個(gè).layout文件以及與它相關(guān)的.html.txt文件。

            在.layout文件中,修改<netuix:layout>標(biāo)簽的適當(dāng)屬性,而把Layout 設(shè)置為markupType。然后添加并配置這個(gè)布局中可用的占位符。清單 1顯示了一個(gè)擁有四個(gè)占位符的定制布局。還要注意,已經(jīng)添加了占位符的width屬性。這在后面會(huì)用于呈現(xiàn)門戶中的HTML。

            清單 1. 有時(shí)您需要?jiǎng)?chuàng)建定制布局,以獲得缺省情況下未能提供的結(jié)構(gòu)。這個(gè)定置布局包括四個(gè)占位符,并且已經(jīng)添加了width屬性。



          <?xml version="1.0" encoding="UTF-8"?>

          <netuix:markupDefinition xmlns:netuix=

          "http://www.bea.com/servers/netuix/xsd/controls/

          netuix/1.0.0"

          xmlns:xsi=

          "http://www.w3.org/2001/XMLSchema-instance"

          xsi:schemaLocation="http://www.bea.com/

          servers/netuix/xsd/controls/netuix/

          1.0.0 markup-netuix-1_0_0.xsd">

          <netuix:locale language="en"/>

          <netuix:markup>

          <netuix:layout type="mainrightbar" title="Main

          and Right Bar Layout" description="Custom

          layout providing a main content window and

          three smaller windows on a right bar"

          htmlLayoutUri="/framework/markup/layout/

          mainrightbar.html.txt"markupType=

           "Layout" markupName="mainrightbar">

          <netuix:placeholder title="main"

          description="First placeholder in custom

          layout." markupType="Placeholder"

          markupName="main" width="75%">

          </netuix:placeholder>

          <netuix:placeholder title="right_one"

          description="Second placeholder in custom

          layout." markupType="Placeholder"

          markupName="right_one" width="25%">

          </netuix:placeholder>

          <netuix:placeholder title="right_two"

          description="Third placeholder in custom

          layout." markupType="Placeholder"

          markupName="right_two" width="25%">

                   </netuix:placeholder>

                   <netuix:placeholder title="right_three"

                      description="Fourth placeholder in custom

                      layout." markupType="Placeholder"

                      markupName="right_three" width="25%">

                   </netuix:placeholder>

                </netuix:layout>

             </netuix:markup>

          </netuix:markupDefinition>


            到這里,您應(yīng)該已經(jīng)明確您希望的定制布局看起來是什么樣子。在.html.txt文件中,修改HTML以形成選擇的表結(jié)構(gòu)。務(wù)必要使定義在.layout文件中的占位符數(shù)與placeholderTD類的<td>標(biāo)簽數(shù)一致。清單 2顯示了使用清單 1中布局的.html.txt文件。

            清單 2. 在 html.txt 文件中,您可以修改HTML以形成表結(jié)構(gòu)。本代碼顯示了在清單1 中使用的html.txt 文件。



          <table class="portalLayout" id="thePortalLayout" width="100%" height="100%">
           <tr>
            <td class="placeholderTD" valign="top" width="75%" rowspan="3">
            <placeholder number="0"/>
            </td>
            <td class="placeholderTD" valign="top" width="25%">
            <placeholder number="1"/>
            </td>
           </tr>
           <tr>
            <td class="placeholderTD" valign="top" width="25%">
            <placeholder number="2"/>
            </td>
           </tr>
           <tr>
            <td class="placeholderTD" valign="top" width="25%">
            <placeholder number="3"/>
            </td>
           </tr>
          </table>

            創(chuàng)建定制布局的最后一個(gè)步驟是創(chuàng)建一個(gè)支持定制布局的骨架JSP頁面。該骨架JSP頁面的名稱需要與<netuix:layout> 標(biāo)簽的類型屬性+ "layout.jsp"相匹配,除非設(shè)置了skeletonURI屬性。skeletonURI屬性允許您指定支持布局的骨架JSP文件的路徑和文件名。否則,框架會(huì)試圖用前面提到的方法在skeleton目錄中尋找JSP頁面。清單 3是支持定制布局的骨架JSP頁面。

            清單 3. 創(chuàng)建定制布局的最后一個(gè)步驟是創(chuàng)建一個(gè)支持定制布局的骨架JSP頁面。下面是支持我們所創(chuàng)建布局的骨架JSP頁面。


          <%@ page import="com.bea.netuix.servlets.
            controls.layout.PlaceholderPresentationContext,
            com.bea.netuix.servlets.controls.layout.
            LayoutPresentationContext, java.util.List"
          %>

          <%@ taglib uri="render.tld" prefix="render" %>
          <%
            LayoutPresentationContext layout = LayoutPresentationContext.
            getLayoutPresentationContext(request);
            List children = layout.getChildren(
            "layout:placeholder");%><render:beginRender>
          <!-- Begin Custom Layout -->
          <%
            if (children.size() > 0){
            PlaceholderPresentationContext ph = (PlaceholderPresentationContext)
            children.get(0);
          %>
            <table
              <render:writeAttribute name="id" value= "<%= layout.getPresentationId() %>"/>
            <render:writeAttribute name="class" value="<%= layout.getPresentationClass() %>" defaultValue="bea-portal-layout"/>
            <render:writeAttribute name="style" value="<%= layout.getPresentationStyle() %>"/>
            cellspacing="0">
           <tr>
          <!-- Begin Custom Layout Cell 1 -->
          <td rowspan="<%=children.size()%>" class="bea-portal-layout-placeholder-container" <render:writeAttribute name="width" value="<%= ph.getWidth() %>"/>
          <render:renderChild presentationContext="<%= ph %>"/>
            </td>
          <!-- End Custom Layout Cell -->
          <%
            if (children.size() > 1) {
             ph = (PlaceholderPresentationContext)
                children.get(1);
          %>
             <!-- Begin Custom Layout Cell 2 -->
               <td class="bea-portal-layout-placeholder-container"
                <render:writeAttribute name="width" value="<%= ph.getWidth() %>"/>>
          <render:renderChild presentationContext="<%= ph %>"/>
             </td>
              <!-- End Custom Layout Cell -->
          <%
             }
          %>
             </tr>
          <%
             for (int i = 2; i < 4; i++) {
               ph = (PlaceholderPresentationContext) children.get(i);
          %>
              <tr>
               <!-- Begin Custom Layout Cell 5 -->
                 <td class="bea-portal-layout-placeholder- ontainer"
                  <render:writeAttribute name="width" value="<%= ph.getWidth() %>"/>>
             <render:renderChild presentationContext="<%= ph %>"/>
               </td>
               <!-- End Custom Layout Cell -->
               </tr>
          <%
             }
          %>
             </table>
          <%
             }
          %>
          <!-- End Custom Layout -->
          </render:beginRender>
          <render:endRender>
          </render:endRender>

            定制菜單
            門戶中的菜單組件也可以基于align屬性來支持定制。它能夠以三種對(duì)齊方式來實(shí)現(xiàn)呈現(xiàn)目錄標(biāo)簽的定制骨架:左、中、右。您可以對(duì)BEA提供的任何默認(rèn)骨架進(jìn)行修改。但是,由于這是基本骨架JSP文件,任何對(duì)門戶的未來升級(jí)都會(huì)潛在地導(dǎo)致覆蓋已修改的JSP文件。出于這個(gè)原因,最好還是使用定制骨架。

            定制骨架可以通過復(fù)制門戶中的任何可用骨架來創(chuàng)建。只需簡(jiǎn)單地復(fù)制整個(gè)默認(rèn)骨架、重命名,然后做您想做的修改。我更愿意定制骨架只包含修改后的骨架JSP,并允許框架為任何遺留的JSP使用默認(rèn)的目錄。

            我們正在討論的修改了對(duì)齊方式的JSP頁面是singlelevelmenu.jsp。清單 4 顯示了這個(gè)修改后的JSP頁面。

            清單 4. 要?jiǎng)?chuàng)建定制菜單,您可以修改BEA提供的任何缺省骨架。簡(jiǎn)單地復(fù)制整個(gè)默認(rèn)骨架、重命名,然后做您想做的修改。我們正在討論的修改了對(duì)齊方式的JSP頁面是singlelevelmenu.jsp。下面是修改后的JSP頁面。


          <%@ page import="com.bea.netuix.servlets.controls.

             window.WindowPresentationContext,

             com.bea.netuix.servlets.controls.window.

             TitlebarPresentationContext, java.util.Iterator,

             com.bea.netuix.servlets.controls.page.

             PagePresentationContext,    com.bea.netuix.servlets.controls.page.

             BookPresentationContext,

             com.bea.netuix.servlets.controls.page.

             MenuPresentationContext,

             com.bea.netuix.servlets.controls.

             PresentationContext, java.util.List,

             com.bea.netuix.servlets.controls.window.

             WindowCapabilities" %>

          <%@ page session="false"%>

          <%@ taglib uri="render.tld" prefix="render" %>

          <%!

             static final String BOOK_CLASS =

                "bea-portal-book";

             static final String MENU_CLASS =

                BOOK_CLASS + "-menu-single";

             static final String MENU_CONTAINER_CLASS =

                MENU_CLASS + "-container";

             static final String MENU_ITEM_CLASS =

                MENU_CLASS + "-item";

             static final String

                MENU_ITEM_ACTIVE_CLASS=

                MENU_ITEM_CLASS + "-active";

             static final String MENU_BUTTONS_CLASS =

                MENU_ITEM_CLASS + "-buttons";

             static final String DESKTOP_BOOK_CLASS =

                "bea-portal-book-primary";

             static final String DESKTOP_MENU_CLASS =

                DESKTOP_BOOK_CLASS + "-menu-single";

             static final String

                DESKTOP_MENU_CONTAINER_CLASS =

                DESKTOP_MENU_CLASS + "-container";

             static final String

                DESKTOP_MENU_ITEM_CLASS =

                DESKTOP_MENU_CLASS + "-item";

             static final String

                DESKTOP_MENU_ITEM_ACTIVE_CLASS =

             DESKTOP_MENU_ITEM_CLASS + "-active";

             static final String

                DESKTOP_MENU_BUTTONS_CLASS =

                DESKTOP_MENU_ITEM_CLASS +

                "-buttons";

          %>

          <%

             BookPresentationContext book =

                BookPresentationContext.

                getBookPresentationContext(request);

             MenuPresentationContext menu =

                MenuPresentationContext.

                getMenuPresentationContext(request);

             String align = menu.getAlign();

            if (align == null) {

                align = "left";  

             }

             String menuContainerClass =

                MENU_CONTAINER_CLASS;

             String menuClass = MENU_CLASS;

             String menuItemClass = MENU_ITEM_CLASS;

             String menuItemActiveClass =

                MENU_ITEM_ACTIVE_CLASS;

             String menuButtonsClass =

                MENU_BUTTONS_CLASS;

             if (book.isDesktopBook())

             {

                menuClass = DESKTOP_MENU_CLASS;

                menuContainerClass =

                   DESKTOP_MENU_CONTAINER_CLASS;

                menuItemClass =

                   DESKTOP_MENU_ITEM_CLASS;

                menuItemActiveClass =

                   DESKTOP_MENU_ITEM_ACTIVE_CLASS;

                menuButtonsClass =

                   DESKTOP_MENU_BUTTONS_CLASS;

             }

             List children = menu.getChildren();

          %>

          <render:beginRender>

             <%-- Begin Single Level Menu --%>

             <div class="bea-portal-ie-table-buffer-div"

                align="<%=align%>">

                <table border="0" cellpadding="0"

                cellspacing="0" width="100%">

                   <tr>

                      <td class="<%= menuContainerClass %>"

                         nowrap="nowrap">

                         <ul

                            <render:writeAttribute name="id"

                               value="<%= menu.getPresentationId()

                               %>"/>

                            <render:writeAttribute name="class"

                               value="<%=

                               menu.getPresentationClass() %>"

                               defaultValue="<%=

                                  menuClass %>"/>

                            <render:writeAttribute name="style"

                               value="<%=

                               menu.getPresentationStyle()

                               %>"/>

                            ><%

                            // Only render tabs when in view mode

                            if (book.getWindowMode().

                               equals(WindowCapabilities.VIEW))

                            {

                               Iterator pages =

                                  book.getPagePresentationContexts().

                                  iterator();

                               while (pages.hasNext())

                               {

                                  PagePresentationContext pageCtx =

                                  (PagePresentationContext)

                                     pages.next();

                                  String activeImage =

                                     pageCtx.getActiveImage();

                                  String inactiveImage =

                                     pageCtx.getInactiveImage();

                                  String rolloverImage =

                                     pageCtx.getRolloverImage();

                                  if (!pageCtx.isHidden() &&

                                     pageCtx.isVisible())

                                  {

                                     if (pageCtx.isActive())

                                     {

                                        if (activeImage == null)

                                        {

                                           %><li class="<%=

                                           menuItemActiveClass

                                           %>"><span><%=

                                           pageCtx.getTitle()

                                           %></span></li><%

                                        }

                                        else if (rolloverImage == null)

                                        {

                                           %><li class="<%=

                                           menuItemActiveClass

                                           %>"><span><img

                                           src="<%= activeImage

                                           %>"></span></li><%

                                        }

                                        else

                                        {

                                           %><li class="<%=

                                           menuItemActiveClass

                                           %>"><span><img src=

                                           "<%= activeImage %>"

                                           longDesc="<%=

                                           rolloverImage %>">

                                           </span></li><%

                                        }

                                     }

                                     else

                                     {

                                        if (inactiveImage == null)

                                        {

                                           %><li class="<%=

                                           menuItemClass %>">

                                           <a href="<render:pageUrl

                                           pageLabel="<%=

                                           pageCtx.getDefinitionLabel()

                                           %>"/>"><%=

                                           pageCtx.getTitle()

                                           %></a></li><%

                                        }

                                        else if (rolloverImage == null)

                                        {

                                           %><li class="<%=

                                           menuItemClass %>">

                                           <a href="<render:pageUrl

                                           pageLabel="<%=

                                           pageCtx.getDefinitionLabel()

                                           %>"/>"><img src="<%=

                                           inactiveImage

                                           %>"></a></li><%

                                        }

                                        else

                                        {

                                           %><li class="<%=

                                           menuItemClass %>">

                                           <a href="<render:pageUrl

                                           pageLabel="<%=

                                           pageCtx.getDefinitionLabel()

                                           %>"/>"><img src="<%=

                                           inactiveImage %>"

                                           longDesc="<%=

                                           rolloverImage

                                           %>"></a></li><%

                                        }

                                     }

                                  }

                               }

                            }

          %>

                         </ul>

                      </td>

          <%

                      if (children != null && children.size() > 0)

                      {

          %>

                         <td class="<%= menuButtonsClass %>"

                            align="right" nowrap="nowrap">

          <%

                      }

          %>

                      </render:beginRender>

                      <render:endRender>

          <%

                      if (children != null && children.size() > 0)

                      {

          %>

                         </td>

          <%

                      }

          %>

                   </tr>

                </table>

             </div>

             <%-- End Single Level Menu --%>

          </render:endRender>

            下一步就是創(chuàng)建能在XML中指定align屬性而并不修改現(xiàn)有singlelevel.menu文件的菜單組件。通過創(chuàng)建單獨(dú)的菜單,我們就不會(huì)把自己限制到必須使用單一對(duì)齊方式的單個(gè)菜單。

            要?jiǎng)?chuàng)建一個(gè)新菜單,首先要復(fù)制singlelevel.menu。然后改變標(biāo)題、描述和markupName以滿足您的需要,并且添加一個(gè)align屬性。

            清單 5. 要?jiǎng)?chuàng)建一個(gè)新菜單,首先要復(fù)制singlelevel.menu。然后改變標(biāo)題、描述和markupName以滿足您的需要,并且添加一個(gè)align屬性。下面是一個(gè)右對(duì)齊的單級(jí)菜單。


          <?xml version="1.0" encoding="UTF-8"?>

          <netuix:markupDefinition xmlns:netuix=

             "http://www.bea.com/servers/netuix/xsd/controls/   netuix/1.0.0"

             xmlns:xsi="http://www.w3.org/2001/

             XMLSchema-instance"

             xsi:schemaLocation="http://www.bea.com/servers/   netuix/xsd/controls/netuix/1.0.0 markup-netuix-

             1_0_0.xsd">

             <netuix:locale language="en"/>

             <netuix:markup>

                <netuix:singleLevelMenu

                   title="Single Level Right Menu"

                   description="This menu provides a single level

                   of tabs, right aligned, used to navigate across             pages."

                   markupType="Menu" markupName=

                   "singleLevelRightMenu" align="right"/>

             </netuix:markup>

          </netuix:markupDefinition>

            要使用新創(chuàng)建的定制骨架,可以創(chuàng)建一個(gè)觀感(look-and-feel)文件,以便將這個(gè)骨架與所選擇的皮膚相關(guān)聯(lián)。觀感文件很容易創(chuàng)建和管理。在Workshop中,當(dāng)編輯一個(gè).portal文件時(shí),可以從File Menu中選擇Portal ' Manage Look And Feel Properties。

            定制Shell
            Web設(shè)計(jì)人員通常會(huì)傾向于使用左側(cè)導(dǎo)航欄提供給用戶一個(gè)集中的導(dǎo)航結(jié)構(gòu)。左側(cè)導(dǎo)航欄,或與之類似的導(dǎo)航欄,可以添加到一個(gè)定制shell中。Shell不一定只包含頁眉和頁腳。清單 6顯示了一個(gè)提供頁眉、頁腳和一個(gè)左側(cè)導(dǎo)航欄的shell例子。

            清單 6. 您可以在定制shell中添加導(dǎo)航欄。下面是一個(gè)提供頁眉、頁腳和一個(gè)左側(cè)導(dǎo)航欄的shell例子。


          <?xml version="1.0" encoding="UTF-8"?>

          <netuix:markupDefinition

             xmlns:netuix="http://www.bea.com/servers/netuix/   xsd/controls/netuix/1.0.0"

             xmlns:html="http://www.w3.org/1999/xhtml-   netuix-modified/1.0.0"

             xmlns:xsi="http://www.w3.org/2001/XMLSchema-   instance"

             xsi:schemaLocation="http://www.bea.com/servers/   netuix/xsd/controls/netuix/1.0.0 markup-netuix-   1_0_0.xsd">

             <netuix:locale language="en"/>

             <netuix:markup>

                <netuix:shell

                   title="Left Navigation Shell" description=

                   "A header, footer and left navigation pane

                   included in this shell." markupType="Shell"

                      markupName="leftNavigation">

                   <netuix:head/>

                   <netuix:body>

                      <netuix:header/>

                      <html:table style="vertical-align: top;

                         width: 100%;">

                         <html:tr>

                            <html:td style="vertical-align: top;

                               width: 1%;" valign="top">

                               <netuix:jspContent contentUri=

                                  "/framework/markup/shell/support/

                                  leftnavigation.jsp"/>

                            </html:td>

                            <html:td style="vertical-align: top;

                               width: 99%;" valign="top">

                               <netuix:break/>

                            </html:td>

                         </html:tr>

                      </html:table>

                   <netuix:footer/>

                   </netuix:body>

                </netuix:shell>

                </netuix:markup>

          </netuix:markupDefinition>

            清單 6中的定制shell是通過復(fù)制教程門戶中的leftPaneHeaderFooter.shell來創(chuàng)建的。選擇<html:td>標(biāo)簽后,也可以同樣地創(chuàng)建一個(gè)右側(cè)導(dǎo)航欄shell。<netuix:break>標(biāo)簽則能呈現(xiàn)門戶內(nèi)容。

            在<netuix:jspContent>標(biāo)簽中,會(huì)使用到一個(gè)leftnavigation.jsp。這個(gè)JSP頁面是在shell/support目錄下創(chuàng)建的,因?yàn)檫@個(gè)修改并不是針對(duì)骨架的。該JSP頁面使用可用的PresentationContexts來顯示模擬Main Book的一列鏈接。請(qǐng)參見清單 7。

            清單 7. 在 清單 6中,會(huì)引用到一個(gè)leftnavigation.jsp。這個(gè)JSP頁面是在shell/support目錄下創(chuàng)建的,因?yàn)檫@個(gè)修改并不是針對(duì)骨架的。該JSP頁面使用可用的PresentationContexts來顯示模擬Main Book的一列鏈接。

          <?xml version="1.0" encoding="UTF-8"?>

          <netuix:markupDefinition

             xmlns:netuix="http://www.bea.com/servers/netuix/   xsd/controls/netuix/1.0.0"

             xmlns:html="http://www.w3.org/1999/xhtml-   netuix-modified/1.0.0"

             xmlns:xsi="http://www.w3.org/2001/XMLSchema-   instance"

             xsi:schemaLocation="http://www.bea.com/servers/   netuix/xsd/controls/netuix/1.0.0 markup-netuix-   1_0_0.xsd">

             <netuix:locale language="en"/>

             <netuix:markup>

                <netuix:shell

                   title="Left Navigation Shell" description=

                   "A header, footer and left navigation pane

                   included in this shell." markupType="Shell"

                      markupName="leftNavigation">

                   <netuix:head/>

                   <netuix:body>

                      <netuix:header/>

                      <html:table style="vertical-align: top;

                         width: 100%;">

                         <html:tr>

                            <html:td style="vertical-align: top;

                               width: 1%;" valign="top">

                               <netuix:jspContent contentUri=

                                  "/framework/markup/shell/support/

                                  leftnavigation.jsp"/>

                            </html:td>

                            <html:td style="vertical-align: top;

                               width: 99%;" valign="top">

                               <netuix:break/>

                            </html:td>

                         </html:tr>

                      </html:table>

                   <netuix:footer/>

                   </netuix:body>

                </netuix:shell>

                </netuix:markup>

          </netuix:markupDefinition>

            定制皮膚和骨架
            顯示清單 7中的鏈接的JSP頁面要使用一些CSS樣式。由于我們無法確定最后會(huì)使用哪種觀感,因此我通過創(chuàng)建一個(gè)額外的CSS并在skin_custom.properties文件中引用它來擴(kuò)展缺省的皮膚。另外,這也保證了以后的升級(jí)不會(huì)覆蓋我的實(shí)現(xiàn)代碼。

            我們已經(jīng)談到了骨架JSP的較小修改,然而,要定制到何種程度并沒有什么限制。例如,門戶組件有一個(gè)orientation屬性。該屬性為對(duì)齊標(biāo)題欄組件呈現(xiàn)的地點(diǎn)提供了一種機(jī)制。您可以實(shí)現(xiàn)一個(gè)骨架,支持標(biāo)題欄呈現(xiàn)到portlet內(nèi)容窗口的四條邊之一:頂邊、右邊、底邊或左邊。清單 8顯示了一個(gè)支持頂邊和底邊方向的定制window.jsp例子。

            清單 8. 可以實(shí)現(xiàn)一個(gè)骨架來支持標(biāo)題欄呈現(xiàn)到portlet內(nèi)容窗口的四條邊之一:頂邊、右邊、底邊或左邊。下面是一個(gè)支持頂邊和底邊方向的定制window.jsp例子。

          <%@ page import="com.bea.netuix.servlets.>%&

             >%&controls.PresentationContext"%>>%&

          <%@ page import="com.bea.netuix.servlets.controls.>%&

             >%&application.DesktopPresentationContext"%>>%&

          <%@ page import="com.bea.netuix.servlets.controls.>%&

             >%&page.BookPresentationContext"%>>%&

          <%@ page import="com.bea.netuix.servlets.controls.>%&

             >%&page.PagePresentationContext"%>>%&

          <%@ page import="com.bea.netuix.servlets.controls.>%&

             >%&window.WindowPresentationContext"%>>%&

          <%@ page import="com.bea.netuix.servlets.manager.>%&

             >%&AppContext"%>>%&

          <%@ page import="com.bea.portlet.PageURL"%>>%&

          >%&

          <table class="leftnav-table">>%&

          <%>%&

             >%&AppContext appCtx = >%&

                >%&AppContext.getAppContext(request);>%&

                >%&DesktopPresentationContext desktopCtx = >%&

                >%&DesktopPresentationContext.>%&

                >%&getDesktopPresentationContext(request);>%&

                >%&BookPresentationContext bookCtx = >%&

                >%&desktopCtx.getBookPresentationContext();>%&

          >%&

                >%&PagePresentationContext childCtx = null;>%&

          >%&

                >%&List bookChildren = >%&

                >%&bookCtx.getPagePresentationContexts();>%&

          >%&

             >%&for (Iterator i = bookChildren.iterator(); >%&

                >%&i.hasNext();) {>%&

                >%&childCtx = (PagePresentationContext) i.next();>%&

                >%&String style = "leftnav-page";>%&

                >%&if (childCtx.isActive()) {>%&

                   >%&style = "leftnav-page-active";>%&

                >%&}>%&

          >%&

          %>>%&

                >%&<tr>>%&

                   >%&<td class="<%=style%>" nowrap>>%&

                   >%&<a href="<%=PageURL.createPageURL(>%&

                   >%&request, response, >%&

                   >%&childCtx.getDefinitionLabel()).>%&

                   >%&toString()%>"><%=childCtx.getTitle()%>>%&

                   >%&</a></td>>%&

                >%&</tr>>%&

          <%>%&

             >%&}>%&

          %>>%&

          </table>>%&

          >%&

          >%&

          >%&

          >%&

          >%&

          <%@ page import="com.bea.netuix.servlets.controls.>%&

             >%&portlet.PortletPresentationContext"%>>%&

          <%@ page import="com.bea.netuix.servlets.controls.>%&

             >%&window.WindowPresentationContext,>%&

             >%&com.bea.netuix.servlets.controls.window.>%&

             >%&TitlebarPresentationContext, >%&

             >%&java.util.List,>%&

             >%&java.util.Iterator, >%&

             >%&com.bea.netuix.servlets.controls.page.>%&

             >%&BookPresentationContext,>%&

             >%&com.bea.netuix.servlets.controls.window.>%&

             >%&WindowCapabilities">%&

          %>>%&

          <%@ page session="false"%>>%&

          <%@ taglib uri="render.tld" prefix="render" %>>%&

          >%&

          <%>%&

             >%&WindowPresentationContext window = >%&

                >%&WindowPresentationContext.>%&

                >%&getWindowPresentationContext(request);>%&

             >%&TitlebarPresentationContext titlebar = >%&

                >%&(TitlebarPresentationContext) >%&

                >%&window.getFirstChild("window:titlebar");>%&

             >%&boolean onBottom=false;>%&

          >%&

             >%&if (window instanceof PortletPresentationContext) {>%&

                >%&String orientation = ((>%&

                   >%&PortletPresentationContext)window).>%&

                   >%&getOrientation();>%&

                >%&onBottom = ((orientation != null) && >%&

                   >%&(orientation.equals("3")));>%&

             >%&}>%&

             >%&if (titlebar != null) {>%&

                >%&titlebar.setVisible(!onBottom);>%&

             >%&}>%&

             >%&boolean isMinimized = >%&

                >%&window.getWindowState().equals(>%&

                >%&WindowCapabilities.MINIMIZED);>%&

          %>>%&

          <render:beginRender>>%&

          <%>%&

             >%&final String expandWidth = "100%";>%&

          %>>%&

          >%&

          >%&

             >%&<%-- Begin Window --%>>%&

             >%&<div>%&

                >%&<render:writeAttribute name="id" value="<%= >%&

                   >%&window.getPresentationId() %>"/>>%&

                >%&<render:writeAttribute name="class" >%&

                   >%&value="<%= window.getPresentationClass() >%&

                   >%&%>" defaultValue="bea-portal-window"/>>%&

                >%&<render:writeAttribute name="style" value=>%&

                   >%&"<%= window.getPresentationStyle() %>"/>>%&

                >%&<render:writeAttribute name="width" >%&

                   >%&value="<%= window.isPacked() ? null : >%&

                   >%&expandWidth %>"/>>%&

             >%&>>%&

          <<%>%&

             >%&if (!onBottom) {>%&

          %>>%&

                >%&<render:renderChild presentationContext=>%&

                   >%&"<%= titlebar %>"/>>%&

          <<%>%&

             >%&}>%&

          %>>%&

          <>%&

                >%&<%-- Begin Window Content --%>>%&

                >%&<% if (! isMinimized )>%&

                >%&{>%&

                   >%&%><div>%&

                      >%&<render:writeAttribute name="class" >%&

                         >%&value="<%= window.>%&

                         >%&getContentPresentationClass() %>" >%&

                         >%&defaultValue="bea-portal-window->%&

                         >%&content"/>>%&

                      >%&<render:writeAttribute name="style" >%&

                         >%&value="<%= window.>%&

                      >%&getContentPresentationStyle() %>" />>%&

                      >%&><%>%&

                >%&}>%&

          %>>%&

                >%&</render:beginRender>>%&

                >%&<render:endRender>>%&

          <>%&

                >%&<% if (! isMinimized )>%&

                >%&{>%&

                   >%&%></div><%>%&

                >%&}>%&

                >%&if (titlebar != null) {>%&

                   >%&titlebar.setVisible(onBottom);>%&

                >%&}>%&

                >%&if (onBottom) {>%&

          %>>%&

                   >%&<render:renderChild presentationContext=>%&

                      >%&"<%= titlebar %>"/>>%&

          <>%&

          <<%>%&

                >%&}>%&

          %>>%&

             >%&</div>>%&

          <<%-- End Window --%>>%&

          </render:endRender>>%&

            既然已經(jīng)開發(fā)了這么多行代碼,讓我們來看看已經(jīng)完成的結(jié)果吧。圖 1顯示了一個(gè)門戶例子,其中使用到缺省的觀感。


          圖 1.
          這個(gè)示例門戶使用了缺省的觀感,它通過定制的樣式顯示shell 導(dǎo)航。


            您覺得我們做的工作比這個(gè)多嗎?我們確實(shí)做了很多。記住,我們的大部分定制都是在默認(rèn)觀感之外創(chuàng)建的,因?yàn)槲覀兿胍薷幕竟δ堋D 2中顯示的是一個(gè)使用了我們所有定制觀感的相同門戶。


          圖 2.
          這個(gè)門戶與顯示在圖 1中的門戶相同,但它使用合并了我們所有修改的觀感。

            好了,完成了。我們并沒有做所有的事。我只是添加了一個(gè)頁眉和頁腳,調(diào)節(jié)了CSS文件中的顏色和邊框。除此之外,代碼都是一樣的。

            BEA Portal UI Framework使開發(fā)人員和管理員能夠以他們覺得合適的方法定制一個(gè)門戶。對(duì)定制的唯一限制是您的想像力,或許還有您的藝術(shù)功底。

            關(guān)于作者
            David Hritz是NuWave Solutions, LLC的CTO。他還是Creating Web Portals with BEA WebLogic (March 2003)一書的合著者。您可以通過dhritz@nuwavesolutions.com聯(lián)系它。

            原文出處:http://www.fawcette.com/weblogicpro/2004_09/magazine/features/dhritz/

          posted on 2005-04-20 11:03 笨笨 閱讀(574) 評(píng)論(0)  編輯  收藏 所屬分類: J2EEALLWeblogic Portal
          主站蜘蛛池模板: 莱芜市| 灵武市| 和田市| 黎川县| 海门市| 伊宁县| 威远县| 盘山县| 宁阳县| 海阳市| 富阳市| 泰兴市| 山阴县| 佛教| 军事| 五华县| 宜都市| 时尚| 馆陶县| 乌苏市| 乐平市| 通道| 新野县| 礼泉县| 灵璧县| 奇台县| 远安县| 宽甸| 五莲县| 汝南县| 江津市| 河西区| 承德市| 元氏县| 东乡县| 莱州市| 漳州市| 宿松县| 大庆市| 宿迁市| 应用必备|