Developing a Liferay Theme

作为一个开发者,你需要你的站点准确有效的传达你的想法。你不希望你设计的网站限制用户从你的内容总收到影响。这就是主题发挥作用的地方。主题允许你创造性的控制和讲述通过你的站点想要讲述的故事。他们可以是你控制网站的外观和感觉。后续为详细介绍。

当你接近主题设计时,记住目标受众,你试图传达的信息,以及网站的目的。主题设计有助于回答这些问题。

次学习路线使用Freemarker模板语言为Liferay's Lunar Resort开发一套主题。你将学会如何使用CSS设计你的主题,怎样响应移动设备,怎样使用Bootstrap's and Font Awesome's 图标在主题中,和如何实现可配置的主题设置。

在开始之前,需要确保你已经安装Liferay开发环境。Liferay IDE 或 Liferay Developer Studio的安装可查看其他文档。也可以选择其他开发工具,但是Liferay提供的开发工具是他们专门为开发Liferay而设计的,开发过程中可很自然的使用它。因为在整个学习过程中会做大量更改部署,所以需要确认你的Portal已经开启开发模式。可以在为主题开启开发模式查看如何开启开发模式。

下面我们将开始学校开发主题:

设置主题

一、             简介

在此部分,将创建Lunar Resort主题的基础。我们将学校创建一个主题的流程和需要的目录结构。最后,我们将修改模板文件portal_normal.ftl和navigation.ftl使其符合Lunar Resort主题的样子。

我们将通过此指南模拟完成一个如下样式的主题:

开始之前,你资源下载在此处下载在联系中需要的资源文件,解压到你的目录中

二、             创建一个主题项目

在后续的学习过程中需要根据指令操作Liferay IDE 或 Liferay Developer Studio。

  1. Select File → New → Liferay Plugin Project.
  2. 在项目向导中, Project name输入 lunar-resort-theme ,Display name输入Lunar Resort Theme build type选择Ant选择适当的Plugins SDK和匹配的Liferay runtime。(此处开发过程中由于出现问题,所以开发是选择为Maven)
  3. 3.       Plugin type选择Theme然后点击Next
  4. Theme parent 选择_styled Theme framework选择Freemarker ,然后点击Finish
   

 

+$$$

Note: 第一次创建项目时,请确保处于联网状态,在后台Liferay's Plugins SDK 下载几个必须得JAR文件,这使初始插件SDK下载小,但它可能需要几分钟的时间来创建您的第一个项目。随后的项目几乎立刻就被创造出来了。

$$$

我们将在左边的项目资源管理器中看见创建好的项目,我们创建的是基于Liferay's _styled theme的一个空的Liferay主题

而不是从头开始建立一个主题,它是使用Liferay基地主题为出发点,确保完全兼容的最佳实践。我们对主题的修改将直接覆盖Liferay's _styled theme的默认设置

三、             设置主题目录结构

当项目创建完成时目录结构应该和以下一样:(此处为Ant构建工具时,Maven有所区别)

主题是基于他们的基础主题的不同,在我们创建项目的时候,我们选择了_styled主题,A copy of this theme's code, therefore, exists in most of these folders.这将确保你页面的所有元素的默认样式。在编写自定义主题是,只需要定义当前主题和基础主题不同的地方即可。

我们所有修改的文件都应该放到_diffs目录中,然后将其转移到父目录中的文件。因此,在_diffs文件夹中的目录必须是父目录的镜像,如果目录不匹配,你所有的修改将无法被应用,为了保持基础目录不变,我们只需要将我们修改或增加的文件放到_diffs目录中。

在最佳实践中,所有的CSS styling 都应在_diffs/css/ 目录的custom.css文件中,因为他是最后加载的,所有放置在custom.css文件中的样式都将覆盖其父主题的样式,保持所有的样式在一个文件中,将更加有利于维护工作的开展。

现在我们已经熟悉了主题的结构和开发流程,我们将开始开发自己的主题

  1. 选择_diffs文件夹然后右键,选择 New → Folder.
  2. 2.       选择_diffs文件夹输入css文件名然后点击Finish
  3. 重复步骤12创建images和templates 目录
  4. 将custom.css文件从docroot/css/ 目录复制到_diffs/css.所有的修改都将放到_diffs 目录的中custom.css镜像文件中。
  5. 复制_aui_variables.scss到diffs/css目录中
  6. 将文件init_custom.ftl, navigation.ftl, and portal_normal.ftl从目录docroot/templates 复制到目录diffs/templates

现在开发主题的起点已经完成,在进入下一个阶段前还有一些额外的工作需要做,

  1. 打开文件_aui_variables.scss输入一下内容

$bkColor: #FFF;

$themeMainColor: #DF5946;

  1. 从下载好的资源文件中将文件 lunar-resort-logo.png从目录/images复制到主题项目的_diffs/images
  2. 最后将下载好的资源文件的中为guestbook-portlet.war部署到liferay项目中

四、             文件portal_normal.ftl的Html结构

Liferay门户中所有的portlets都是通过模板文件portal_normal.ftl渲染的。

下图反应了HTML结构完成的样子

HTML结构分散在三个部分中:Banner(横幅),Content,和Footer。

  • Banner包含the logo for the site(网站Logo), its name(网站名字), the page title(页面标题), and the main navigation(主导航)。
  • Content <div>包含网站面包屑和页面中Portlets。
  • Footer包含'powered-by Liferay' 和social media links(社交媒体链接)。

这三个部分都都在id 为“wrapper”的<div>中,这个用来调整整个站点的宽度

五、             修改主题模板

在这部分,我们将添加一些内容到文件portal_normal.ftl 和navigation.ftl中,以匹配我们最后完成的Lunar Resort主题效果

  1. 打开文件portal_normal.ftl,然后找到<body class="${css_class}">,修改为如下代码:
  2. 在文件portal_normal.ftl中找到如下代码并删除
<body class="${css_class} dockbar-split">
<#if !is_signed_in>
<a href="${sign_in_url}" data-redirect="${is_login_redirect_
    required?string}" id="sign-in" rel="nofollow">${sign_in_text}</a>
</#if>

默认的 Sign In 链接会被去掉,但是会在下个步骤中替换他

  1. 找到代码<@liferay.dockbar />并删除<#if is_signed_in> 和</#if>标签保留他们之间包裹的内容,

变更会不管是登录还是未登录都可以看到Dockbar ,如果未登录,Dockbar 将简单显示登录的链接,这个将方便以后学习过程

  1. 将后面的代码插入到id为content的<div>标签的结束标签</div>之前
<#if the_title != "Reservation">
<div id="reserveBtnWrapper">
<span id="reserveBtn">
<a href="/web/guest/reservation">Make Your Reservation!</a>
</span>
</div>
</#if>

本次添加的链接在保留在主题 Lunar Resort的每一个页面,除了保留页面。现在你只有一个默认的Welcome页面,不用担心,一会将使用资源导入(Resources Importer)添加剩下的页面,如果现在点击该链接将放回一个错误信息。

  1. 保存文件

