<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Terry.Li-彬

    虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
     

    上一篇講到當用戶在瀏覽器地址欄上輸入http://localhost:8080/后,經過幾次迭代,服務器最終處理的是http://localhost:8080/c/portal/update,那當服務器收到/c/portal/update的請求后做了什么動作,最后是怎么向瀏覽器發送網頁信息呢?

    1. 首先MainServlet接收這個請求,然后傳遞到LayoutAction。(具體怎么傳遞后續會介紹到)
    在struts-config.xml中有定義,表明有關"/portal/layout"的請求是由LayoutAction來處理的。而在tiles-def.xml中定義"/portal/layout"最終傳遞到"/portal/layout.jsp"。

    struts-config.xml
    ------------------------
    <action path="/portal/layout" type="com.liferay.portal.action.LayoutAction">
      <forward name="portal.layout" path="portal.layout" />
    </action>

    tiles-def.xml
    ------------------
    <definition name="portal.layout" extends="portal">
    <put name="content" value="/portal/layout.jsp" />
     <put name="selectable" value="true" />
    </definition>

    2. 下面分析LayoutAction的簡要流程

    LayoutAction.execute()
    --------------------------------
    ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
    Layout layout = themeDisplay.getLayout();

    /* 加入/html/portal/layout/view/portlet.jsp 到網頁*/
    incluldeLayoutContent(req, res, themeDisplay, layout);

    /* 加入/html/portal/layout.jsp 到網頁,先portlet.jsp,后layout.jsp*/
    return mapping.findForward("portal.layout");

    LayoutAction.includeLayoutContent()
    -----------------------------------------------------
    String path = StrutsUtil.TEXT_HTML_DIR;
    /* path = "/html" */

    path += PortalUtil.getLayoutViewPage(layout);
    /* path = "/html/portal/layout/view/portlet.jsp" */

    RequestDispatcher rd = ctx.getRequestDispatcher(path);
    rd.include(req, stringServletRes);

    可見兩個jsp文件是頁面的關鍵所在。

    /portal/layout/view/portlet.jsp
    -----------------------------------------
    <%
    String content = LayoutTemplateLocalUtil.getContent(layoutTypePortlet.getLayoutTemplateId(),
       false, theme.getThemeId());
    %>
    <%= RuntimePortletUtil.processTemplate(application, request, response, pageContext, content) %>

    /*****************************************************
    其中content的內容通過斷點調試可以知道(是什么時候生成的呢?)
    <div class="columns-2" id="content-wrapper">
      <table id="layout-grid">
        <tr>
          <td class="lfr-column thirty" id="column-1" valign="top">
            $processor.processColumn("column-1")
          </td>
          <td class="lfr-column seventy" id="column-2" valign="top">
            $processor.processColumn("column-2")
          </td>
        </tr>
      </table>
    </div>
    *****************************************************/
    /* RuntimePortletUtil.processTemplate()函數返回的是一個很長很長的字符串,就是最終用于顯示頁面上各個portlet的代碼,下面有分析 */

    RuntimePortletUtil.processTemplate()
    ------------------------------------------------------
    TemplateProcessor processor = new TemplateProcessor(ctx, req, res, portletId);
    VelocityContext vc = new VelocityContext();
    vc.put("processor", processor);
    // Velocity variables
    VelocityVariables.insertVariables(vc, req);
    vc.put("taglibLiferay", velocityTaglib);
    vc.put("theme", velocityTaglib);
    StringWriter sw = new StringWriter();
    Velocity.evaluate(vc, sw, RuntimePortletUtil.class.getName(), content);

    String output = sw.toString();
    /*****************************************************
    output的初始內容為:
    <div class="columns-3" id="content-wrapper">
      <table id="layout-grid">
        <tr>
          <td class="lfr-column thirty" id="column-1" valign="top">
            [$TEMPLATE_COLUMN_column-1$]
          </td>
          <td class="lfr-column thirty" id="column-2" valign="top">
            [$TEMPLATE_COLUMN_column-2$]
          </td>
          <td class="lfr-column thirty" id="column-3" valign="top">
            [$TEMPLATE_COLUMN_column-3$]
          </td>
        </tr>
      </table>
    </div>
    *****************************************************/

    Map columnsMap = processor.getColumnsMap();

    while (itr.hasNext()) {
      Map.Entry entry = (Map.Entry)itr.next();
      String key = (String)entry.getKey();
      String value = (String)entry.getValue();
      output = StringUtil.replace(output, key, value);
    }

    /*****************************************************
    如果首頁面上有四個portlet,名字為A,B,C,D,其中A在左邊一列上,B,C同在中間一列,D在右邊一列。則output的內容為:
    <div class="columns-3" id="content-wrapper">
      <table id="layout-grid">
        <tr>
          <td class="lfr-column thirty" id="column-1" valign="top">
            <div class="lfr-portlet-column" id="layout-column_column-1">
              [$TEMPLATE_PORTLET_A$]
            </div>
          </td>
          <td class="lfr-column thirty" id="column-2" valign="top">
            <div class="lfr-portlet-column" id="layout-column_column-2">
              [$TEMPLATE_PORTLET_B$]
              [$TEMPLATE_PORTLET_C$] 
            </div>
          </td>
          <td class="lfr-column thirty" id="column-3" valign="top">
            <div class="lfr-portlet-column" id="layout-column_column-3">
              [$TEMPLATE_PORTLET_D$] 
            </div>
          </td>
        </tr>
      </table>
    </div>
    *****************************************************/

    Map portletsMap = processor.getPortletsMap();
    itr = portletsMap.entrySet().iterator();
    while (itr.hasNext()) {
      StringMaker sm = new StringMaker();
      processPortlet(sm, ctx, req, res, portlet, queryString, columnId, columnPos,columnCount, null);
      output = StringUtil.replace(output, "[$TEMPLATE_PORTLET_" + portlet.getPortletId() + "$]", sm.toString());

    /*****************************************************
      這里每迭代一個portlet,output的內容中就添加了該portlet的view.jsp代碼段落,而且還會增加portlet的標準頭部和邊框,如最小化,關閉等按鈕及其對應的JavaScript代碼。
    *****************************************************/
    }

    return output;
    /* 這個output就是在portlet.jsp中要顯示的內容 */


    portal.jsp
    ------------
    <c:choose>
      <c:when test="<%= themeDisplay.isStateExclusive() %>">
        <%= request.getAttribute(WebKeys.LAYOUT_CONTENT) %>
      </c:when>
      <c:when test="<%= themeDisplay.isStatePopUp() %>">
        <liferay-theme:include page="portal_pop_up.jsp" />
      </c:when>
      <c:otherwise>
        <liferay-theme:include page="portal_normal.jsp" />
      </c:otherwise>
    </c:choose>

    在Liferay中沒有發現portal_normal.jsp的蹤影,發現portal_normal.vm似乎有點相關。portal_normal粉墨登場。

    portal_normal.vm
    -------------------------
    #parse ($init)
    <html dir="#language ("lang.dir")">
    <head>
      <title>$company_name - $the_title</title>
        $theme.include($top_head_include)
        #css ($css_main_file)
        #js ($js_main_file)
        #if ($company_logo != "")
          <style type="text/css">
            #banner .logo {background: url($company_logo) no-repeat;
                   height: ${company_logo_height}px;
                   width: ${company_logo_width}px; }
          </style>
        #end
    </head>

    <body class="$css_class">
    $theme.include($top_messages_include)
    <div id="wrapper">
      <div id="banner">
        <div id="banner-inner">
          <h1 class="logo">
            <a href="$company_url">$company_name</a>
          </h1>
          <div id="page-search">
            $theme.journalContentSearch()
          </div>
          #parse ("$full_templates_path/dock.vm")
            #if ($update_available_url)
              <div class="popup-alert-notice">
                <a class="update-available" href="$update_available_url">#language("updates-are-available-for-liferay")</a>
              </div>
            #end
            #if ($has_navigation)
              #parse ("$full_templates_path/navigation.vm")
            #end
          </div>
        </div>

        #if ($selectable)
          $theme.include($content_include)
        #else
          <div id="content-wrapper" class="login">
            $portletDisplay.recycle()
            $portletDisplay.setTitle($the_title)
            $theme.wrapPortlet("portlet.vm", $content_include)
          </div>
        #end

        <div id="footer">
          <p class="language">$theme.language()</p>
        </div>
    </div>

    $theme.include($bottom_ext_include)
    $theme.include($session_timeout_include)
    $theme.include($sound_alerts_include)

    </body>
    </html>

    可見關鍵是一些Velocity變量的值,例如$top_head_include。


    init.vm
    ----------
    #set ($bottom_ext_include = "$dir_include/common/themes/bottom.jsp")
    #set ($content_include = "$dir_include$tilesContent")
    #set ($session_timeout_include = "$dir_include/common/themes/session_timeout.jsp")
    #set ($sound_alerts_include = "$dir_include/common/themes/sound_alerts.jsp")
    #set ($top_head_include = "$dir_include/common/themes/top_head.jsp")
    #set ($top_messages_include = "$dir_include/common/themes/top_messages.jsp")

    可見$top_head_include就是top_head.jsp。

    top_head.jsp
    -------------------
    <%@ include file="/html/common/themes/top_js.jspf" %>
    <%@ include file="/html/common/themes/top_js-ext.jsp" %>
    portal/portal-web/docroot/html/common/themes/top_js.jspf
    <%
      String[] javaScriptFiles = PropsUtil.getArray(PropsUtil.JAVASCRIPT_FILES);
      for (int i = 0; i < javaScriptFiles.length; i++) {
    %>
    <script src="<%= themeDisplay.getPathJavaScript() %>/<%= javaScriptFiles[i] %>" 
    type="text/javascript"></script>
    <%
    }
    %>

    那javascriptFiles又如何得到的呢?

    portal.properties
    ------------------------
    javascript.files=\
            jquery/jquery.js,\
            jquery/cookie.js,\
         
            jquery/tabs.js,\
            \
            liferay/liferay.js,\
            liferay/browser.js,\
            liferay/util.js,\
            liferay/language.js,\
            liferay/layout.js,\
            \
            liferay/ajax.js,\
            liferay/animate.js,\
            liferay/auto_fields.js,\
            liferay/color_picker.js,\
            liferay/columns.js,\
            liferay/dock.js,\
            liferay/dynamic_select.js,\
            liferay/freeform.js,\
            liferay/layout_configuration.js,......

    另外還有一個很重要的properties文件值得關注:language.properties。好累啊,還有很多細節可以繼續挖掘,還涉及到Velocity的一些變量的操作,休息下先。

     

    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2177391

    posted on 2008-03-14 14:11 禮物 閱讀(1810) 評論(0)  編輯  收藏 所屬分類: Liferay
    主站蜘蛛池模板: 四虎永久在线精品免费观看视频 | 国产成人精品免费午夜app| 亚洲综合在线成人一区| 在线免费视频一区二区| jizz免费观看视频| 亚洲国产视频网站| 中文字幕日韩亚洲| 久草在视频免费福利| 精选影视免费在线 | 国产日本亚洲一区二区三区| 久久久久亚洲精品中文字幕| 91免费人成网站在线观看18| 一级特级女人18毛片免费视频| 亚洲精品亚洲人成在线麻豆| 亚洲一区二区三区乱码A| 日本免费一区二区在线观看| 一级毛片在线完整免费观看| 亚洲成a人片在线看| 亚洲AV综合色区无码一区| 国产精品视_精品国产免费| 亚洲最大免费视频网| 久久久久国色AV免费观看| 亚洲国产精品日韩av不卡在线| 亚洲成年轻人电影网站www| 亚洲 综合 国产 欧洲 丝袜 | 18禁超污无遮挡无码免费网站国产 | 男女污污污超污视频免费在线看| 亚洲视频一区在线观看| 国产成人精品日本亚洲专区 | 97国产在线公开免费观看| 性生大片视频免费观看一级| 亚洲av永久无码精品三区在线4| 亚洲精品乱码久久久久久按摩 | 奇米影视亚洲春色| 日本免费人成黄页在线观看视频| 99re视频精品全部免费| 成人自慰女黄网站免费大全| 黄色网页免费观看| 色天使色婷婷在线影院亚洲| 亚洲日本VA中文字幕久久道具| 亚洲成AV人片久久|