kapok

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

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

          標題:門戶用戶界面:讓應用程序更吸引人
          ——使用WebLogic Portal輕松創建引人注目的用戶界面
          瀏覽次數: 961 時間:2004-10-29
          作者:David Hritz

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

            門戶用戶界面框架組件
            用戶界面框架有很多組件。BEA開箱即用地實現了的所有用戶界面組件。這些缺省的組件對某些應用程序來說已經足夠了,但我們還是很可能需要某個級別的定制。在深入討論框架和定制之前,先讓我們簡略地看一下每個用戶界面組件以及它們之間的關系。

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

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

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

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

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

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

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

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

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

            布局(Layout)和占位符(placeholder) 門戶的頁面結構基于它的布局。布局是一種簡單的表結構,用來把門戶中的組件置入到稱為占位符的獨立單元中。當創建您自己的布局時,BEA會提供布局樣式供您使用。這些樣式會描述門戶如何放置占位符。

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

            菜單(Menus) 兩個菜單之一可以在目錄導航的門戶中使用。這些菜單提供了稍微有點不同的導航級別。這些菜單系統的缺省功能可以通過修改相關的skeleton文件來定制。

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

            皮膚的命名:

          • 如果沒有指定,就使用/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/。
            門戶骨架呈現標簽庫
            門戶從選擇的骨架中呈現出來。每個門戶 XML組件會映射到一個骨架JSP文件。骨架JSP文件根據一個門戶標簽庫來呈現這些組件。這個標簽庫就是門戶骨架呈現標簽庫,它包含在render_taglib.jar中。知道庫中所有可用標簽的工作原理對理解門戶的呈視過程和骨架定制很重要。用得最多的呈現標簽是<render:beginRender>與<render:endRender>、<render:writeAttribute>,以及<render:renderChild>與<render:pageUrl>。

            <render:beginRender>和<render:endRender>標簽用于啟動和結束一個門戶組件的呈現過程。門戶組件在層次上互相相關。例如,桌面包含頂級目錄。而該目錄又能包含任何數量的頁面或子目錄,子目錄又可以包含自己的portlet、頁面或者子目錄。門戶組件呈現就依據了這種層次結構。嵌套在門戶 XML中的子組件被呈現在它們雙親的<render:beginRender>和 <render:endRender>標簽之間。這兩個標簽包含了開放和封閉的HTML元素,而在這些元素中嵌套的組件會呈現它們自己的HTML。

            <render:writeAttribute>標簽要與<render:beginRender>標簽一同使用。因為<render:beginRender>標簽呈現了組件的開放HTML,而<render:writeAttribute>標簽則添加屬性到這個開放的HTML標簽中。

            帶有子組件的組件,比如標題欄和標題欄按鈕,用<render:renderChild>標簽呈現這些子組件。

            在呈現標簽庫中,標簽可以用來創建URL。雖然這些標簽在骨架呈現時很有用,但是它們實際上可以在應用程序的任何必要的地方使用。

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

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

            定制布局
            BEA提供了三種布局樣式,應該可以包括絕大多數需要的布局樣式。然而,有時您還是需要創建定制布局,以獲得缺省情況下未能提供的結構。要創建一個定制布局,首先需要復制一個.layout文件以及與它相關的.html.txt文件。

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

            清單 1. 有時您需要創建定制布局,以獲得缺省情況下未能提供的結構。這個定置布局包括四個占位符,并且已經添加了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>


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

            清單 2. 在 html.txt 文件中,您可以修改HTML以形成表結構。本代碼顯示了在清單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>

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

            清單 3. 創建定制布局的最后一個步驟是創建一個支持定制布局的骨架JSP頁面。下面是支持我們所創建布局的骨架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屬性來支持定制。它能夠以三種對齊方式來實現呈現目錄標簽的定制骨架:左、中、右。您可以對BEA提供的任何默認骨架進行修改。但是,由于這是基本骨架JSP文件,任何對門戶的未來升級都會潛在地導致覆蓋已修改的JSP文件。出于這個原因,最好還是使用定制骨架。

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

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

            清單 4. 要創建定制菜單,您可以修改BEA提供的任何缺省骨架。簡單地復制整個默認骨架、重命名,然后做您想做的修改。我們正在討論的修改了對齊方式的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>

            下一步就是創建能在XML中指定align屬性而并不修改現有singlelevel.menu文件的菜單組件。通過創建單獨的菜單,我們就不會把自己限制到必須使用單一對齊方式的單個菜單。

            要創建一個新菜單,首先要復制singlelevel.menu。然后改變標題、描述和markupName以滿足您的需要,并且添加一個align屬性。

            清單 5. 要創建一個新菜單,首先要復制singlelevel.menu。然后改變標題、描述和markupName以滿足您的需要,并且添加一個align屬性。下面是一個右對齊的單級菜單。


          <?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>

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

            定制Shell
            Web設計人員通常會傾向于使用左側導航欄提供給用戶一個集中的導航結構。左側導航欄,或與之類似的導航欄,可以添加到一個定制shell中。Shell不一定只包含頁眉和頁腳。清單 6顯示了一個提供頁眉、頁腳和一個左側導航欄的shell例子。

            清單 6. 您可以在定制shell中添加導航欄。下面是一個提供頁眉、頁腳和一個左側導航欄的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是通過復制教程門戶中的leftPaneHeaderFooter.shell來創建的。選擇<html:td>標簽后,也可以同樣地創建一個右側導航欄shell。<netuix:break>標簽則能呈現門戶內容。

            在<netuix:jspContent>標簽中,會使用到一個leftnavigation.jsp。這個JSP頁面是在shell/support目錄下創建的,因為這個修改并不是針對骨架的。該JSP頁面使用可用的PresentationContexts來顯示模擬Main Book的一列鏈接。請參見清單 7。

            清單 7. 在 清單 6中,會引用到一個leftnavigation.jsp。這個JSP頁面是在shell/support目錄下創建的,因為這個修改并不是針對骨架的。該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樣式。由于我們無法確定最后會使用哪種觀感,因此我通過創建一個額外的CSS并在skin_custom.properties文件中引用它來擴展缺省的皮膚。另外,這也保證了以后的升級不會覆蓋我的實現代碼。

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

            清單 8. 可以實現一個骨架來支持標題欄呈現到portlet內容窗口的四條邊之一:頂邊、右邊、底邊或左邊。下面是一個支持頂邊和底邊方向的定制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>>%&

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


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


            您覺得我們做的工作比這個多嗎?我們確實做了很多。記住,我們的大部分定制都是在默認觀感之外創建的,因為我們想要修改基本功能。圖 2中顯示的是一個使用了我們所有定制觀感的相同門戶。


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

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

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

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

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

          posted on 2005-04-20 11:03 笨笨 閱讀(574) 評論(0)  編輯  收藏 所屬分類: J2EEALLWeblogic Portal
          主站蜘蛛池模板: 建昌县| 阳东县| 临西县| 昌图县| 新沂市| 磐安县| 敦煌市| 金坛市| 卢氏县| 高青县| 图们市| 乳山市| 陆川县| 惠安县| 漳浦县| 崇礼县| 和硕县| 越西县| 南宁市| 体育| 石嘴山市| 惠来县| 玛纳斯县| 福泉市| 东台市| 黎平县| 富民县| 含山县| 浪卡子县| 博爱县| 蓬溪县| 榆林市| 伊川县| 大竹县| 左贡县| 定日县| 盐亭县| 从江县| 广宁县| 柳州市| 恩平市|