接下来我们将修改导航

  1. 打开文件navigation.ftl将内容替换为如下内容
<nav class="${nav_css_class}" id="navigation" role="navigation">
<ul aria-label="<@liferay.language key="site-pages" />" 
    role="menubar">
<#list nav_items as nav_item>
<#assign nav_item_attr_has_popup = "" />
<#assign nav_item_attr_selected = "" />
<#assign nav_item_css_class = "lfr-nav-item" />
<#assign nav_item_caret = "" />
<#assign nav_item_link_css_class = "" />
 
<#if nav_item.isSelected()>
<#assign nav_item_attr_selected = "aria-selected='true'" 
                />
<#assign nav_item_css_class = "${nav_item_css_class} 
                selected active" />
</#if>
<#if nav_item.hasChildren()>
<#assign nav_item_attr_has_popup = 
                "aria-haspopup='true'" />
<#assign nav_item_caret = "<b class='icon-caret-down'>
</b>" />
<#assign nav_item_css_class = "${nav_item_css_class} 
                dropdown" />
<#assign nav_item_link_css_class = "dropdown-toggle" />
</#if>
 
<li ${nav_item_attr_selected} class="${nav_item_css_class}" 
            id="layout_${nav_item.getLayoutId()}" role="presentation">
<a aria-labelledby="layout_${nav_item.getLayoutId()}" 
                ${nav_item_attr_has_popup} 
                class="${nav_item_link_css_class}" 
                href="${nav_item.getURL()}" ${nav_item.getTarget()} 
                role="menuitem"><span>${nav_item.icon()} 
                ${nav_item.getName()} ${nav_item_caret}</span></a>
 
<#if nav_item.hasChildren()>
<ul class="dropdown-menu child-menu" role="menu">
<#list nav_item.getChildren() as nav_child>
<#assign nav_child_attr_selected = "" />
<#assign nav_child_css_class = 
                            "lfr-nav-item" />
 
<#if nav_item.isSelected()>
<#assign nav_child_attr_selected 
                                    = "aria-selected='true'" />
<#assign nav_child_css_class = 
                                    "selected" />
</#if>
 
<li class="${nav_child_css_class}" 
                                id="layout_${nav_child.getLayoutId()}" 
                                ${nav_child_attr_selected} 
                                role="presentation">
<a aria-labelledby=
                                    "layout_${nav_child.getLayoutId()}" 
                                    href="${nav_child.getURL()}" 
                                    ${nav_child.getTarget()} 
                                    role="menuitem">
                                    ${nav_child.getName()}</a>
</li>
</#list>
</ul>
</#if>
</li>
</#list>
</ul>
</nav>

这些修改的代码在原代码的基础了做了一些补充,最主要的变化在于修改的子菜单的classes:子菜单现在已经可以使用,另外一个名称为.active 的class将在当前页面高亮显示.

  1. 保存文件

现在已经有了一个封装好的模板,然后我们将部署主题

  1. 启动服务,在资源管理器中选择主题,然后拖拽到服务上部署主题
  2. 主题部署完成后,登录门户,进入到管理员->站点管理->页面
  3. 确定公共页面选中,然后滚动滚动条到可用主题标题
  4. 选中Lunar Resort theme 前面的单选按钮,然后保存

现在主题已经应用,然而在查看之前需要在做一些其他工作

  1. 选择右边菜单中的logo,取消显示站点名称
  2. 6.       点击选择文件,选择主题目录中的_diffs/images目录下的lunar-resort-logo.png文件
  3. 点击保存
  4. 当看到页面提示操作成功时,即可返回欢迎页面查看。

The theme appears broken at the moment, but this is to be expected. In the sections that follow, you'll fix this. This shows you the starting point the base theme provides.

You've successfully installed and applied your new theme! In the next section you'll learn how to import resources for your theme.

为主题导入资源

一、             简介

我们已经为 Lunar Resort创建了主题,但是目前看起来比较空洞。我们需要一些默认的内容使其在第一次安装的时候就看起来比较漂亮。这里有两种方法为主题导入资源,创建一个archive.lar文件或者在目录结构中创建一个包括布局和内容的sitemap.json文件

两种方法都是不错的选择,但是使用LAR方法有几个缺点。LARs是依赖于版本的,所以当我们将Liferay升级到新版后将意味着重新创建LAR。而且针对内容的任何修改都必须重新创建LAR文件

然而sitemap.json文件可以工作在任何Liferay版本中,我们只需要简单重新部署就可以发布我们变更。

在这部分我们将学校如何使用sitemap.json文件作为 Lunar Resort 主题的资源导入者。为了使用资源导入者,我们首先需要创建适当的目录结构。

二、             设置资源到如的目录

一个空的resources-importer已经创建,而不需要们再单独的创建每一个目录和文件,首先我们需要删除已有的resources-importer目录

  1. 删除主题目录中docroot/WEB-INF/src目录已有的resources-importer目录,将其替换为学习资源中的resources-importer目录

变更后的Resources Importer将使用如下目录结构组织资源文件

主题资源将被组织成documents and media files and web content articles,结构和模板在journal 目录对应的文件夹中

web content articles目录可以编辑和放置HTML或XML文件,图片文件放到document_library/documents文件夹,在web上下文中应用时使用如下代码

         src= "[$FILE=filename.filetype$]"

现在已经完成大部分网页内容所需要的准备工作,对应一下更加复杂的内容必须使用结构和模板,以下为几个额外的需要准备的步骤

对于carousel ,web内容被添加到自己专有的目录中,carousel 包含在journal/articles/目录.结构在/structures目录,模板位于/templates 目录并被放置到他自己专有的carousel 目录.完成后的目录结构如下图

目前创建的目录结构是网页内容公认的结构。

三、             创建sitemap.json

sitemap.json 文件定义了网站中网页内容布局、页面和portlets。作为文件的扩展名,sitemap.json 使用了JSON语法,所以如果熟悉JSON语法的话可以很容易的操作sitemap ,如果不熟悉JSON语法也不用担心后续会详细介绍sitemap

至于之前复制resources-importer 文件夹的时候已经创建了sitemap.json文件,所以此处不用重新创建。

以下代码为使用默认布局和填充页面添加的Welcome和关于我们页面

