当在Dockbar上点击Add->More...后,就进入了layout_configuration:

这也是一个portlet(Liferay内核中的一个特殊的portlet),portlet_id为87,参见liferay-portlet.xml:

  1. <portlet>
  2. <portlet-name>87</portlet-name>
  3. <icon>/html/icons/default.png</icon>
  4. <struts-path>layout_configuration</struts-path>
  5. <use-default-template>false</use-default-template>
  6. <show-portlet-access-denied>false</show-portlet-access-denied>
  7. <show-portlet-inactive>false</show-portlet-inactive>
  8. <private-request-attributes>false</private-request-attributes>
  9. <private-session-attributes>false</private-session-attributes>
  10. <render-weight>50</render-weight>
  11. <add-default-resource>true</add-default-resource>
  12. <system>true</system>
  13. </portlet>

这个portlet对应的页面在/html/portlet/layout_configuration/view.jsp中:

  1. <%@ include file="/html/portlet/layout_configuration/init.jsp" %>
  2. <c:if test="<%= themeDisplay.isSignedIn() && (layout != null) && (layout.isTypePortlet() || layout.isTypePanel()) %>">
  3. <%
  4. PortletURL refererURL = renderResponse.createActionURL();
  5. refererURL.setParameter("updateLayout", "true");
  6. %>
  7. <div id="portal_add_content">
  8. <div class="portal-add-content">
  9. <aui:form action='<%= themeDisplay.getPathMain() + "/portal/update_layout?p_l_id=" + plid + "&p_v_l_s_g_id=" + themeDisplay.getParentGroupId() %>' method="post" name="fm" useNamespace="<%= false %>">
  10. <aui:input name="doAsUserId" type="hidden" value="<%= themeDisplay.getDoAsUserId() %>" />
  11. <aui:input name="<%= Constants.CMD %>" type="hidden" value="template" />
  12. <aui:input name="<%= WebKeys.REFERER %>" type="hidden" value="<%= refererURL.toString() %>" />
  13. <aui:input name="refresh" type="hidden" value="<%= true %>" />
  14. <c:if test="<%= layout.isTypePortlet() %>">
  15. <div class="portal-add-content-search">
  16. <span id="portal_add_content_title"><liferay-ui:message key="search-applications-searches-as-you-type" /></span>
  17. <aui:input cssClass="lfr-auto-focus" id="layout_configuration_content" label="" name="layout_configuration_content" onKeyPress="if (event.keyCode == 13) { return false; }" />
  18. </div>
  19. </c:if>
  20. <%
  21. UnicodeProperties typeSettingsProperties = layout.getTypeSettingsProperties();
  22. Set panelSelectedPortlets = SetUtil.fromArray(StringUtil.split(typeSettingsProperties.getProperty("panelSelectedPortlets")));
  23. PortletCategory portletCategory = (PortletCategory)WebAppPool.get(company.getCompanyId(), WebKeys.PORTLET_CATEGORY);
  24. portletCategory = _getRelevantPortletCategory(permissionChecker, portletCategory, panelSelectedPortlets, layoutTypePortlet, layout, user);
  25. List categories = ListUtil.fromCollection(portletCategory.getCategories());
  26. categories = ListUtil.sort(categories, new PortletCategoryComparator(locale));
  27. int portletCategoryIndex = 0;
  28. Iterator itr = categories.iterator();
  29. while (itr.hasNext()) {
  30. PortletCategory curPortletCategory = (PortletCategory)itr.next();
  31. if (curPortletCategory.isHidden()) {
  32. continue;
  33. }
  34. request.setAttribute(WebKeys.PORTLET_CATEGORY, curPortletCategory);
  35. request.setAttribute(WebKeys.PORTLET_CATEGORY_INDEX, String.valueOf(portletCategoryIndex));
  36. %>
  37. <liferay-util:include page="/html/portlet/layout_configuration/view_category.jsp" />
  38. <%
  39. portletCategoryIndex++;
  40. }
  41. %>
  42. <c:if test="<%= layout.isTypePortlet() %>">
  43. <div class="portlet-msg-info">
  44. <liferay-ui:message key="to-add-a-portlet-to-the-page-just-drag-it" />
  45. </div>
  46. </c:if>
  47. <c:if test="<%= !layout.isTypePanel() && permissionChecker.isOmniadmin() %>">
  48. <%
  49. Group controlPanelGroup = GroupLocalServiceUtil.getGroup(company.getCompanyId(), GroupConstants.CONTROL_PANEL);
  50. long controlPanelPlid = LayoutLocalServiceUtil.getDefaultPlid(controlPanelGroup.getGroupId(), true);
  51. PortletURLImpl pluginsURL = new PortletURLImpl(request, PortletKeys.PLUGIN_INSTALLER, controlPanelPlid, PortletRequest.RENDER_PHASE);
  52. pluginsURL.setPortletMode(PortletMode.VIEW);
  53. pluginsURL.setRefererPlid(plid);
  54. %>
  55. <p class="lfr-install-more">
  56. <aui:a href="<%= pluginsURL.toString() %>" label="install-more-applications" />
  57. </p>
  58. </c:if>
  59. </aui:form>
  60. </div>
  61. </div>
  62. </c:if>
  63. <c:if test="<%= !themeDisplay.isSignedIn() %>">
  64. <liferay-ui:message key="please-sign-in-to-continue" />
  65. </c:if>

