目标:Ofbiz皮肤完全自主定制;
前提:已经创建hello工程,针对hello应用进行定制开发;
注意:完成自主定制皮肤只针对具体应用。如果需要定制通用皮肤,header与footer可以完全定制,但左侧菜单与内容区域定制会受到较大的局限。
hello应用目录结构;
与kadmin主题目录结构:
分析:皮肤主题的开发与定制主要在themes/*下完成,但如果想完全自主定义,如二级菜单或者是内容显示区域,侧需要配合具体应用来完成。以下步骤先从themes目录下进行操作也定制;
定制要点:
1、从themes目录下复制一个主题重全名为kadmin;
2、修改kadmin/ofbiz-component.xml内容;
<ofbiz-component name="kadmin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd"> <!-- define resource loaders; most common is to use the component resource loader --> <resource-loader name="main" type="component"/> <!-- entity resources: model(s), eca(s), group, and data definitions --> <entity-resource type="data" reader-name="seed" loader="main" location="data/kadminThemeData.xml"/> <!-- web applications; will be mounted when using the embedded Jetty container --> <webapp name="kadmin" title="Kadmin" menu-name="secondary" server="default-server" location="webapp/kadmin" mount-point="/kadmin" app-bar-display="false"/> </ofbiz-component>
<entity-engine-xml> <VisualTheme visualThemeId="KADMIN" visualThemeSetId="BACKOFFICE" description="It's bizzness, it's bizzness time. I couldn't have said it better myself. This theme gets down"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_NAME" resourceValue="KADMIN" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_STYLESHEET" resourceValue="/bizznesstime/css/style.css" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_HELPSTYLESHEET" resourceValue="/bizznesstime/css/help.css" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_DOCBOOKSTYLESHEET" resourceValue="/bizznesstime/webapp/bizznesstime/css/docbook.css" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_HDR_JAVASCRIPT" resourceValue="/bizznesstime/js/application.js" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_SHORTCUT_ICON" resourceValue="/images/ofbiz.ico" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_HDR_IMAGE_URL" resourceValue="/images/ofbiz_logo.gif" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_HDR_TMPLT_LOC" resourceValue="component://bizznesstime/includes/header.ftl" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_FTR_TMPLT_LOC" resourceValue="component://bizznesstime/includes/footer.ftl" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_NAV_TMPLT_LOC" resourceValue="component://bizznesstime/includes/appbar.ftl" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_MSG_TMPLT_LOC" resourceValue="component://bizznesstime/includes/messages.ftl" sequenceId="01"/> <VisualThemeResource visualThemeId="KADMIN" resourceTypeEnumId="VT_SCREENSHOT" resourceValue="/bizznesstime/screenshot.jpg" sequenceId="01"/> </entity-engine-xml>这是一个资源文件,大体内容定义了包括主题的名称、类型、样式、脚本及flt模板文件。这些内容将在程序运行后写入到数据库visual_theme、visual_theme_resource、visual_theme_set三个表中,程序运行之后,将会读取数据库表的的对应信息,添加到页面中,如下所示:
( 注:sequenceId 的作用是针对 resourceTypeEnumId 的类型为同类型加以区分; 例 XML中如果有两个
resourceTypeEnumId=”VT_STYLESHEET”则其中一个的sequenceId=”01”则另一个为sequenceId=”02”)
2):includes
该文件夹主要包含该主题页面的头部,尾部,一级菜单,消息和关闭头部文件的 FTL;其中修改主题的页面都在这里修
改 。
4、打开header.flt文件,会看类似下面的语句<#if (requestAttributes.person)??><#assign person = requestAttributes.person></#if>,这是freemark标记语言,先略过,接下来下半部分会看到类似
<body>
<div id="wrapper">
……
这样的语句,这样相信很熟悉了,这是一个html页面定义的开始部分。接着往下看,会发现,这些body标签并没有关闭,开始觉得奇怪,但想想,这是一个头部的模块,还有其它部分的模块还没有加载完成,就明白了。细看header.ftl与footer.ftl与appbar.ftl代码,发现这些代码都可以完全自定义,可以使用自定义的样式与脚本实现不同效果。改着改着,发现问题来了,没找到menu与content的定义文件!看下图:
是的,在themes目录里没找到menu的定义ftl文件,因为不在这里定义,如果需要定义,只能对具体应用进行定义,不能对全部应用进行统一定义。
5、移步到具体应用程序文件夹hot-deploy/hello/widget/hello/CommonScreens.xml
我们已经知道main-decorator是主装饰模块,actions配置节是模块设置,widgets里是配置装饰器,我们在component://common/widget/CommonScreens.xml中找到GlobalDecorator的定义文件。其中有一段是这样的:
<!-- render appheader: both menu widget style and ftl template style menus are supported--> <section name="Render-App-Nav"> <condition> <not> <if-empty field="userLogin" /> </not> </condition> <widgets> <section> <condition> <not> <if-empty field="appheaderTemplate" /> </not> </condition> <widgets> <platform-specific> <html> <html-template location="${appheaderTemplate}" /> </html> </platform-specific> </widgets> <fail-widgets> <section> <condition> <not> <if-empty field="parameters.applicationTitle" /> </not> </condition> <widgets> <label style="apptitle">${parameters.applicationTitle}</label> </widgets> </section> <section> <condition> <not> <if-empty field="applicationMenuLocation" /> </not> </condition> <widgets> <include-menu name="${applicationMenuName}" location="${applicationMenuLocation}" /> </widgets> </section> </fail-widgets> </section> </widgets> <fail-widgets> <!-- better to just not include this, the CommonAppBarMenu doesn't show anything by default if the user isn't logged in, causing a funny empty menu: <include-menu name="CommonAppBarMenu" location="component://common/widget/CommonMenus.xml"/> --> </fail-widgets> </section>看其中这段:
<condition> <not> <if-empty field="appheaderTemplate" /> </not> </condition>
<condition> <not> <if-empty field="applicationMenuLocation" /> </not> </condition>
意思是说,如果存在applicationMenuLocation,则执行下面这段,
<widgets> <include-menu name="${applicationMenuName}" location="${applicationMenuLocation}" /> </widgets>
本篇结束
hello实例程序、themes主题包