{
        "layoutTemplateId": "1_column",
        "layouts": [
                {
                        "name": "Welcome",
                        "title": "Welcome",
                        "friendlyURL": "/home",
                        "columns": [
                                [
                                        "carousel.xml",
                                        "Welcome to the Lunar Resort.html",
                                        "Amenities.html",
                                        "2 column description.html"
                                ]
                        ]
                },
                {
                        "name": "About Us",
                        "title": "About Us",
                        "friendlyURL": "/about-us",
                        "columns": [
                                [
                                        "About Us Info.html"
                                ]
                        ]
                }

sitemap 开始时为页面定义了一个默认的布局模板ID。我们可以从Liferay bundle目录的layouttpl 文件夹中找到。然后页面在sitemap中引用布局并组织页面,然后页面给出了name(名字)、title(标题)和friendly URL(友好的URL)

然后网页内容被组织到columns 部分,Columns 指出了布局模板的列,由于Welcome页面使用1_column 布局,layoutTemplateId 不需要明确指定,由于页面是用一列布局,网页内容文章都放在同一个括号内[。如在一个网络内容文章中的图像,您可以通过资源导入中的文件名引用Web内容。

一下的布局为,使用Rover Racing 子页面和填充页面增加的Activities 页面

{
"name": "Activities",
"title": "Activities",
"friendlyURL": "/activities",
"columns":[
            [
                "Activities Info.html",
                "Activities Links.html"
            ]
],
"layouts":[
{
    "name": "Rover Racing",
    "title": "Rover Racing",
    "friendlyURL": "/rover-racing",
    "columns": [
        [
            "Rover Racing Article.html"
        ]
    ]
},

可以看出创建在layouts 中创建子页面和创建父页面具有相同的语法,子页面的layouts配置放置在父页面的配置中

以下代码为定义了在布局中添加了两个portlets 的页面

{
    "name": "Collaboration",
    "title": "Collaboration",
    "friendlyURL": "/collaboration",
    "layoutTemplateId": "2_columns",
    "columns": [
        [
            {
            "portletId": "36"
            }
        ],
        [
            {
            "portletId": "115"
            }
        ]
    ]
}

Portlets 像网页内容一样定义在模板columns 中,只是语法上稍微有点变化,他们是引用portlet ID,可以在Liferay bundle中的portlet-custom.xml文件中找到,由于不是使用默认的布局,所以需要设置layoutTemplateId

以下代码为创建一个在导航栏上隐藏的页面,页面包括一个网页内容和一个自定义的portlet。

{
    "name": "Reservation",
    "title": "Reservation",
    "friendlyURL": "/reservation",
"hidden": "true",
    "columns":[     
            [
                    "Reservation Form.html",
                    {
                    "portletId": "guestbook_WAR_guestbookportlet"
                    }
            ]
    ]
 
}

自定义的Portlet和核心的Portlet定义方式相同,自定Portlet的ID在他们自己的portlet.xml文件中,

四、             配置liferay-plugin-package.properties

在这部分我们将配置Resources Importer中的liferay-plugin-package.properties文件

  1. 打开主题目录中WEB-INF目录下的liferay-plugin-package.properties文件

默认情况下,开发模式需要开启后面这行代码resources-importer-developer-mode-enabled=true,这个确保主题资源每次部署是都能即时查看,但是在生产模式是禁止开启次配置,

由于主题的资源将直接导入到站点,而不是一个站点模板,您需要添加两个附加属性。

  1. 添加如下两行代码到文件最后
resources-importer-target-class-name=com.liferay.portal.model.Group
resources-importer-target-value=Guest

The first property sets the type of portal entity to write the resources to, which is the site in this case. The second property sets the name of the portal entity to write the resources to, which is set to the Guest group in this case, so the resources will be visible on the public pages. It's important to note that you should never set the resources-importer-target-class-name=com.liferay.portal.model.Group property in a production environment. Instead you should remove the property, which will import the resources to the site template.在生产模式需要去掉此属性

  1. 取消一下注释并保存文件
required-deployment-contexts=\
    resources-importer-web
  1. 重新部署主题并在浏览器中查看

在继续开发之前注释如下代码

required-deployment-contexts=\
    resources-importer-web
 
resources-importer-target-class-name=com.liferay.portal.model.Group
resources-importer-target-value=Guest

通过CSS设计主题风格

一、             简介

之前,我们为Lunar Resort构建了主题并导入了内容,但是最终结果取看起来比较平庸。所有工作只留下一个不和风格的主题,后续将使用CSS设计主题风格

二、             设置自定义CSS

在添加CSS到主题前,需要完成几个前期的步骤。

  1. 打开_diffs/css/目录中的custom.css文件

我们将一步步的添加CSS,直到看到和设想的HTML图片一样的页面.可以再次参考一下图片:

这个图片很好的表示了添加CSS的路线

  1. 替换custom.css 内容为一下代码

/* This file allows you to override default styles in one central location for easier upgrade and maintenance. */

@import "compass";

@import "mixins";

@import "aui_variables";

html {

height: 100%;

body {

@include background-image(linear-gradient(to bottom,

rgba(0,196,255,1), rgba(0, 196, 255, 0.3),

rgba(238, 231, 0, 0)));

background-repeat: no-repeat;

height: 100%;

/*-------------------Admin Menus------------------------*/

.nav-account-controls{

.user-avatar .dropdown-menu, .admin-links .dropdown-menu,

.dockbar-user-notifications .dropdown-menu,

.my-sites .dropdown-menu, .sign-in a{

background-color: $themeMainColor;

}

.user-avatar .dropdown-toggle, .admin-links

.dropdown-toggle, .dockbar-user-notifications

.dropdown-toggle, .my-sites .dropdown-toggle,

.sign-in a{

background-color: $themeMainColor;

&:hover{

background-color: #00C4FB;

}

}

}

/*---------Add, Edit, and Preview Controls---------*/

.nav-add-controls{

#_145_addPanel, #_145_previewPanel,

#_145_editLayoutPanel {

background-color: $themeMainColor;

&:hover {

background-color: #00C4FB;

}

}

.page-edit-controls, .site-add-controls,

.page-preview-controls, .toggle-controls{

border-radius:6px;

}

}

/*--- Return Body styling for popup menus back to normal --- */

&.portal-popup {

background-image:none;

}

}

/* ---------- Wrapper ---------- */

/* ---------- Banner ---------- */

/* ---------- Content ---------- */

/* ---------- Footer ---------- */

}

Liferay支持 SASS (Syntactically Awesome Style Sheets)。SASS允许使用嵌套,使我们的代码保持简洁和很好的结构。它也允许在CSS中声明变量是CSS更容易维护。

You can read more about SASS here.

在代码中,一些初始样式被添加到站点背景、编辑控制、Dockbar、以及一些入口。随着compass 和mixins 的导入,_aui_variables.scss也被导入,因此在custom.css 文件中可以使用其中定义的变量

此样式为站点背景添加了渐变,并保留的弹出的窗口的样式

三、             设计页面wrapper

Wrapper 是一个包含主题元素的容器,他使用定位和样式使样式主题构成一个整体。我们可以是使用Wrapper为主题定义尺寸和背景

添加以下代为到Wrapper部分

#wrapper {
    
    margin: 0 auto;
    max-width: 1000px;
    padding:0;
    position:relative;

从包含在Wrapper中的Banner、Content和Footer部分后添加结束标签}

CSS使用了SASS变量$bkColor来设置Wrapper的背景颜色,使其和渐变颜色有所区分,更重要的是他为主题设置了宽度(width )和外边距(margins )。

作为设计选择,为Wrapper设置宽度(max-width: 1000px;),居中(margin: 0 auto;),对于浏览器相对布局。此设计允许渐变背景在超过max-width的浏览器中显示,如果在大于max-width的浏览器中显示主题,不用担心在主内容的两边看到坏点,你总是想在设计主题时保持用户体验。

使用max-width属性设置宽度,使其很灵活。在一段的学习路径的一部分,这将让主题缩小规模较小的设备,相反的使用width属性,宽度将固定不可变

  1. 保存文件后从导航进入到欢迎页面查看效果

效果如下

四、             设计页面banner

Banner包含了主题头部的元素,这部分是站点访问者访问站点的时候首先看到的

  1. 将以下代码添加到custom.css文件中的Banner部分
#banner {
    
 
    #heading {
        padding: 0 4%;
 
        .site-title {
            .logo {
                padding-bottom: 16px;
            }
        }
 
        .page-title {
            color: $themeMainColor;
            font-style: oblique;
            text-transform: uppercase;
        }
    }
 
    /* ---------- Main Navigation ---------- */
 
    #navigation {
        
        display: block;
        position: relative;
        z-index: 1;
 
        .active{
            
> a {
                    color: #FFF;
                }
        }        
 
        .dropdown-menu li {
            background: #00ACFF;
            border-width: 0;
            margin: 0;
            position: relative;
 
&:after, &:before {
                border-width: 0;
            }
 
            a {
                color: #FFF;
 
&:hover {
                    background: rgba(0, 0, 0, 0) none repeat scroll 0 0;
                }
            }
        }
 
        li {
            margin: 0 4px;
            padding: 15px 10px;
            position: absolute;
 
&:hover {
                
 
                .child-menu {
                    display: block;
                    margin-top: 0;
                }
 
                a {
                    color: #FFF;
                    text-decoration: none;
                }
            }
        }
 
        ul {
            li {
&:hover {
                
                    .child-menu {
                        display: block;
                        padding: 0;
                        li {
                            
&:hover {
                                
                            }
                        }
                        a {
                            color: #FFF;
                            margin: -10px;
                            text-decoration: none;
                        }
                    }
                }
            }
        }
 
> ul > li {
            display: inline-block;
            font-size: 1.2em;
            position: relative;
 
            a {
                color: #FFF;
                padding: 15px 10px;
            }
        }
    }
}