而这里面所有portlet以及分类都是用循环所包含进来的,见第55行:

所以每个Portlet分类以及其中的portlet都在/html/portlet/layout_configuration/view_category.jsp中:

  1. <%@ include file="/html/portlet/layout_configuration/init.jsp" %>
  2. ...
  3. <div class="lfr-add-content <%= layout.isTypePortlet() ? "collapsed" : "" %>" id="<portlet:namespace />portletCategory<%= portletCategoryIndex %>">
  4. <h2>
  5. <span><%= Validator.isNotNull(externalPortletCategory) ? externalPortletCategory : LanguageUtil.get(pageContext, portletCategory.getName()) %></span>
  6. </h2>
  7. <div class="lfr-content-category <%= layout.isTypePortlet() ? "aui-helper-hidden" : "" %>">
  8. ...
  9. <c:choose>
  10. <c:when test="<%= layout.isTypePortlet() %>">
  11. <div
  12. class="lfr-portlet-item <c:if test="<%= portletLocked %>">lfr-portlet-used</c:if> <c:if test="<%= portletInstanceable %>">lfr-instanceable</c:if>"
  13. id="<portlet:namespace />portletItem<%= portlet.getPortletId() %>"
  14. instanceable="<%= portletInstanceable %>"
  15. plid="<%= plid %>"
  16. portletId="<%= portlet.getPortletId() %>"
  17. title="<%= PortalUtil.getPortletTitle(portlet, application, locale) %>"
  18. >
  19. <p><%= PortalUtil.getPortletTitle(portlet, application, locale) %> <a href="javascript:;"><liferay-ui:message key="add" /></a></p>
  20. </div>
  21. <input id="<portlet:namespace />portletItem<%= portlet.getPortletId() %>CategoryPath" type="hidden" value="<%= divId.toString().replace(':', '-') %>" />
  22. ...
  23. <div
  24. class="lfr-portlet-item lfr-archived-setup"
  25. id="<portlet:namespace />portletItem<%= portletItem.getPortletItemId() %>"
  26. instanceable="<%= portletInstanceable %>"
  27. plid="<%= plid %>"
  28. portletId="<%= portlet.getPortletId() %>"
  29. portletItemId="<%= portletItem.getPortletItemId() %>"
  30. title="<%= HtmlUtil.escape(portletItem.getName()) %>"
  31. >
  32. <p><%= HtmlUtil.escape(portletItem.getName()) %> <a href="javascript:;"><liferay-ui:message key="add" /></a></p>
  33. </div>
  34. <input id="<portlet:namespace />portletItem<%= portletItem.getPortletItemId() %>CategoryPath" type="hidden" value="<%= divId.toString().replace(':', '-') %>" />
  35. <%
  36. }
  37. %>
  38. </c:when>
  39. <c:otherwise>
  40. <div>
  41. <a href="<liferay-portlet:renderURL portletName="<%= portlet.getRootPortletId() %>" windowState="<%= WindowState.MAXIMIZED.toString() %>"></liferay-portlet:renderURL>"><%= PortalUtil.getPortletTitle(portlet, application, locale) %></a>
  42. </div>
  43. </c:otherwise>
  44. </c:choose>
  45. <%
  46. }
  47. %>
  48. </div>
  49. </div>
  50. <input id="<portlet:namespace />portletCategory<%= portletCategoryIndex %>CategoryPath" type="hidden" value="<%= newCategoryPath.replace(':', '-') %>" />
  51. <%
  52. }
  53. %>

从这里很容易看出,每个分类对应的代码段是第6行开始,它的id为id="<portlet:namespace />portletCategory<%= portletCategoryIndex %>,而每个portlet的对应的代码段是从第17行开始,它对应的id为id="<portlet:namespace />portletItem<%= portlet.getPortletId() %>

我们来验证下:比如我们为了如下的显示:

对应的,因为layout_configuration对应的portletId为87(上文已说),对应的<portlet:namespace>为_87_。这个分类是第9个分类,而这个分类中包含的2个Portlet对应的id分别为34,67,见liferay-display.xml:

  1. ..
  2. <category name="category.shopping">
  3. <portlet id="34" />
  4. <portlet id="67" />
  5. </category>
  6. ..

所以,分类的id为_87_portletCategory9,而两个portlet的id分别为_87_portletItem67和_87_portletItem34,对比页面源码,果然这样:

本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/900924,如需转载请自行联系原作者