导航栏以list形式格式化,并放到logo下面,他被放置到一个和logo比较接近的红色bar内,为了进一步将导航的颜色与主题的其余部分联系起来,当活动和悬停时,导航项目被赋予了蓝色背景。以下为目前的效果

五、             设计页面content-div

Content<div>用来设置主题中内容部分的位置和尺寸。目前内容<div>紧贴着Wrapper的边缘,使主题看起来很密集的感觉,现在我们将给内容设置一部分空间

  1. 添加以下代码到文件custom.css 文件的Content部分
#content {
    
    padding: 0px 20px;
 
    /* ---------- Carousel ---------- */
    .carousel {
        z-index: 0;
    }
 
    /*------Activities------*/
    .img:hover {
        opacity: 0.5;
    }
 
    /*------Out of This World------*/
    #columnLeft { 
        font-size: 36px; 
        line-height: 60px;   
        text-align: center;
        color: $themeMainColor;
    }
 
    #columnRight {
        font-size: 16px;
        line-height: 30px;            
        color: #696969;
    }
 
    /*------Reserve Button------*/
    #reserveBtnWrapper {
        margin-left: auto;
        margin-right: auto;
        padding-bottom: 25px;
        width: 300px;
 
        #reserveBtn {
            
            border-radius: 10px;                    
            color: #FFF;
            font-size: 1.5em;
            height: 62px;
            margin: 30px;
            padding: 10px 0;
 
&:hover {
                    
                }
 
                a {
                    border-radius: 10px;                        
                    color: #FFF;
                    padding: 9px 10px;
                    text-decoration: none;
                }
        }
    }
 
    /*--Portlet styles---*/
    .portlet {
        .portlet-title {
            img {
                display: none;
            }
        }
    }
}

在Wrapper边缘中的Content<div>添加相似的内编剧(padding),为相似的网页内容文件添加相似的样式和删除portlets的icons,

The carousel has been given some styling as well. It's been centered and some spacing has been added between the breadcrumbs and the carousel. The carousel has also been given a z-index of 0, so the navigation shows above it. Save the file and navigate to the Welcome page.

  1. 保存文件刷新页面查看效果

六、             设计页面footer

当你创建一个主题,你想页面看起来像整个图片。Footer看起来应该像图片的结束部分,在这种情况下,找到一个方法来统一主题与footer的设计是很好的,在这种情况下,它的外观应该与导航栏相似。

  1. 添加如下代码到文件custom.css的Footer部分然后保存它
footer{
    
    padding: 35px;
        .powered-by {
            color: #FFF;
            float: right;
            margin-top: 0;
        }
}

现在我们已经为footer设置了和导航相似的样式,并且为内容设置了更多的空间,'powered-by' 链接设置为和导航链接相似的样式。目前Footer的内容比较稀少,在后续会继续修改。

到这一点,你的造型一直专注于宏观图片,处理页面较大的元素。下一步你会探讨微画一点,把你的造型在个人门户。

七、             设计自定义portlets

如果你点击Make Your Reservation 链接,站点将显示一个预定的表格。

Guestbook portlet目前看起来比较简单,现在将改变他,是他和页面的其他元素比较相似,我们只需要知道已经存在的classes并且覆盖它

  1. 登录管理员账号,点击也没按底部的Make Your Reservation链接
  2. 点击 Guestbook portlet的齿轮图标选择外观和风格
  3. 选择窗体头部的高级样式(Advanced Styling )标签页
  4. 在头部蓝色高亮区域,可看见如下信息

现在我们可以看见Guestbook portlet的class为.guestbook-portlet。他遵循一种简单的规则:和portlet名字相同,我们可以为Guestbook portlet编写自己的CSS在高级样式部分,单位为了有很好的项目组织,我们将样式放到custom.css文件中

  1. 打开文件custom.css然后添加以下代码到#content样式的结束标签 } 之前
/*---------Guestbook Portlet Styles------------*/
.guestbook-portlet {
    
    border: 2px solid #50A2F6;
    border-radius: 25px;
    color: #FFF;
    max-width: 100%;
    padding: 30px;
}

这给出多种选择,但主题可以做更多的事情。背景颜色和导航的底部相似,但是文本在表格中有点无法辨认。如果你没有添加任何数据到guestbook,你将无法看到表格元素。如果你还没添加数据将在Main guestbook 中添加两条数据并保存它。现在就可以看见表格数据了。现在可以看见背景颜色和两条数据链接有点不协调。为了改变guestbook 样式的其他部分,你需要知道elements or classes.

大多数浏览器允许你检查页面元素查看HTML。使用内置的浏览器工具,您可以检索类和元素名称的其余部分

  1. 使用浏览器的开发者工具查看table 元素th 元素td元素的css名字
  2. 添加如下代码到guestbook 部分的padding: 30px;后面然后保存文件
.table {
    th {
        
    }
 
    td {
        
        color: #000;
    }
}
 
.portlet-title-text {
    display: block;
    font-size: 1.3em;
}
 
.aui-search-bar .field {
    border-radius: 25px;
    margin-top: 10px;
}

使用浏览器开发人员工具查看其它部分的classes,已经添加到页面包括标题和搜索栏,刷新后页面如下

八、             使用Bootstrap Styles

自从Liferay Portal 6.2主题基于 Bootstrap 2.3.2,在编辑 buttons, forms, and layouts等标签时,推荐使用Bootstrap 处理主题

You can view Bootstrap's Base CSS here.

也许你没有意识到,但是导入的网页内容文章已经使用的Bootstrap 标签样式,如下:

<form class="form-horizontal">
<fieldset>
<legend>Reservation Form</legend>
<div class="control-group">
<label class="control-label" for="inputName">Name</label>
<div class="controls">
<input type="text" id="inputName" placeholder="Enter your
                  Name here" required="required">
</div>
</div>
<div class="control-group">
<label class="control-label" for="inputEmail">Email</label>
<div class="controls">
<input type="email" id="inputEmail" placeholder="Enter your
              E-Mail here" required="required">
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Submit</button>
</div>
</div>
</fieldset>
</form>

This form follows Bootstrap's horizontal form example. The form inputs are extended even further, using Bootstrap's invalid inputs markup. For example, by setting the type for the E-mail input to email you are able to get validation for the field!

Bootstrap makes it easy for you to get a consistent look to your theme's UI in a short amount of time.

A step-by-step approach to CSS allows you to handle it with ease and keep track of your progress. In the next portion of the Learning Path you'll create the social media links for the Lunar Resort.(不翻译了,大体意思是讲解上面代码用到的Bootstrap,和使用Bootstrap可以是开发简单)

在主题中使用bootstrap和font-awesome-icons

一、             简介

我们创建了一个主题,导入资源和使用CSS自定义外观和感觉。现在我们将学校怎样使用Liferay绑定包中icons(图标)为Lunar Resort添加一个友情链接

Bootstrap 和Font Awesome icons已经绑定到Liferay的包中,可以直接作为主题的资源使用。每一个icons库都提供了一个独特的样式以供选择。任何情况下,要使用icons只需要将元素的class设置为icon的名字即可

所有可用的Bootstrap icons及其名字都可以在Github repository找到

同样所有可用的Font Awesome icons及名字都可以在他们的Github repository中找到

在这个部门我们将使用Font Awesome's icons为Lunar Resort添加一个友情链接,这只是一种选择,我们可以使用Bootstrap实现同样的功能

二、             在主题创建一个社交媒体链接(友情链接)

后面我们将在Footer中添加友情链接

  1. 打开文件portal_normal.ftl.
  2. 在<footer>标签中,在<p class="powered-by">之前添加如下代码

<div class="social-media-wrapper">

<h2 class="nav-heading">

Follow Us

</h2>

<ul>

<li>

<div id="facebook"><a class="icon-facebook"

href="http://www.facebook.com/pages/Liferay/45119213107"

target="_blank"><span class="hide">Facebook</span></a></div>

</li>

<li>

<div id="twitter"><a class="icon-twitter"

href="http://www.twitter.com/liferay"

target="_blank"><span class="hide">Twitter</span></a></div>

</li>

<li>

<div id="linked-in"><a class="icon-linkedin"

href="http://www.linkedin.com/company/83609"

target="_blank"><span class="hide">LinkedIn</span></a></div>

</li>

<li>

<div id="youtube"><a class="icon-youtube"

href="http://www.youtube.com/user/liferayinc"

target="_blank"><span class="hide">YouTube</span></a></div>

</li>

<li>

<div id="google-plus">

<a class="icon-google-plus"

href="https://plus.google.com/+liferay/posts"

target="_blank"><span class="hide">Google</span></a></div>

</li>

</ul>

</div>

  1. 保存文件

每一个友情链接都有一个Font Awesome brand icon,Font Awesome为每种图标提供了两种选择。

  1. 一种选择,其中的品牌标志是在一个固定的位置,由空像素,与一个边界。这让你移动的标志和边界作为一个整体,但不给你的位置或造型的标志本身的控制。
  1. 一组图标的品牌标志没有一个边界。这允许你的位置和风格的标志,并创建自己的边界。

我们需要设置友情链接的背景颜色和logo的位置。如果看见的是是由于logo是使用空的背景元素,而底部的红色背景直接透过背景显示出来了。这种情况就不适合使用这种方式了

使用第二个选项,无国界的品牌标志,品牌标志是在<a>标签有自己的风格。他们然后放置在<DIV>标签,这是造型的背景颜色。这可以让你定位的标志,它自己的颜色,同时也让你控制的背景和边界的大小和颜色。

现在我们为友情链接添加以下CSS

  1. 打开文件custom.css,在footer中.powered-by之前添加如下代码
.social-media-wrapper {
    h2 {
        color: #FFF;
        text-align: center;
    }
 
    li {
        border-radius: 6px;
        display: inline-block;
        font-size: 31px;                        
        margin-top: 11px;
        padding: 3px;
 
        a {
            border-radius: 6px;
            color: #FFF;
            padding: 7px 8px;
&:hover {
                    text-decoration: none;
                }
        }
    }
 
    ul {
        margin: auto;
        text-align: center;
        li { 
            div{                                    
                border: 1px solid #CD4023;
                border-radius: 6px;
                height: 39px;
                padding-top: 7px;
                width: 44px;
&:hover {
                    border-bottom: 1px solid white;
                }
            }
            #facebook{
                
            }
            #twitter{
                
            }
            #linked-in{
                
            }
            #youtube{
                
            }
            #google-plus{
                
            }                    
        }
    }
}
  1. 保存文件
  2. 刷新欢迎页面可以看见footer部分为如下显示

制作可配置的主题

一、             简介

主题设置可以允许管理员在不修改任何代码的情况下控制页面元素的展示。

主题设置可以为站点范围和页面范围,管理员只需要简单的点击几次鼠标既可以定制主题元素的显示方式。

现在我们已经明白主题设置可以提供哪些功能,然后我们将学习如何配置主题。

二、             配置liferay显示和感觉

首页,你需要标记出哪些主题元素是可以配置的。在Lunar Resort中,我们需要将 Breadcrumbs(面包屑), Portlet borders(边框), and Page Title(页面标题)定义为可配置的。

现在我们已经知道哪些元素需要管理员控制,然后我们将开始设置