Liferay layout_configuration 分析相关推荐

  1. Liferay MinifierFilter的研究

    大家都知道,在Web应用程序中,为了节省网络开销,往往吧多个小的js文件整合成一个大的js文件,吧多个小的css文件整合成一个大的js文件,这样原本N次小文件的请求就可以合并成单次的网络请求.最典型的 ...

  2. 去掉主页 breadcrumb导航条上的Liferay字样

    需求: 我们公司需要从breadcrumb上去掉最前面的那个Liferay,如图: 我们想只保留"Welcome",而去掉前面的"Liferay" 问题分析: ...

  3. Liferay Portal Json Web Service 反序列化漏洞(CVE-2020-7961)

    之前在CODE WHITE上发布了一篇关于Liferay Portal JSON Web Service RCE的漏洞,之前是小伙伴在处理这个漏洞,后面自己也去看了.Liferay Portal对于J ...

  4. Liferay 部署war包时候的deployDirectory 细节分析

    引入: 在上文中,我们从宏观上讲解了Liferay部署war包的动作是如何触发监听器并且完成部署过程的,但是其中最核心的一块deployDirectory我们没讲,它的作用是当有了临时目录并且已经把w ...

  5. Liferay 控制面板在指定文件夹添加Basic Document流程分析

    结论: 当在Liferay中用管理员登录,导航到控制面板->Documents and Media ,在指定文件夹下添加BasicDocument时,服务器做了如下的事情: (1) 在DLFIL ...

  6. Liferay研究-smilingleo

    http://blog.csdn.net/smilingleo/article/details/1859908 Liferay研究之一:Ext环境的搭建 本篇主要介绍如何搭建Ext开发环境.网上也有很 ...

  7. Liferay Portal学习笔记-coldTear

    [原创]Liferay Portal学习笔记(一):安装 一. 简单安装 1)下载并安装 JDK1.5 1.  下载并安装 Windows Platform J2SE(TM) Development ...

  8. Liferay中使用portlet:resourceURL触发serveResource()方法调用的细节

    引入: 大家在Portlet 开发中经常用到<portlet:resourceURL>,而大体上都会去调用相应的serveResource()方法,这个过程虽然大家都清楚,但是能弄明白这个 ...

  9. Java中String连接性能的分析

    总结:如果String的数量小于4(不含4),使用String.concat()来连接String,否则首先计算最终结果的长度,再用该长度来创建一个StringBuilder,最后使用这个String ...

  10. [Liferay] Liferay 实现单点登录 - OpenLDAP

    [Liferay] Liferay 实现单点登录 - OpenLDAP Liferay 的单点登录绝对是个难啃的骨头,更何况网上能搜到的基本都是些滥竽充数的文章,很不负责任. 于是在自己搭通单点登录一 ...

最新文章

  1. detector = dlib.get_frontal_face_detector()获取人脸框的用法
  2. 【计算机网络】数据链路层 : 差错控制 ( 纠错编码 | 海明码 | “海明码“ 原理 | “海明码“ 工作流程 | 确定校验啊位数 | 确定校验码和数据位置 | 求校验码值 | 检错纠错 )★
  3. python可以播放音乐吗_详解python播放音频的三种方法
  4. win7讲述人安装包_文件夹选项与讲述人
  5. 【转载】数字签名是什么?
  6. RPi 2B python opencv camera demo example
  7. 每日Ubuntu小技巧 - 使用TeamViewer连接远程桌面
  8. Visual Studio 2017 离线安装方式
  9. Java并发编程笔记
  10. 经典排序算法(二十二)--图书馆排序(Library Sort)
  11. SQL 删除重复记录,并保留其中一条
  12. html源代码中 图像的属性标记,HTML图像标签img和源属性src及Alt属性、宽高、对齐...
  13. linux进阶-PHP加速器
  14. 所属学院mid函数计算机学院,EXCEL答案公式==
  15. 树莓派Ubuntu21.04,树莓派4b/4g,Python3.9.5搭建PyTorch
  16. ubuntu 16.04 单用户____修改忘记密码
  17. 阿里云服务器以及CDN支持IPV6的方法
  18. 「生产技改工程」智能变电站辅助监控系统
  19. 高通平台SSC架构-sensor学习
  20. linux双屏鼠标移,ubuntu如何实现双屏显示

热门文章

  1. 图像裁剪插件--cropper的基本使用
  2. MapGIS K9三维TDE平台实现动态光标效果
  3. 如何学习平面设计色彩搭配原理
  4. 远程办公软件:TeamViewer使用评测与安装
  5. 【CGAL_空间搜索与排序】3D快速求交和距离计算
  6. VC打印机使用 win95环境的下例子测试
  7. 演示面阵激光雷达的工作原理
  8. MySQL主从配置(Django实现主从配置读写分离)
  9. 远程桌面管理工具源码
  10. win64位MySQL5.7.32下载、安装及配置