定制可配置主题需要多个步骤,首页,我们需要在文件中liferay-look-and-feel.xml配置主题的设置项

  1. 打开docroot/WEB-INF/目录下的文件liferay-look-and-feel.xml
  2. 在<template-extension>ftl</template-extension>后面添加以下代码
<settings>
<setting configurable="true" key="show-breadcrumbs" 
    options="true,false" type="select" value="false" />
<setting configurable="true" key="portlet-setup-show-borders-default" 
    options="true,false" type="select" value="true" />
<setting configurable="true" key="show-page-title" 
    options="true,false" type="select" value="true"/>
</settings>

这个代码只是标记了主题中哪些元素需要设置。每个设置都有一些共同的属性。Configurable属性定义了用户是否配置该设置。Key属性引用主题设置的语言文件中的key。Options属性为设置时下来列表中的选项。Type定义了控制面板中主题设置的UI类型。Value属性设置了主题设置的默认值

虽然您可以使用您自己的键创建自定义主题设置,但也可以使用现有的主题设置。Portlet设置显示边框就是用户可配置的Lunar Resort中的默认主题配置

  1. 保存文件
  2. 管理员登录,点检管理->站点管理->页面
  3. 在设置页面的下面部分可以看见如下的设置

这一步我们已经完成了为主题样式和感觉添加自定义设置设置选择,但是要使其真正生效,还需要在init_custom.ftl文件中定义他们的值

三、             配置init_custom.ftl

之前我们已经完成了为主题样式和感觉添加自定义设置设置选择,在这部分我们将为主题设置配置逻辑

  1. 打开文件init_custom.ftl并加入如下代码
<#assign show_breadcrumbs =
getterUtil.getBoolean(theme_settings["show-breadcrumbs"])>
 
<#assign show_page_title =
getterUtil.getBoolean(theme_settings["show-page-title"])>

Velocity模板使用如下代码

#set ($show_breadcrumbs = $getterUtil.getBoolean($theme_settings.getProperty("show-breadcrumbs")))
#set ($show_page_title = $getterUtil.getBoolean($theme_settings.getProperty("show-page-title")))

代码为将在liferay-look-and-feel.xml定义的设置定义为变量,使用在文件定义的key为关键字使用代码getterUtil.getBoolean(theme_settings[key]).portlet-setup-show-borders-default未定义是因为默认已经在系统中定义了,

现在我们需要在portal_normal.ftl设置条件表达式来判断是否显示主题元素

  1. 打开文件portal_normal.ftl,将以下代码
<h2 class="page-title">
<span>${the_title}</span>
</h2>

替换为

<#if show_page_title>
<h2 class="page-title">
<span>${the_title}</span>
</h2>
<#else>
<h2 class="no-page-title"/>
</#if>

现在如果将show_page_title 设置为true,<h2>页面标题元素将被加载,如果为false,则元素就不加载并且加载一个空的元素,no-page-title被作为额外的样式。

  1. 找到元素<nav id="breadcrumbs"><@liferay.breadcrumbs /></nav>并且添加判断条件
<#if show_breadcrumbs>
<nav id="breadcrumbs"><@liferay.breadcrumbs /></nav>
</#if>

如果show_breadcrumbs属性为true,breadcrumbs 将包含到页面,如果为false页面将不显示。

  1. 保存文件

现在我们已经可以在管理页面配置主题的显示,并在页面上查看效果。前面我们学了在站点范围的主题设置,后面我们将学习单独页面范围的主题设置

四、             配置单独页面主题设置

对于大多数页面我们只要使用主题的默认设置即可,但是对于某些页面,我们需要让其展示为和默认样式不一样。这就需要单独页面设置来发挥作用了。

我们将根据后续几个步骤对欢迎页面进行设置

  1. 管理员登录,进入到欢迎页面配置页面
  2. 选择外观和风格部分
  3. 选中单选按钮“为此页面定义一个独有的外观”
  4. 设置show-page-title为false,验证一下Breadcrumbs 是否为false
  5. 点击保存
  6. 刷新页面查看修改

我们注意到 show-page-title matches和在liferay-look-and-feel.xml中定义的key一样,但是其他主题设置属性不一样,这是因为其他属性使用了语言文件中的key,最佳实践是我们所有的主题设置都要使用语言文件中的key,如果打开在liferay-portal-[version]/tomcat-[version]/webapps/ROOT/WEB-INF/lib/文件夹中的portal-impl.jar文件,我们将在文件夹language_en.properties看到language_en.properties文件,这个文件中包含了Liferay Portal使用的所有的语言key

  1. 在language_en.properties文件中搜索show-breadcrumbs portlet-setup-show-borders-default ,我们将看见liferay默认使用的英语翻译。

注:简体中文为文件Language_zh_CN.properties

为了是其包含show-page-title我们需要创建一个hook修改language_en.properties文件,在下个部分我们将学到怎样实现

五、             为主题设置配置多语言支持

为了自定义language keys我们需要创建一个hook plugin 修改language_en.properties文件,下面是创建hook的步骤

  1. 打开 IDE/Developer Studio 选择 File → New → Liferay Plugin Project.
  2. 设置Project name 为language-key-hook 和Display name 为Language Key Hook.
  3. 设置合适的SDK 和runtime, Plugin type选择Hook , 点击Finish.

Hook基础已经创建,接下来需要配置hook,在这里我们需要修改英文语言包,但是其他语言包的修改过程是一样的

  1. 在项目 language key hook上点击右键,选择 New → Liferay Hook Configuration.
  2. Hook plugin project选择language-key-hook, hook type选择Language properties 然后点击下一步
  3. 离开默认文件选择Add按钮
  4. property file输入Language_en.properties 点击Finish,此处我们输入(Language_zh_CN.properties)
  5. 文件已经打开,他位于项目docroot/WEB-INF/src目录下的content 文件夹中
  6. 添加以下 language key到文件中然后保存
show-page-title = 显示页面标题
  1. 发布language-key-hook到服务,等待部署完成
  2. 查看配置页面的外观和风格,主题设置中show-page-title将是用我们设置好的 language key

Excellent! The theme settings now all have language keys! In the next portion of the Learning Path you'll expand your CSS further by making the Lunar Resort theme responsive to mobile devices.(不翻译,现在语言已经设置好了,接下来将讲解CSS在移动设备中的使用)

制作响应式主题(响应式布局)

一、             简介

设计一个主题是一个具有挑战性的过程,尤其是我们需要靠将它设置为相应试的。主题在电脑上怎么显示,在平板和手机上怎么显示,这些都是在设计主题是需要注意的问题。在这部分,我们将探索如何调整你的主题,以应对不同设备上的纵横比。

使主题成为响应式看起来是一个艰巨的任务,但是不用担心,liferay为我们提供了快速完成这项工作的工具,由于Liferay的预览功能,对不同的设备适应你的主题只需要几个步骤。

二、             使用预览功能预览主题

通过Liferay的预览窗口可以看到现有的CSS样式针对不同设备是如何响应的,以确定需要作出哪些修改。在屏幕左侧选择Docker按钮,在加号图标下面可以看见一个显示器图标,这个就是预览按钮

点击预览按钮后出现预览窗口,在点击预览按钮之前请确保页面滚动条在页面头部,否则会导致预览窗口无法显示,

在预览菜单中,我们可以看见几个预定义的渲染选项,和自定大小的选项。默认情况下我们将在智能手机视图中查看页面,一个好的经验法则是工作有机地结合起来,从桌面上查看你用来预览你的主题在更小的设备。到本节结束时,你会明白为什么这是对的。目前,只要记住这一刻。

  1. 选择平板视图

每个设备默认都是使用纵向视图显示站点,如果你第二次点击平板视图,就会发现视图变为横向展示,再次点击则变回纵向

  1. 在视图窗口滚动页面,我们将看到那些元素必须修改

首先,carousel 到了页面边缘外面,所以在平板试图中应该去掉他,其次,虽然导航功能可以使用,但是他不是平板友好的,所以我们修改修改他,最后,logo看起来没问题,但是应该缩小一点

  1. 切换到横向视图确认需要修改哪些元素
  2. 选项智能手机视图
  3. 在视图窗口滚动页面,才刚看在手机视图中是怎样加载的

Now in the Smartphone preview, you can see that the same concerning areas on a tablet are more obvious in this preview: the logo is too large and needs to be scaled down; the navigation is even more squeezed than before; the carousel is even further beyond the borders of the page and definitely needs to be removed in this view.

横向是相同的操作

三、             修改主题使其可以相应平板电脑和手机视图

确定了需要修改的主题元素后,现在我们就可以添加CSS使其可以平板电脑和手机视图

  1. 打开文件custom.css在文件最后添加如下代码,在最后结束标签之后
/*-------responsive-------*/
@include respond-to(phone, tablet) {
    html #wrapper #banner #navigation {
        display:none;
        position:relative;
    }
    .aui {
        * {
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
        }
 
        body{
            background-image:none;
        }
 
        .carousel{
            display:none;
        }
        #wrapper {
            margin: 0;
            padding:0;
            position:relative;
 
            #banner {
                position:relative;
                padding-bottom:0;
                padding-top:0;
                #heading {
                    bottom: 100%;
                    left:-19px;
                    margin-top: 0;
                    position: absolute;
                    top:-70px;
 
                    .site-title {
                        font-size: 26px;
 
                        img {
                            height:60px;
                            width: auto;
                        }
 
                        .logo{
                            height:35px;
                            width:auto;
                            top:0;
                        }
                    }
                    .page-title{
                        padding-top:20px;
                    }
                }
                #navigation {
                    display: none;
                    position:relative;
&.open {
                        display: block;
                        margin-top: 0px;
 
                        .navbar-inner {
                            @include border-radius(3px);
                            padding: 10px;
                            .nav-collapse {
                                height: auto;
                                overflow: visible;
                            }
                        }
                        li{
                            width:100%;
                            padding: 0px 0px;
                            margin: 0px;
                            text-align:center;
 
                            .dropdown-menu{
                                position:relative;
                            }
                        }
 
                        ul{
                            margin:0px;
>li{
                                display:inline-block;
                            }
                            li{
                                a{
                                    display:block;
                                    padding: 15px 0px 5px 29px;
                                }
&:hover .child-menu a{
                                    margin:0;
                                }
                            }
                        }
 
                        .child-menu{
                            width:100%;
                            margin:-2px;
                            
                            li{
                                display:inline;
                            }
                            a{
                                padding: 5px 6px 0px 40px;
                                color:#FFF;
                                font-style:oblique;
&:hover{
                                    
                                }
                            }
                        }
                    }
 
                    .nav {
                        margin: 0;
                    }
                }
            }
            #content{
                padding-top:70px;
            }
 
            #footer{
                max-width:979px;
            }
        }
 
        .dockbar-split .dockbar, .dockbar {
            float: right;
            height: 56px;
            position: relative;
            z-index: 401;
 
            .info-items {
                height: auto;
                position: static;
                width: 300px;
            }
 
            .navbar-inner {
                width: auto;
                height:60px;
                box-shadow:none;
 
                img{
                    width:32px;
                }
 
                .btn-navbar {
                    background: transparent;
                    border: none;
                    float: left;
                    font-size: 24px;
                    padding: 12px 15px;
 
&:hover {
                        
                    }
 
&.open {
                        
                    }
                }
 
                .nav-account-controls {
                    padding: 0 5px;
 
                    .user-avatar-image {
                        display: none;
                    }
                }
 
                .nav-add-controls {
                    background: transparent;
                    border-top-width: 0;
                    position: static;
                    z-index: 350;
                    padding: 0 5px;
 
> li {
                        float: none;
                        margin: 0;
                        position: relative;
                        transition:none;
                        left:0;
                        top: 0;
 
&:hover {
                            left:0;
                        }
 
&.toggle-controls a {
                            position: static;
                            visibility: visible;
                        }
 
                        .page-preview-controls {
                            display: none;
                        }
 
> a {
                            background: transparent;
                            text-align: left;
                            white-space: nowrap;
 
&:hover {
                                background: #F3f3f3;
                            }
 
                            [class^="icon-"], [class^="icon-"], [class*=" icon-"] {
                                font-size: 22px;
                                margin-top: 0;
                            }
 
&.toggle-controls-link {
                                background: transparent;
 
                                [class^="icon-"], [class^="icon-"], [class*=" icon-"] {
                                    color: #FFF;
                                }
                            }
 
                            .nav-item-label {
                                background: transparent;
                                display: inline;
                                left: 0;
                                margin-left: 0;
                                margin-top: 0;
                                padding: 0;
                                position: relative;
                            }
 
&:hover .nav-item-label {
                                display: inline;
                            }
 
                            .icon-caret-down {
                                display: none;
                            }
                        }
                    }
                }
 
                .nav-collapse {
                    z-index: 400;
 
&.open {
                        overflow: visible;
                    }
 
> .nav {
                        background: #009AE5;
                        border-width: 0;
                        left: auto;
                        margin: 0;
                        min-width: 160px;
                        position: absolute;
                        right: 0;
                        z-index: 400;
 
> li {
&.dropdown {
                                .dropdown-menu li a {
                                    font-size: 16px;
                                    line-height: 32px;
                                }
 
&.open {
> .dropdown-toggle {
                                        color: #FFF;
                                    }
                                }
                            }
 
> a {
                                color: #FFF;
                                font-size: 16px;
                                margin: 5px 0;
                                padding: 6px 15px;
 
&:focus, &:hover {
                                    
                                }
                            }
                        }
                    }
                }
            }
        }
 
        .portlet-dockbar {
            display: inline-block;
            width: 100%;
        }
 
        .signed-out #_145_navAddControlsNavbarBtn {
            display: none;
        }
    }
}
/*-------------phone responsive--------------*/
@include respond-to(phone) {
    .aui {
 
        #wrapper{
            margin: 0 -20px;
            #banner{
                padding-top:70px;
                #heading{
                    margin-top: -2em;
                    margin-bottom:0;
                    position: relative;
                    top: -30px;
                    left: 0;
                    .site-title{
                        img{
                            width:auto;
                            height:80px;
                            margin-top:-13px;
                        }
                    }
                    .page-title{
                        padding-top:20px;
                    }
                    .no-page-title{
                        padding-top:60px;
                    }
                }
 
                #navigation.open{
                    margin-top:-184px;
                }
            }
 
            #content{
                margin-top:-70px;
            }
        }
        dockbar-split .dockbar, .dockbar {
            float: none;
        }
    }
}

Now if you preview your theme on the tablet and phone you'll see that all the elements respond well. The logo has been scaled down and repositioned to better fit the tablet and phone; the main navigation bar now uses the following code to hide itself: #navigation { display: none;.... The pop-up navigation is handled with #navigation.open, and can be accessed by selecting the hamburger button next in the top right corner. Finally, the carousel has been removed in both the tablet and phone views.

Sass mixins were used to tell the CSS to respond to the correct devices. For instance, the @include respond-to(phone, tablet) mixin is used to wrap the styles that are shared for both the phone and tablet devices. This is why it is good to work organically for responsiveness. By starting off with the tablet device and moving down to the phone, you are able to figure out what elements have shared render issues and can then update them for both the phone and tablet in one mixin.

The @include respond-to(phone) mixin is then used to wrap the remaining styles that are unique to the phone only.

总结

我们学习了从创建一个主题到最后完成它。现在我们可以吧我们自己的主题放到Liferay的商定中供其它人下载。

在上传到商店之前需要确认liferay-plugin-package.properties文件中关于资源导入的属性已经更新,以免在生产环境中运行,一下为修改步骤

  1. 修改liferay-plugin-package.properties文件中开发模式为false
resources-importer-developer-mode-enabled=false

仅在初始部署时主题资源将覆盖现有的门户资源。现在,开发模式已被禁用,您需要删除一个附加属性。

  1. 取消注释required-deployment-contexts:
  2. 从文件中删除如下代码
required-deployment-contexts=\
    resources-importer-web
resources-importer-target-class-name=com.liferay.portal.model.Group

这将确保默认情况下,资源将被导入到站点模板中。

There you have it! As you can see, theme development is a multi-headed beast, but with careful planning and a thought out process you can tame it and develop a well designed theme.

转载于:https://www.cnblogs.com/liferay6/p/7508720.html

liferay 6.2 主题开发相关推荐

  1. liferay开发文档_Liferay –简单主题开发

    liferay开发文档 实际上,Liferay的6.1版本已经走了很长一段路,该版本完全支持JSF和IceFaces. 我一直在努力学习它的绳索,因为我希望使其成为我们团队中的标准协作工具. 好的软件 ...

  2. Liferay –简单主题开发

    实际上,Liferay的6.1版本已经走了很长一段路,该版本完全支持JSF和IceFaces. 我的目标是使它成为我们团队中的标准协作工具,因此我仍在尝试学习它的精髓. 好的软件应用程序可以解决问题, ...

  3. wordpress模版post.php,WordPress主题开发手册

    WordPress使用多个模板文件来显示[文章]这个文章类型. 处理博客或其文章的任何内容都属于[文章]文章类型. Index.php 如果没有其他模板文件,index.php将显示[文章]文章类型. ...

  4. wordpress 主题开发

    https://www.cnblogs.com/welhzh/p/6937243.html wordpress 主题开发 https://yusi123.com/3205.html https://t ...

  5. drupal主题开发_Drupal开发人员,关于如何使您的网站更易于访问

    drupal主题开发 对于OpenConcept Consulting Inc.的创始人兼总裁开放源代码开发人员Mike Gifford ,在他的名字后面提到Drupal可访问性是多余的. 他花了十年 ...

  6. 2020年wordpress主题开发视频教程、WP主题WP模板开发视频教程

    这个<2020年wordpress主题开发视频教程>是由码不停蹄官网录制的wordpress建站系列教程之一.本套视频教程非常适合wordpress新手用来学习开发wordpress主题模 ...

  7. wordpress网站单页模板主题开发制作

    单页模板主题一般通常用在不需要经常更新的页面上,像我们常见的关于我们,企业文化.联系我们,都属于单页面,相对来说比较简单,内容也比较单一.单页的主要调用方法和文章页很相似,常见的网站单页主要有以下部分 ...

  8. PbootCMS模板主题开发必备标签集合

    1.公司信息标签 适用范围:全站任意地方均可使用.标签作用:用于调取网站与公司相关的信息,对应后台的"基础内容>公司信息". {pboot:companyname} 公司名称 ...

  9. wordpress网站文章内容页模板主题开发制作教程

    内容页模板主题是网站中的重中之重,是主要承载我们的网站内容的页面,也是为用户展示结果的界面,那么wordpress网站文章内容页模板主题开发制作教程主要将的就帮我们顺利的学会主题开发,主要的内容有,标 ...

最新文章

  1. java 和 mysql 获取周 星期 的第一天 最后一天 或者 月的 日期(字符串转日期,日期转字符串,日期加减)...
  2. bzoj3295:[CQOI2011]动态逆序对
  3. 人生苦短,我学python之python+selenium select下拉框
  4. Linux云服务器安装Redis并设置远程连接设置开机自启
  5. 在Ubuntu 11.10中将窗口按钮移回右侧
  6. jboss相关的术语
  7. 8.霍夫变换:线条——基本的霍夫变换算法、霍夫变换的复杂性、霍夫例子_3
  8. java数组循环动态赋值_04、Java基础语法(循环嵌套、break、continue、方法、方法的重载、数组动态初始化)...
  9. 关于System.AccessViolationException异常
  10. makefile:425: *** 遗漏分隔符
  11. ZYNQ PL开发流程
  12. Centos7安装源地址
  13. php 图片外链限制,将新浪微博图床图片保存到本地解决限制外链的方法
  14. ios输入框被软键盘遮住问题
  15. Extracting Data from XML
  16. leetcode (Image Smoother)
  17. 剑指Offer66题之每日6题 - 第六天
  18. Android 常用 Manager的总结
  19. HTML前端静态网页制作
  20. Django大咖之路: 如何对付学习Django过程中所遇到的挫败感?

热门文章

  1. hdu 1025 Constructing Roads In JGShining's Kingdom(DP + 二分)
  2. java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice
  3. 《算法导论》(CLRS)第三版 第3章总结
  4. 在线十六进制颜色随机生成器
  5. 分清函数指针和指针函数
  6. PDF转换技巧之如何把文件转换为WPS?
  7. PHP设计模式之----观察者模式
  8. CentOS7 NTP server + keepalived
  9. vfp:数据库中表间关系的参照完整性
  10. 苏宁大数据怎么运营_苏宁易购的经营模式