Themes
Introduction
Themes customize the overall look and feel of Liferay and were introduced in version 3.5 of the portal.
They are generally written using the Plugins SDK with a templating language. Since version 4.3, themes have been written primarily in Velocity. As of version 6.0, they can now also be written using Freemarker.
Children Pages
· Accessibility Guidelines
Table of Contents [-]
- 1 Introduction
- 2 Hiding text
- 3 HTML Validation vs Performance
- 4 Go to content link
- 5 Opens in a new window
Introduction #
Web
accessibility refers to the practice of making websites usable by
people of all abilities and disabilities. This page outlines the best
practices for building an accessible portal in Liferay.
Hiding text #
Sometimes,
you may want to hide some information in a label or a table but you may
still want that information to be read by screen readers. In Liferay,
we provide a css selector for doing this: aui-helper-hidden-accessible. It is different to the aui-helper-hidden because this selector will hide the text also from screenreaders.
Example: <a href="#">Read more <span class="aui-helper-hidden-accessible"> about the Accessibility Guidelines page </span></a>
This link will only display "Read More" but users using a screenreader will get all the information they may need.
HTML Validation vs Performance #
If
you have a look at the templates (vm files) for Liferay portal, you may
find that the javascript is placed after the </body> tag. This
small change brings a lot of improvements in performance, but it does
not validate HTML. So, you will have to modify the vm templates if you
want to change this. There is also a theme in liferay plugins repository
which already validates HTML called "WCAG 2.0".
Go to content link #
By
default, the classic theme and control panel theme have links at the
very beginning of every page with "Skip to content" -- it automatically
goes to the begining of the content (the anchor #main-content). You can
add more links or change the existing one in your theme to fit your
needs.
Opens in a new window#
If you use <aui:a>
instead of <a> in your links, this will be done automatically for
you. If your link opens a new window the html generated for your link
will be like this:
<a target="_blank" href="#">
<span class="taglib-text">RSS</span><span class="opens-new-window-accessible">(Opens New Window)</span>
</a>
All
the liferay links opening a new window are like this, so you can modify
the text for an image using css in the class
opens-new-window-accessible.
Embedding a portlet in the theme
Table of Contents [-]
- 1 Introduction
- 2 Example
- 2.1 Create the preferences for the portlet
- 2.2 Instanceable Portlets
- 2.3 Plugin Portlets
- 2.4 Embedding: The taglibLiferay Tool
- 2.5 Changing Parameters
- 2.6 Resetting Preferences
- 2.7 Complete Example
Introduction #
Themes
are developed using the Velocity template language. Liferay provides
tools available within Velocity's context to perform special operations
such as embedding a portlet.
Here is an example of embedding the Navigation portlet into the theme. Example #
Create the preferences for the portlet #
#set ($VOID = $velocityPortletPreferences.setValue('display-style', '1'))
#set ($VOID = $velocityPortletPreferences.setValue('portlet-setup-show-borders', 'false'))
Instanceable Portlets #
If the portlet is instanceable, then the nomenclature for the portlet must contain an Instance Id in the form of a 4 character, alpha-numeric string, such as E3j7. The goal for this value is that it should be unique among the portlets of the same type on any give page.
#set ($instanceId = 'E3j7')This value is appended to the root portlet Id like so (In this case we are using the Navigation portlet who's portletId is '73'):
73_INSTANCE_E3j7Hence,
#set ($myPortletId = "73_INSTANCE_${instanceId}")
Plugin Portlets #
If the portlet is from a deployable plugin, the nomenclature for the portlet must contain the Plugin Id in the form defined in Theme Id or Portlet Id references in portal-ext.properties.Embedding: The taglibLiferay Tool #
Finally, we want to have the portlet invoked in some specific location using the taglibLiferay tool.$taglibLiferay.runtime($myPortletId, '', $velocityPortletPreferences.toString())
Changing Parameters #
You can pass different parameters to the portlet by setting the value of the second parameter in the form of a query string:#set ($queryString = "param1=value1¶m2=value2")
$taglibLiferay.runtime($myPortletId, $queryString, $velocityPortletPreferences.toString())
Resetting Preferences #
If you plan to add more than one portlet to the page in this way, make sure to reset the preferences you created for each portlet:#set ($VOID = $velocityPortletPreferences.reset())You can then proceed with a different portlet.
Complete Example #
Here is a complete example:#set ($VOID = $velocityPortletPreferences.setValue('display-style', '1'))
#set ($VOID = $velocityPortletPreferences.setValue('portlet-setup-show-borders', 'false'))
#set ($instanceId = 'E3j7')
#set ($myPortletId = "73_INSTANCE_${instanceId}")
$taglibLiferay.runtime($myPortletId, '', $velocityPortletPreferences.toString())
#set ($VOID = $velocityPortletPreferences.reset())
Fast Theme Development
Overview2 #
As a theme developer, you might find it time
consuming to continuously have to compile (jar) and deploy your theme
plugin during development. The following describes a methodology that
can be used to assist a theme developer from having to continuously
compile and deploy to the server as you refine things like CSS,
JavaScript, Theme Images with this simple trick.
Currently this
trick is only easily available using Liferay 5.2 and for a logged in
user. Variants for any version are certainly imaginable once you
understand how this works. Instructions #
Step 1 : Create a custom attribute for your user #
Go
to the control panel, and add a new custom attribute to your user. In
this example I'll use a variable named "AlternatePath". As the value for
"AlternatePath" set it to the patch to your local _diffs (or base
directory depending upon which is relevant to you) of your theme plugin.
For myself, on Mac OS, I use:
file:///Users/jklo/Documents/source/liferay-plugins/themes/my-theme/docroot/_diffs
Linux/Unix
users will have a very similar file reference. Windows users will
differ slightly as it will need to reference a drive letter in the path.
The easiest way to get the right path, use your web browser to open a
file locally within the _diffs directory. The URL in your browser should
use the correct file: syntax.
Step 2 : Modify the init_custom.vm to reference the variable you just set #
You can copy and paste the code below into your init_custom.vm. Then compile and deploy your theme plugin. What it does is get the value of the AlternatePath variable we set above, and if it exists and is not empty, it disables theme caching, and then modifies the $imagePath, $javaPath, $cssPath, and $css_main_file variables so that they reference the location on your local computer, instead of the ones within the deployed theme.#set ($altPath = $user.getExpandoBridge().getAttribute('AlternatePath'))
#if ($altPath && $altPath != "")
#set ($ignore = $theme_display.setThemeCssFastLoad(false))
#set ($ignore = $theme_display.setThemeImagesFastLoad(false))
#set ($ignore = $theme_display.setThemeJsBarebone(false))
#set ($ignore = $theme_display.setThemeJsFastLoad(false))
#set ($imagePath = $theme_display.setPathThemeImage("$altPath/images"))
#set ($javaPath = $theme_display.setPathThemeJavascript("$altPath/javascript"))
#set ($cssPath = $theme_display.setPathThemeCss("$altPath/css"))
#set ($css_main_file = $htmlUtil.escape($portalUtil.getStaticResourceURL($request, "$altPath/main.css")))
#endYou should now be able to make modifications to files within your local images, javascript, css, and main.css and the changes become instantly viewable within the portal only to yourself. Once you are satisfied with your changes you can compile and deploy your theme, and then clear the value of the AlternatePath variable you set.
Row Coloring
Problem #
Where and how do we change the colours for the backgrounds when hovered over with mouse within 'themes'? Currently when I hover over a category wihin the message portlet the background colour and text colour changes which is great, but the problem is that the background colour changes to 'yellow' for white backgrounds, and 'black' for green backgrounds.Solution #
The default CSS/Jsp for the Brochure template looks like this for these classes (css_cached.jsp):.portlet-section-body {
color: <%= colorScheme.getPortletSectionBody() %>;
background: <%= colorScheme.getPortletSectionBodyBg() %>;
}
.portlet-section-body-hover, TR.portlet-section-body:hover {
color: <%= colorScheme.getPortletSectionBodyHover() %>;
background: <%= colorScheme.getPortletSectionBodyHoverBg() %>;
}
.portlet-section-body A {
color: <%= colorScheme.getPortletSectionBody() %>;
}
.portlet-section-body-hover A, TR.portlet-section-body:hover A {
color: <%= colorScheme.getPortletSectionBodyHover() %>;
}
.portlet-section-alternate {
color: <%= colorScheme.getPortletSectionAlternate() %>;
background: <%= colorScheme.getPortletSectionAlternateBg() %>;
}
.portlet-section-alternate-hover, TR.portlet-section-alternate:hover {
color: <%= colorScheme.getPortletSectionAlternateHover() %>;
background: <%= colorScheme.getPortletSectionAlternateHoverBg() %>;
}
.portlet-section-alternate A {
color: <%= colorScheme.getPortletSectionAlternate() %>;
}
.portlet-section-alternate-hover A, TR.portlet-section-alternate:hover A {
color: <%= colorScheme.getPortletSectionAlternateHover() %>;
Which
means if your CSS looks like this, then you need to change the values
in liferay-look-and-feel.xml from your theme. There are two things that
you can do, really:
1. Edit the CSS/Jsp to hard code your desired values. e.g. .portlet-section-alternate-hover A, TR.portlet-section-alternate:hover A {
color: #SOMECOLOR;
}
2. Edit the liferay-look-and-feel.xml file for the theme you are editing (recommended).
The Liferay look and feel file will have the following key-value pair references: portlet-section-body=#3F3F3F
portlet-section-body-bg=#EAF2FF
portlet-section-body-hover=#FFFFFF
portlet-section-body-hover-bg=#5274AE
portlet-section-alternate=#3F3F3F
portlet-section-alternate-bg=#DBE1ED
portlet-section-alternate-hover=#FFFFFF
portlet-section-alternate-hover-bg=#5274AEwhich affect the CSS classes you want. Notice how the names are reflected by the methods of the colorScheme object:
getPortletSectionAlternateHover() = portlet-section-alternate-hover = #FFFFFF
Edit those, redeploy the theme, or restart the server, and you should be ok.
Theme Development using the ViewDesigner Dreamweaver Plugin
Introduction #
ViewDesigner
helps web designers to easily create or modify Liferay Themes. Web
designers would be more comfortable with web designer tools like
Dreamweaver (DW) / FrontPage(FP) to design the themes rather than using
text based editors. The current approach of putting the css changes in
the _diff folder, and doing an ANT to create the theme WAR is not what
web-designers are used to.
ViewDesigner is an OpenSource Project
licensed under CDDL. While it currently supports Windows, a Mac version
will be available shortly. It will work with DreamWeaver 8, CS3 and CS4.
You can download the plugin from here. Setup #
- Download DW from Adobe Downloads and install. Ensure that the DW Extension Manager is also installed.
- Download the latest ViewDesigner Plugin from here
- Install the plugin using the DW Extension Manager
- Click File -> Install Extension -> Browse for the mxp file that you just downloaded, and click on OK
- Accept the license, and you would get a message which says that the plugin is installed successfully.
- Open Dreamweaver.
- Click File -> Import. You would find "Import Web Space Theme File" menu item that is added
- Similarily click File->Export, you would find "Export Web Space Theme File" menu item.
- This confirms that the ViewDesigner Plugin has been installed successfully.
Downloading existing LR / Web Space Theme WAR File #
- Using the PluginInstaller portlet , download any existing theme WAR. Add Plugin Installer Portlet -> Browse Repository Tab -> Theme Plugins Sub tab.
- In LR 5.2 and Web Space 10.0 and above, you would have to do the above step using the Control Panel -> Plugins Installation -> Theme Plugins -> Install More themes.
- You could alternatively download the theme WAR from plugins.liferay.com or from the SourceForge repository.
Importing the Theme WAR into Dreamweaver #
- Click File -> Import->Import Web Space Theme File.
- In the pop up window that appears, enter fill appropriate values for the following
- Path to Web Space Theme file - point it to the LR / Web Space Theme-WAR that you just downloaded using the PluginInstaller.
- Working folder of Web SpaceTheme file: - Any directory on your file system where you would want to extract the Theme WAR file.
- Path to Java.exe: java.exe location. Once you mention this location, this value gets persisted, and shows up in this text box by default. You could change it if you want to.
- Click on "Cancel" to close the "Import Web Space Theme File" dialog box.
- Clicking on the "Help" button, opens up the Help page for doing the import.
- Click on "Ok" button to import the WAR into Dreamweaver / CS.
- The plugin now extracts the Theme WAR file in the specified Working Folder, and opens a sample preview page (index.html). This is just a preview page, and the changes made to this page wont be seen on the portal.
Modifying the Theme #
- Now make the theme related changes that you want. The index.html page shows you a preview of the changes that you are making to the CSS files.
- After doing all the desired changes, Click on File -> Save All.
Exporting the Theme WAR file after making changes #
- Now click on File->Export->Export Web Space Theme File
- Enter the following details
- Working folder for Web Space Theme file: Folder where you extracted the Theme WAR file and made changes.
- Save New Web Space Theme file To: Location on the Local File system where you would like the new modified WAR file to be created.
- Path to Java.exe: Java.exe location on your local file system.
- As soon as the user selects the "Working folder for Web Space Theme file:", the plugin reads the liferay-look-and-feel.xml and liferay-plugin-package.properties and populates the fields in the "Theme Properties:". The user might want to change them or leave them as it is before the Export operation. If the user wants to change any of the theme properties, he/she can enter the new values, and it gets persisted into the respective files.
- Theme Id: The id of the theme.This gets persisted into the liferay-look-and-feel.xml
- Theme Name: - The name of the theme. This is the name that gets displayed in the list of available themes. This gets persisted into the liferay-look-and-feel.xml and liferay-plugin-package.properties.
- Theme Description: - A short description of the theme.This gets persisted into the liferay-plugin-package.properties.
- Compatability Version: - The version of Liferay, this theme is compatible with. This gets persisted into the liferay-look-and-feel.xml
- Author: - The author(eg company name) of the theme. This gets persisted into the liferay-plugin-package.properties.
- Author URL: The author URL (could be the company URL). This gets persisted into the liferay-plugin-package.properties.
- Theme Licence: The licence of the theme. This gets persisted into the liferay-plugin-package.properties.
- Click on "Cancel" to close the "Export Web Space Theme File" dialog box.
- Clicking on the "Help" button, opens up the Help page for doing the Export.
- Click on Ok to export the Web Space theme WAR.
- You would get a message confirming that the export was successful.
Deploying the Newly created Theme WAR #
- Use the Plugin Installer Portlet to deploy this newly created theme WAR file.
- Plugin Installer -> Upload File Tab -> Browse for the new WAR file -> Install.
- For LR 5.2 and Web Space 10.0 and above use Control Panel -> Plugin Installations -> Theme Plugins -> Install More Themes -> Upload File -> Browse and upload this modified theme WAR
- The new WAR file would be deployed now.
- You could alternatively put this WAR file into LR / Web Space Hot Deploy directory and it would automatically be deployed.
- Go to any community page, click on Manage Pages -> Look and Feel Tab. You would see the newly deployed theme in the list of available themes. Just click on the theme, to set it as the current theme for that community.
Plugin Log Messages #
- The plugin log messages are written into ViewDesignerLogs.txt which is in <DW config folder>\Configuration\commands\WSThemingPlugin. In case of any errors during Import / Export operation, this file is automatically opened in the browser and shown to the user.
Known Issues#
- The web designer (or the user) would have manually change the thumbnail.png and screenshot.png in the "images" folder before exporting the theme WAR file. Other wise the preview of the theme that shows in the portal page would be a stale one.
- Currently the plugin cannot modify the vm(Velocity markup) files of the theme. We are working on building this feature into the plugin.
- The index.html (the preview page) is a static page that the plugin adds to the theme WAR during import. The ideal way of doing this would be, that the portal creates the preview page, and packages it into the theme WAR, when we download the WAR file. We are working on this also.
Theme variations using CSS
Introduction #
This entry is an extension to the Wiki entry on building themes (see Themes v4.3-v5.2.x).
There are two nice sections on that page on using theme specific
"Settings" and "Color Schemes" for creating variations of themes. There
is also an example that shows how one can create a variation on a theme
by including different sections in a template.
The technique
documented here was inspired by that idea of having two theme "color
schemes" registered, but having only a single source set. You should be
familiar with that technique before reading this entry. The example document here was used in a theme where it was desired to have a variation of a theme where the portlet borders are turned off universally. While its true that one could instruct users to go to each portlet's configuration, and "turn off" border display manually, that may impractical on sites with large numbers of portlets and/or pages. What if the end user wanted to switch back and forth between the two looks and decide which they liked better?
Theme Variations #
The
technique documented here creates a "color scheme" that has the borders
turned off, but preserves the other attributes of the theme, and does
so with a single CSS source set (allowing for easier maintenance). It
uses a CSS design pattern known as "CSS sub-class selectors." Note that
this technique can be used for more than just borders. It can be used
when you have several very small variations on a single theme, and you
want to keep all of those variations in a single source file.
1. Per the known technique of creating a color scheme, we create a color scheme for the default theme registered in liferay-look-and-feel.xml: <theme id="customTheme" name="My custom theme">
<color-scheme id="01" name="Default">
<css-class>default</css-class>
<color-scheme-images-path>${images-path}/color_schemes/default</color-scheme-images-path>
</color-scheme>
</theme>2. Separate out all color settings and image selections into a special CSS file (in this example, put it in css/color_schemes/default.css. Here are a few sample entries in the file:
.default #portlet-wrapper, .default #portlet-wrapper- {
background-color: white;
}
.default .portlet-title {
color: black;
}
.default .portlet, .default .portlet-topper, .default .portlet-content, .default .portlet-title {
background-image: url(../../images/color_schemes/default/portlet/portlet_bg.png);
}3. Now, here is the "new" technique: We want EVERYTHING in the theme, colors and all, to be identical, with a single exception: we don't want borders. So, a NEW entry in liferay-look-and-feel.xml following the above "default" definition:
<color-scheme id="02" name="Default with no portlet borders">
<css-class>default noborders</css-class>
<color-scheme-images-path>${images-path}/color_schemes/default</color-scheme-images-path>
</color-scheme>
Important to note in the above: the "css-class" entry is defined as the SAME css class as the first one, followed by a space,
then the name of the theme's "sub-class" (in this case, "noborders").
Next, the "color-scheme-images-path" is defined as the SAME path as the
original "default" scheme. Thus, there is no need to duplicate the image
files either.
4. This is the only new CSS that needs to be added to the "default.css" file: .default.noborders .portlet,
.default.noborders .portlet-topper,
.default.noborders .portlet-content,
.default.noborders .portlet-title {
background-image: none;
background-color: white;
}
Notice
that the initial CSS selector is ".default.noborders", with NO space
between them. That is CSS for "must have both of these classes".
Since in the liferay-look-and-feel.xml, the "css-class" has the space, the Liferay theme system generates class="default noborders"
in the HTML of the portal. All of the CSS that is namespaced with JUST
the selector ".default" will be applied to BOTH themes - the "Default", and
the "Default with no borders" theme. All CSS selectors that are
namespaced with ".default.noborders" will apply ONLY if the "no borders"
theme is selected. 5. We could create a third and forth theme like this:
<color-scheme id="03" name="Default with no portlet borders, blue background">
<css-class>default noborders blue-bg</css-class>
<color-scheme-images-path>${images-path}/color_schemes/default</color-scheme-images-path>
</color-scheme>
<color-scheme id="04" name="Default with no portlet borders, red background">
<css-class>default noborders red-bg</css-class>
<color-scheme-images-path>${images-path}/color_schemes/default</color-scheme-images-path>
</color-scheme>
and add this to the CSS
.default.noborders.blue-bg .portlet {
background-color: blue;
}
.default.noborders.red-bg .portlet {
background-color: red;
}We now have FOUR theme variations with only a couple of lines in the CSS file. The selector ".default" applies to ALL FOUR themes. The selector ".default.noborders" applies to three of the four (those without borders). The selector ".default.noborders.blue-bg" applies only to that with the blue background.
It would be fairly easy to make a large number of permutations on this: a "blue background WITH borders" for example, using a similar technique. The selector ".default.blue-bg" will apply to all elements that are default and blue background, regardless of if they have a border or not.
So I'll try to give a simple example for setting up a theme, named Custom Colors, with two color schemes (green and orange).
1) Create a liferay-look-and-feel.xml file in /plugins-sdk/themes/custom-colors-theme/docroot/WEB-INF:
<?xml version="1.0"?>
<!DOCTYPE look-and-feel PUBLIC "-//Liferay//DTD Look and Feel 5.2.0//EN" "http://www.liferay.com/dtd/liferay-look-and-feel_5_2_0.dtd">
<look-and-feel>
<compatibility>
<version>5.2.0+</version>
</compatibility>
<theme id="custom-colors" name="Custom Colors">
<color-scheme id="01" name="Green">
<css-class>green</css-class>
</color-scheme>
<color-scheme id="02" name="Orange">
<css-class>orange</css-class>
</color-scheme>
</theme>
</look-and-feel>
2) Create your css files:
/plugins-sdk/themes/custom-colors-theme/docroot/_diffs/css/color_schemes
-> green.css
-> orange.css
3) Open /plugins-sdk/themes/custom-colors-theme/docroot/_diffs/css/custom.css
4) Add these two lines to the top of custom.css:
@import url(color_schemes/green.css);
@import url(color_schemes/orange.css);
5) If you plan on changing out the images make sure you create:
/plugins-sdk/themes/custom-colors-theme/docroot/_diffs/images/color_schemes
-> /green
-> /orange
6) Run the ant build for your theme and you should be good to go
The big thing to note here is that you must import your color scheme css files. I assumed that Liferay would include the appropriate CSS file for me, but that does not happen.
1) Create a liferay-look-and-feel.xml file in /plugins-sdk/themes/custom-colors-theme/docroot/WEB-INF:
<?xml version="1.0"?>
<!DOCTYPE look-and-feel PUBLIC "-//Liferay//DTD Look and Feel 5.2.0//EN" "http://www.liferay.com/dtd/liferay-look-and-feel_5_2_0.dtd">
<look-and-feel>
<compatibility>
<version>5.2.0+</version>
</compatibility>
<theme id="custom-colors" name="Custom Colors">
<color-scheme id="01" name="Green">
<css-class>green</css-class>
</color-scheme>
<color-scheme id="02" name="Orange">
<css-class>orange</css-class>
</color-scheme>
</theme>
</look-and-feel>
2) Create your css files:
/plugins-sdk/themes/custom-colors-theme/docroot/_diffs/css/color_schemes
-> green.css
-> orange.css
3) Open /plugins-sdk/themes/custom-colors-theme/docroot/_diffs/css/custom.css
4) Add these two lines to the top of custom.css:
@import url(color_schemes/green.css);
@import url(color_schemes/orange.css);
5) If you plan on changing out the images make sure you create:
/plugins-sdk/themes/custom-colors-theme/docroot/_diffs/images/color_schemes
-> /green
-> /orange
6) Run the ant build for your theme and you should be good to go
The big thing to note here is that you must import your color scheme css files. I assumed that Liferay would include the appropriate CSS file for me, but that does not happen.
Themes (WAP)
Themes customize the overall look and feel of Liferay and were introduced in version 3.5 of the portal. With Liferay version 4.3, we now have a WAP theme that is designed to run on mobile devices.Overview #
To find out where to start, look at liferay-look-and-feel.xml found in the \trunk\portal-web\docroot\WEB-INF\ folder.
<theme id="mobile" name="Mobile">
<root-path>/wap/themes/${theme-id}</root-path>
<wap-theme>true</wap-theme>
</theme>This is very similar to our other themes except it has this attribute:
<wap-theme>true</wap-theme>
This tells the portal that the theme was developed for a mobile device.
You also notice the addition of a wap folder in \trunk\portal-web\docroot\. To make a theme show up correctly in a mobile device, you need this doc type:
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.1//EN" "http://www.wapforum.org/DTD/xhtml-mobile11.dtd">
Make sure all your tpl, jsp, and VM files adhere to this standard.
New template files have been created for mobile display. If you look at liferay-layout-templates.xml. You see entries for for *.wap.tpl files like the follow: <wap-template-path>/html/layouttpl/custom/1_column.wap.tpl</wap-template-path>In the 4.3 \trunk\themes\ folder, you'll find a sample wap theme called sample-base-wap-theme.war. Use this as your template for custom wap themes.
Database Changes#
The Layout table also has addition fields for wapThemeId and wapColorSchemeId.
Themes v4.0-v4.2
Themes customize the overall look and feel of Liferay and were introduced in version 3.5 of the portal.Overview #
It
is a collection of .jsp or velocity templates that contain fragments of
the various components that make up the HTML sent to the client
browser. Though most theme template bundles contain a variety of
template files, the "required" template files are:
- portal_normal.vm Controls the layout of portal templates for "normal" pages
- portal_pop_up.vm Controls the layout of portal templates for "pop-up" pages
NOTE: It appears that Velocity is now the template engine of choice. The Velocity context is created and initialized in com.liferay.taglib.util.ThemeUtil.includeVM().
A theme can have one or more "color schemes", which gives even more flexability to the look and feel of a theme. The Ant script /portal/portal-web/build.xml contains the target build-color-scheme that is capable of generating images that match a color scheme (using the services of com.liferay.portal.tools.ColorSchemeBuilder).
The themes that are available to a portal are described in WEB-INF/liferay-look-and-feel.xml (as well as WEB-INF/liferay-look-and-feel-ext.xml). These themes are read in by com.liferay.portal.service.impl.ThemeLocalUtil. Theme definitions are held in in-memory collections of com.liferay.portal.model.Theme objects (and not in the database).
Themes can be limited to certain company Ids (by including or excluding the themes in the <company-limit> section of WEB-INF/liferay-look-and-feel.xml).
Themes can be either part of the build, or "hot deployable." A "Hot deployable" theme is simply the theme(s) directory(ies) bundled up into a .WAR file with the WEB-INF directory containing the liferay-look-and-feel.xml that describes the theme(s). A hot deploy theme bundle can contain more than one theme.
The basic structure of a theme directory (whether in a .WAR, or part of the build) is: Root theme directory: /html/themes/<nameOfTheme> Image files used by theme: <themeRoot>/images Templates that describe the themes: <themeRoot>/templates
Generally speaking, themes are not layed out in tables. Best practice has placing visual elements inside of tags, then defining background, position, etc. of these elements in <themeRoot>/templates/css_cached.vm
Upgrade to 4.2.x #
Any upgrade to a theme from versions 4.0-4.1.3 to 4.2.x must change the following files:
WEB-INF/liferay-look-and-feel.xml#
1. Change version number to 4.2.1 (or whatever version you're upgrading to) resulting in:<version>4.2.1</version>
css_cashed.vm#
1. Add:.pop-up-outer { border: 1px solid #383838; background-color: #FFFFFF; }
.pop-up-inner { border: 1px solid #747474; }
.pop-up-header { background-color: #000000; height: 25px; }
.pop-up-title { color: #FFFFFF; font-weight: bold; padding-left: 10px; }
.pop-up-close a { color: #FFFFFF; margin-right: 7px; white-space: nowrap; text-decoration: underline; }
2. At this block of code:
.portlet-box {
height: auto;
text-align: center;
#if ($browserSniffer.is_ie_5_5_up($request))
height: 100%;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='$themeDisplay.getPathThemeImage()/custom/portlet-bg.png',
sizingmethod='scale');
#else
background-image: url($themeDisplay.getPathThemeImage()/custom/portlet-bg.png);
#end
background-color: $colorScheme.getPortletBg();
}Delete line "text-align: center;" resulting in:
.portlet-box {
height: auto;
#if ($browserSniffer.is_ie_5_5_up($request))
height: 100%;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='$themeDisplay.getPathThemeImage()/custom/portlet-bg.png',
sizingmethod='scale');
#else
background-image: url($themeDisplay.getPathThemeImage()/custom/portlet-bg.png);
#end
background-color: $colorScheme.getPortletBg();
}
portal_normal.vm#
1. Delete 2 lines:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN":and
{{{"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
}}}
2. At this block of code: #if ($themeDisplay.isShowPageSettingsIcon())
<a href="$themeDisplay.getURLPageSettings().toString()">$languageUtil.get($pageContext, "page-settings")</a>
#end
:Add another link resulting in:
#if ($themeDisplay.isShowPageSettingsIcon())
<a href="$themeDisplay.getURLPageSettings().toString()">$languageUtil.get($pageContext, "page-settings")</a> -
<a href="javascript: void(0);" onClick="$themeDisplay.getURLLayoutTemplates()">$languageUtil.get($pageContext, "layouts")</a>
#end
3. At this block of code:
{{{ <div id="layout-my-places">
#set($myPlacesPortlet = $staticFieldGetter.getFieldValue("com.liferay.portal.util.PortletKeys", "MY_PLACES"))
$taglibLiferay.runtime($myPlacesPortlet)
</div>
}}} :Add align=right to div resulting in:
{{{ <div id="layout-my-places" align=right>
#set($myPlacesPortlet = $staticFieldGetter.getFieldValue("com.liferay.portal.util.PortletKeys", "MY_PLACES"))
$taglibLiferay.runtime($myPlacesPortlet)
</div>
}}}
portlet_top.vm#
1. At this block of code:
{{{<table border="0" cellspacing="0" cellpadding="0" width="100%" onMouseOver="toggleById('portlet-small-icon-bar_$portletId', true)"
onMouseOut="toggleById('portlet-small-icon-bar_$portletId', true)">
}}} :Add class="portlet-header-bar" resulting in:
{{{<table class="portlet-header-bar" border="0" cellspacing="0" cellpadding="0" width="100%"
onMouseOver="toggleById('portlet-small-icon-bar_$portletId', true)" onMouseOut="toggleById('portlet-small-icon-bar_$portletId',
true)">
}}}
Themes v4.3-v5.2.x
Introduction #
Themes customize the overall look and feel of Liferay. They since version 4.3 are written using the plugins SDK and the templating language Velocity.
Deploying a Theme#
There
are two methods to deploying a theme in Liferay. First you can download
a prepackaged theme from the Software Catalogue Portlet or you can
deploy a theme from a packaged WAR you have downloaded.
Deploying from the Software Catalogue#
To
do so place the Software Catalogue Portlet on a page. You can find the
Software Catalogue by going to the Dock and selecting the Add
Application from the drop down menu. When the list of applications load,
you'll find Software Catalogue in the Admin section.
Alternatively,
if you are running Liferay 5.2.0 you can also access the Software
Catalogue in the Control Panel. Both options will require you to have
the proper permissions to be able to install a theme. From the Software Catalogue Portlet you can search or browse for a new theme.
Deploying a Packaged Theme WAR#
To
deploy a packed theme WAR you'll need access to the directory that
Liferay listens to for auto deployment (by default this directory is the
user folder). Simply copying the theme WAR file in this directory will
deploy your theme.
Developing a Theme#
Installing the Plugins SDK#
As of Liferay 5.1, themes are built on top of default "styled" and "unstyled" themes.
To build a theme start by downloading and unzipping the Liferay Plugins SDK. Also see the Liferay Plugins Development Guide to set up your plugins environment. Create a build.{username}.properties file in your SDK directory replacing {username} with your systems username. Then, add this line to the code within the file:
app.server.dir={path to your app server}You are now ready to create you blank theme! From the command line, navigate to the plugins/themes directory and type:
For windows:
create <project name> "<theme title>"For Linux/Mac:
./create.sh <project name> "<theme title>"Where <project name> is what your theme will be called within the file structure, and <theme title> is the text that will actually be displayed within the liferay portal in the Available Themes list. The second parameter must have quotes around it to allow spaces in the name of the theme.
Writing Your Theme#
Now that your new theme has been created, you're ready to modify the default styling.
Inside
the newly created theme you'll find several directories, one of which
is called _diffs (located in docroot). In here you can overwrite any of
the files that would be automatically created for your theme. Below are
some of the files that can be overwritten. /THEME_ID/ *
/css/
base.css
custom.css
main.css
navigation.css
forms.css
portlet.css
deprecated.css
tabs.css
layout.css
/images/
(many directories)
/javascript/
javascript.js
/templates/
dock.vm
navigation.vm
portal_normal.vm
portal_popup.vm
portlet.vm
/WEB-INF
/META-INF
* (the name/theme id of the theme, which is specified in WEB-INF/liferay-look-and-feel.xml)At the very least you'll need to modify the custom.css file to change the way your theme looks. We highly recommend that all changes be made to custom.css since the other css files are used to provide structure to your theme. To do this, in the _diffs folder create the "css" folder and save "custom.css" into this directory.
Likewise, for any javascript functionality creating the javascript.js file will also get included in your theme.
Browser/OS Consistency#
As
a theme developer you'll notice the inconsistency of how your theme is
rendered in multiple browsers (and even operating systems). If you find
that you need to make a browser, or OS specific modification, these CSS
class selectors are available to use:
Selecting different browsers would be like so: .ie h1{}
.gecko h1{}
.safari h1{}
.ie6 h1{}
.ie7 h1{}
.konqueror h1{}To feed rules to different operating systems you would do
.win h1 {}
.linux h1{}
.mac h1{}You can also feed rules to users who have javascript on like so:
.js h1{}You can also combine any of these rules by “chaining” the css selectors, like so:
.firefox.mac h1 {}
.js.firefox h1{}And you can do this with the different color schemes like this:
.safari.js .blue h1{}
Velocity Templates#
Velocity templates control the different HTML of the portal using Apache Velocity Templates. We recommend that you view their docs to see how they are written.- portal_normal.vm - This file controls the basic skeleton HTML of the page Liferay will serve.
- dock.vm - This provides the drop down dock on the page.
- init_custom.vm - This file allows you to override and define new velocity variables.
- navigation.vm - This file is called by portal_normal.vm and provides the HTML to make the navigation bar.
- portal_pop_up.vm - This file handles the pop up notification for Liferay.
- portlet.vm - This file wraps the content of very portlet.
Properties#
You
probably have already noticed that there is another directory besides
the _diffs folder in your theme. The WEB-INF could hold many important
configuration files but we'll be looking at one important properties
file.
You'll notice that the create script automatically created a
liferay-plugin-package.properties file. Opening it with your favorite
text editor will allow you to edit such information as the license,
author, etc. You'll notice that some of the information has been auto
populated. The first thing you'll want to do is replace your name with for "Liferay, Inc." on the author field.
Change as many values as you'd like and save this file.
Finished!#
You should now have completed your first theme. To deploy your theme type,
ant deployfrom the command line in your theme folder. This will deploy your theme for you and all your users to enjoy.
Note: it is much easier to develop your theme if you first deploy the blank template and modify the files in the webapps folder of your Liferay installation and copy them back into the _diffs folder. If you choose to take this approach be sure to turn caching off for Liferay on your development machine. See Liferay Developer Mode for more information.
Quality Control#
These are the steps to ensure that your theme will look good in some of the less visable areas of Liferay Portal.
Presentation and Legibility#
Thankfully,
Liferay portal has been designed so that majority of the themed
elements share properties, making the styling process very quick. That
being said, there are certain portlets that are good to check on while
you are theming to get a sampling of the whole.
- Calendar Portlet - theming the tabs and dates of the summary, month, and week tabs
- Page Comments Portlet - theming the heading and odd and even fields
- Currency Converter - theming the table
- Document Library - theming the iframe that is used for the classic uploader
- Add Application module
- Layout Template module
- Quick Note Portlet
- Sign In Portlet when signed out
- Success and failure messages
- Dock controls
Advanced#
Color Schemes#
See Theme variations using CSS for instructions on how to create a color scheme.
Theme Conventions#
CSS Conventions#
Here are CSS formatting conventions that will make sure your code is consistent, and easily readable:
- Outside of selector bodies:
- Group selectors under the common element that they style using comment tags
- Keep global selectors towards the top, and more specific selectors towards the bottom
- Keep only 1 endline between all selectors and comments
- Inside selector bodies:
- Insert 1 space between selector name and opening "{"
- For using multiple selectors for the same body of declarations, separate selectors with "," and 1 endline
- All declarations are indented by one tab
- Keep all declarations in alphabetical order within the declaration body
- For each declaration, be sure to put 1 space between the property and the value, after the ":"
- Colors should only be specified by using their hexidecimal value.
- Use all caps for hexidecimal values, and condense to 3 digits whenever possible
- For the "background" property, make sure there is no space between "url" and opening "("
- No quotes are required when using url() or for font names, unless using fonts that aren't browser-safe
- Insert spaces after commas between font names
- When using urls, always use a relative address instead of absolute
- Condense all padding,margin, and border values whenever possible, leaving out measurement units on "0" values (i.e. px, pt, em, % etc)
- Comments are only used to head and divide each section of the code appropriately. Comments without any content below it are not necessary.
- Use shorthand properties where applicable.
Filename Conventions#
- Use Conventional names when saving image files
- Use underscores only in file names - no dashes
Related Articles#
- Plugins SDK
- Theme variations using CSS
- Themes (WAP)
- How To Change Liferay Default Theme
- Create Liferay Themes for 6.0.x
- Upgrade 5.2.x Themes to 6.0.x
Themes v6.0
Introduction #
Themes
customize the overall look and feel of Liferay. They are written using
the plugins SDK and, since version 6.0, can be written using one of the templating languages, Freemarker or Velocity.
Deploying a Theme#
There
are two methods to deploying a theme in Liferay. First you can download
a prepackaged theme from the Software Catalogue or you can hot deploy a
theme from a WAR.
Using the Software Catalogue#
You
can also access the Software Catalogue in the Control Panel under
"Plugins Installation". From there you can search or browse for a new
theme.
Hot Deploying a WAR#
To
deploy a packed theme WAR you'll need access to the directory that
Liferay listens to for auto deployment (by default this directory is the
user folder). Simply copying the theme WAR file in this directory will
deploy your theme.
Developing a Theme #
Prerequisites #
- Plugins SDK for your Liferay version.
- The plugins SDK is needed because it generates a framework. You don't need to use any fancy editors or install anything crazy though -- an SDK is simply a bunch of files and scripts that make your life easier. You can download the SDK from the Liferay main page, unzip it, set up the file called build.username.properties, and you're good to go. You simply need it to do the first step -- everything after that is what you already know: CSS in your editor of choice. Don't get scared because it's called an SDK!
- Good understanding of CSS (you cannot edit the HTML -- only CSS can be modified to style Liferay)
Recommended Tools #
- Firefox with Firebug
- Google Chrome (has the inspect tool, to allow you to look at various elements on a page)
Writing your Theme #
- Navigate using command prompt or terminal to the $PLUGINS_SDK/themes folder. Run:
create newtheme "My New Theme"
or, on Linux/Mac:
./create.sh newtheme "My New Theme"
- Navigate to the newly created $PLUGINS_SDK/themes/newtheme/_diffs and add some customizations to the default theme. The way to do this is to create a directory called 'css' in _diffs, then add/edit the file css/custom.css. Liferay doesn't allow you to directly modify the "base" CSS -- you can however hide elements at will using CSS (display:none;) and move them around to your liking. This follows the principle for separation of content and style.
- Issue 'ant all' in the $PLUGINS_SDK/themes/newtheme folder to build and deploy.
- Log in into Liferay and check out your new creation.
Side tip for non-noobs (power users): If you want your theme to be developed from an existing theme other than the classic plain theme, you can modify the file build.xml (inside the folder of the theme) and change the parent.theme attribute to the id of the theme you want it to be copied from (for example, classic) and then deploy again. Generally you just want to use the basic plain Liferay setup however, because it's pretty empty and you style everything yourself.
The theme's folder is set up like this:
/THEME_NAME/
/css/
base. css
custom. css
main. css
navigation. css
forms. css
portlet. css
deprecated. css
tabs. css
layout. css
/images/
(many directories)
/javascript/
javascript. js
/templates/
dock. vm
navigation. vm
portal_normal. vm
portal_popup. vm
portlet. vm
Additional Notes #
- Liferay's theming process is pretty unique: a pre-made theme, the "_unstyled" theme (default) is applied first when you create a new theme (when you do create newtheme "My New Theme"). In fact, try creating a theme but not adding any _diffs files -- you'll see that the site is still styled! That's because it's the "_unstyled" theme, which does give your site minimal structure. It looks very plain though. That's because it's ready for you to make your modifications.
- On top of the classic theme's code, you add your own styles, images, dock customizations and et cetera by creating the above directory structure in your theme _diffs folder. If you don't want to overwrite a file (you like the classic/default way it looks), you don't have to. If you want to rewrite everything, you can do that too. Liferay is super flexible. Say you want to change something in the dock. Open up dock.vm from the classic theme, and make your modifications. Save it to your _diffs (take care that you put it in the right directory, e.g custom.css goes in yourtheme/_diffs/css/custom.css) and you should have a functional theme.
Dockbar #
A
lot of questions are asked about the Dockbar. Starting in Liferay
6.0.x, the dock was moved to being a portlet instead of something
directly in themes. What that means is that dock.vm no longer exists:
instead, to edit dockbar requires that you create a hook or ext plugin
that overrides the dockbar's JSP or whatever else you're seeking to
change. It sounds involved, but it really isn't hard -- once you've
created the new hook, you simply overwrite whatever you want on the JSP
or other files.
Styling the dockbar is easy still too, since the CSS is all in dockbar.css. Creating the links on the dockbar while removing the dockbar itself is a common request also. For more information on linking dockbar items, see Link to Dockbar
Link to Dockbar
Introduction #
For a lot of Liferay implementations, the dockbar needs to be hidden and the "Add Application" button and the "Layout Templates" button need to be placed on the site body. Unfortunately, doing that has not been the easiest thing to figure out. Fortunately, there does exist an easy way to do it.Code #
If
you place this code anywhere in portal_normal.vm, it links to the "Add
Application" container as well as the "Layout Templates" container.
<!-- This can be placed anywhere in the portal_normal.vm -->
<a href="javascript:;" id="addApplications">Add Application</a>
<a href="javascript:;" id="layoutTemplates">Layout Templates</a>
<script type="text/javascript">
AUI().use(
'aui-dialog',
'liferay-layout-configuration',
function(A) {
// Create the Add Applications dialog
var addApplicationsDialog = new A.Dialog({
title: 'Add Application',
width: 280,
visible: false
}).plug(A.Plugin.IO, {
after: {
success: function(event, id, obj) {
Liferay.LayoutConfiguration._dialogBody = addApplicationsDialog.get('contentBox');
Liferay.LayoutConfiguration._loadContent();
}
},
autoLoad: false,
data: {
doAsUserId: themeDisplay.getDoAsUserIdEncoded(),
p_l_id: themeDisplay.getPlid(),
p_p_id: 87,
p_p_state: 'exclusive'
},
showLoading: false,
uri: themeDisplay.getPathMain() + '/portal/render_portlet'
});
// Attach the click listeners to the links
A.one('#addApplications').on('click', function(event) {
addApplicationsDialog.render().show().io.start();
});
A.one('#layoutTemplates').on('click', function(event) {
Liferay.LayoutConfiguration.showTemplates();
});
}
);
</script>
Using Custom Permissions in Theme
Introduction #
Our goal is to add a custom permission to Liferay that can be used to control access/visibility to resources in the Velocity templates in a custom theme. This allows an administrator to manage access through the front-end of the software, in a manner they are probably already familiar with. In our example, we'll create a role that will be used to determine if a user can see the dock, but these principles could be applied to many other scenariosThis article assumes that you have already configured your Plugins SDK environment and downloaded the Liferay Portal source code.
Creating a custom theme #
- From a command prompt, navigate to the plugins/themes directory
- Create a new them using the following command:
create dock-permissions "Dock Permissions"
- Change your directory to dock-permissions-theme and deploy your new theme using the following command:
ant deploy
- Watch the command window and the console to ensure the theme is deployed and registered successfully and available for use.
- Log in to Liferay and from the Dock, select Manage Pages.
- Select the Look and Feel tab and choose your new Dock Permissions theme.
- The theme will change to a very unstyled look and feel
- Using your file explorer, navigate to your portal source code folder,
- Copy the contents of the portal-web\docroot\html\themes\classic\_diffs directory to plugins\themes\dock-permissions-theme\docroot\_diffs
- From the command prompt, deploy the dock-permission-theme again.
- Refresh your browser and you should see the dock-permission-theme looks just like the Liferay Classic theme.
Customizing the Resource Actions #
We'll be making use of Liferay's Permission System to control who will see the Dock in our custom theme. Liferay's Permissions system is based on the concepts of actions and resources. In our case, we'll be adding the action VIEW_DOCK to the com.liferay.portal.model.Layout resource.The resource-actions for a portlet are stored in the /resource-actions/$portletname.xml file. We need to modify the resource actions that are associated with the communities portlet, so we'll be modifying the /resource-actions/communities.xml file. This file is embedded in the portal-impl.jar, and should not be modified. Instead, we will create a new communities.xml file in the /WEB-INF/classes/resource=actions folder of our Liferay installation.
- In a command prompt window, navigate to your /webapps/ROOT/WEB-INF/lib folder.
- In this folder is the portal-impl.jar file. To extract the communities.xml file from this .jar, issue the following command:
jar xvf portal-impl.jar resource-actions/communities.xml
- The communities.xml file will be extracted to a resource-actions folder in the lib directory.
- Copy the resource-actions folder from the lib directory to /webapps/ROOT/WEB-INF/classes
- Open /webapps/ROOT/WEB-INF/classes/resource-actions/communities.xml with a text editor.
- Add the following line to the <supports> section of the <model-resource> section (approximately line 28):
<action-key>VIEW_DOCK</action-key>
- Save the file, then stop and restart Liferay.
Creating a custom role #
The VIEW_DOCK permission is now part of the My Communities portlet and can be added to any existing role. For this example, we'll create a new role called Dock-Users and assign this new permission.- Navigate to the Control Panel and select Roles under the Portal heading.
- Click the Add button
- Enter Dock-Users for the name and provide a description.
- Click Save.
- Click the Actions button that corresponds to the Dock-Users role and select Define Permissions.
- Click the Add Portlet Permissions, and select the My Communities portlet.
- In the Page section, find the action.VIEW_DOCK entry and set the scope to Enterprise.
- Click Save, then click the Roles link in the breadcrumb trail.
- Click the Actions button that corresponds to the Dock-Users role again and this time select Assign Members.
- Assign some users to this new role and save.
Checking Permissions in a Theme #
The last step is to check for our new permission inside our custom theme. This would be done in one of the Velocity templates. In our example, we want to hide the entire Dock for users that don't have the VIEW_DOCK permission, so we'll create a variable called $show_dock that can be used to determine if the Dock should be displayed.- Create a new folder called templates at plugins/themes/dock-permissions-theme/docroot/_diffs
- Copy init_custom.vm and portal_normal.vm from plugins/themes/dock-permissions-theme/docroot/templates to /themes/dock-permissions-theme/docroot/_diffs/templates
- Add the following line to _diffs/templates/init_custom.vm:
#set ($show_dock = $layoutPermission.contains($permissionChecker, $getterUtil.getLong($plid), "VIEW_DOCK"))
- In the _diffs/templates/portal_normal.vm, replace the following code:
#parse ("$full_templates_path/dock.vm")
with
#if ($show_dock)
#parse ("$full_templates_path/dock.vm")
#end
- Re-deploy your theme.
Note, if you hide the Dock from users, you will have to provide some other means for them to sign out.
References #
Plugins SDK
http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Plugins+SDK
Using Liferay's Permissions System from a portlethttp://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Plugins+SDK
http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Using+Liferay%27s+Permission+System+from+a+portlet
Overwrite Liferay Portlet Permissions
http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Overwrite+Liferay+Portlet+Permissions
Permissioning Explained
http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Permissioning%20Explained
very nice post
ReplyDeleteawesome post keep it up.
ReplyDeletecan you explain about .sass-cache folder in theme. When I build theme with maven build, the .sass-cache folder contains some css files which are NOT same as my source css files e.g: mainstyle.css. It contains different code in it. Sometimes it loads css files from that folder instead of my source css files. This conflict leads me to do server restart which is havoc. Can you please explain a solution ?
ReplyDeleteI use liferay 6.2.0 sp1 enterprise edition
DeleteAwesome post about liferay its really great...
ReplyDeleteTheme customization is the major part of website creation segment.Choosing correct themes only give the exact layout and structure to the website.
ReplyDeleteWeb Design Company | Website Designing Companies
Very Helpful post.
ReplyDeleteGreat work Himanshu.
I appreciate your efforts in writing a long post to help the developers.
ReplyDeleteIt is a very informative post to learn liferay theme Development.
Very nice post thanks for this information
ReplyDeletewe are custom facebook apps developer you can contact to JaK Technology .
Thanks you
Custom Facebook Apps Development
Thank you for sharing such useful stuff and very much appreciable.
ReplyDeletehttp://cctvinstallation.in
Thanks for this collection :) it always help to make new creative ideas and designs
ReplyDeleteVery nice and help ful for Service builder i found this one also helpful
ReplyDeletehttp://liferayiseasy.blogspot.in/search/label/service%20builder
Fantastic information. Thanks regarding offering people such a helpful information
ReplyDeletecheck writing software | inventory management software dubai
If you want some tutorial on liferay hook you may visit
ReplyDeletehttp://liferayiseasy.blogspot.in/search?q=hook
Thanks you... vary nice articles.
ReplyDeleteNice tutorial!
ReplyDeleteI have make some new liferay theme, you can download free at www.liferaytheme.com
http://edusparkle.com
ReplyDeletehttp://quizexpo.com
http://patnauniversity.quizexpo.com
Amazing post dude.It will be very helpful for begginers like me.Thank you very much for this important post.Waiting for your next post.You can visit our site to get awesome
ReplyDeletehtml templates
thanks
ReplyDeleteThanks for the post. Hope so that this tutorial of yours work well for me. People who are finding it difficult to design their front end may also take help from the after effects templates that are specially designed according to the needs and the demand of the project. They are more impressive and effective then any other normal template.
ReplyDeleteThanks for sharing such unique information which are in actual fact as well as helpful for us.Keep it up.....
ReplyDeleteWeb Design Bangalore | Web Design Companies Bangalore
Positive site, where did u come up the information on this have read a few of the on your website now, and I really like your style. Thanks a million and please keep up the effective work.
ReplyDeleteSEO services pakistan
Hi I have created a dashboard theme and how to connect with Single page application.
ReplyDeletePlease help me.
How to integrate social login and sharing on my Magento e-commerce site?
ReplyDeleteMagento Hide Price
Very Great Post..Am impressed..and also am learned lots of information in your article..Thank you sharing the useful information....Website Designing Services Bangalore | Website Development Services in Bangalore
ReplyDeleteNexevo Technologies Blog: Website Design Company in Bangalore | Website Development Company in Bangalore
ReplyDeleteThanks for give me this information really this product is very effective.
Custom Software Development India - Nintriva
Well, this is very intertesting and good post. Keep more sharing. Web Design Company Bangalore | Website Development Company Bangalore
ReplyDeleteI really appreciate information shared above. It’s of great help. If someone want to learn Online (Virtual) instructor lead live training in liferay, kindly contact us http://www.maxmunus.com/contact
ReplyDeleteMaxMunus Offer World Class Virtual Instructor led training on liferay. We have industry expert trainer. We provide Training Material and Software Support. MaxMunus has successfully conducted 100000+ trainings in India, USA, UK, Australlia, Switzerland, Qatar, Saudi Arabia, Bangladesh, Bahrain and UAE etc.
For Demo Contact us.
Nitesh Kumar
MaxMunus
E-mail: nitesh@maxmunus.com
Skype id: nitesh_maxmunus
Ph:(+91) 8553912023
http://www.maxmunus.com/
Very Great Post.. ..Thank you sharing the useful information..
ReplyDeleteWebsite Designing Company in Delhi | Website Designing Company in Rohini | Website Designing Company in Kirti Nagar
Very good Post.....Thank you sharing the useful information..
ReplyDeleteWebsite Designing Company in Delhi | Website Designing Company in Rohini | Website Designing Company in Kirti Nagar
Thank you for sharing such an informative news with us. Keep on sharing Contents like this. You can also share this content on various sites like the Automation Associates LLC site.
ReplyDeleteThank you for sharing this excellent post. The post is handy and useful. You can also share these type of posts in the platforms like Wordpress, the famous Blogspot site, the all favorite Tumblr site and also in the location like Medium and lastly to the Live Journal site.
ReplyDeleteThis is the kind of post I was searching for today. Awesome post and very useful and easy to read. Thank you for sharing this wonderful; post. You can also share these post on the Social media's like Google Plus, the all time hit Facebook, the notorious Twitter, the business sharing site LinkedIn and lastly to the famous Infographic site Pinterest to gain more traffic to your blog post.
ReplyDelete
ReplyDeleteReally nice information. It is very useful and informative post. Thanks for sharing.
Mobile & Analytics
Thanks For Your valuable posting, it was very informative
ReplyDeletetoshiba q300 interne ssd
• Nice and good article. It is very useful for me to learn and understand easily. Thanks for sharing your valuable information and time. Please keep updatingAzure Online course Hyderabad
ReplyDeleteIt is extremely nice to see the greatest details presented in an easy and understanding manner.
ReplyDeleteWeb Development Services in Bangalore
Website Design and Development Services in Bangalore
Hi,
ReplyDeleteThanks for sharing a very interesting article about Theme complete tutorial. This is very useful information for online blog review readers. Keep it up such a nice posting like this.
From,
Maestro Infotech,
Web Design Company Bangalore
Thanks for the post, I am techno savvy. I believe you hit the nail right on the head. I am highly impressed with your blog.
ReplyDeleteIt is very nicely explained. Your article adds best knowledge to our Java Online Training from India.
or learn thru Java Online Training from India Students.
Thanks for sharing amazing information !!!!!!
ReplyDeletePlease keep up sharing.
Thank you for sharing valuable information
ReplyDeleteMobile app training institue in chennai
Web designand developemnt training institue in chennai
Digital Marketing training institue in chennai
Amazing post.Thanks for your details and explanations..I want more information from your side.Thank you
ReplyDeleteTrading erp software in chennai
thank you so much, sir for Sharing this informative blog
ReplyDeleteIt is very nice information about the digital marketing.Thanks for sharing with us. Web Development Company in Bangalore | Best Web Design Company in Bangalore | Web Development Company in Bangalore
ReplyDeleteIt is nice blog Thank you porovide important information and i am searching for same information to save my time Ruby on rails Online
ReplyDeletethank you so much, sir for Sharing this informative blog
ReplyDeletelaptop service center in kk nagar
mobile service center in kk nagar
acerlaptop service center in kk nagar
dell laptop service center in kk nagar
lenovo laptop service center in kk nagar
Hi! Thank you for the share this information. This is very useful information for online blog review readers. Keep it up such a nice posting like this.
ReplyDeleteWebsite Design
SEO Company
Hi! Thank you for the share this information. This is very useful information for online blog review readers. Keep it up such a nice posting like this.
ReplyDeleteWebsite Design
SEO Company
Amazing Article ! I have bookmarked this article page as i received good information from this. All the best for the upcoming articles. I will be waiting for your new articles. Thank You ! Kindly Visit Us @ Coimbatore Travels | Ooty Travels | Coimbatore Airport Taxi | Coimbatore taxi
ReplyDeleteYour very own commitment to getting the message throughout came to be rather powerful and have consistently enabled employees just like me to arrive at their desired goals.
ReplyDeleteBest Devops Training in pune
Data science training in Bangalore
Useful information.I am actual blessed to read this article.thanks for giving us this advantageous information.I acknowledge this post.and I would like bookmark this post.Thanks
ReplyDeleteSelenium training in Chennai
Selenium training in Bangalore
Selenium training in Pune
Selenium Online training
This comment has been removed by the author.
ReplyDeleteInformation from this blog is very useful for me, am very happy to read this blog Kindly visit us @ Luxury Watch Box | Shoe Box Manufacturer | Candle Packaging Boxes | Wallet Box
ReplyDeleteI have to search sites with relevant information on given topic and provide them to teacher our opinion and the article.
ReplyDeletestate employee cashless treatment scheme
Truly, this article is really one of the very best in the history of articles. I am a antique ’Article’ collector and I sometimes read some new articles if I find them interesting. And I found this one pretty fascinating and it should go into my collection. Very good work!
ReplyDeletesenior citizen saving scheme
An effective setup could be venues providing testing infrastructure and sending data to the event app. virtualedge and thank you for attending birthday party
ReplyDeletecss founder is the right way to build your business website. We are known as the best Web Design Company in Navi Mumbai, we have delivered 4500+ projects across the world. You may connect with us for more information.
ReplyDeleteWe are providing the best smartphone insurance. Connect with us (Your Mobile Insurance) to get the best and fast replacement and repair service.
ReplyDeleteWe are the best provider of tent rental in Dubai, UAE. Connect with us if you are looking for the best tents for rent. We can be the right choice for you.
ReplyDeleteOutdoor Sun Shades Rental Dubai
We are known as the best web design company in navi mumbai that have delivered many successful projects across the world. We can be the right choice for you. Connect with us for more information.
ReplyDeleteReally amazing information, thanks for your efforts for this blog. Thank you so much for sharing this post
ReplyDeleteCar Parking Shades Supplier
Connect with the best SEO Company in Mumbai that can provide you fully digital marketing solution at an affordable price. Connect with us for more information.
ReplyDeleteMMORPG
ReplyDeleteInstagram takipçi satın al
tiktok jeton hilesi
tiktok jeton hilesi
antalya saç ekimi
Instagram takipçi satın al
instagram takipçi satın al
metin2 pvp serverlar
instagram takipçi satın al
smm panel
ReplyDeletesmm panel
iş ilanları
İnstagram Takipçi Satın Al
Hirdavatci
https://www.beyazesyateknikservisi.com.tr
servis
tiktok jeton hilesi
minecraft premium
ReplyDeletenft nasıl alınır
lisans satın al
uc satın al
özel ambulans
en son çıkan perde modelleri
en son çıkan perde modelleri
yurtdışı kargo
Need professional WordPress Web Design Services? We're experts in developing attractive mobile-friendly WordPress websites for businesses. Contact us today! https://just99marketing.com/wordpress-web-design
ReplyDelete“Though fancy may be the patient’s complaint, necessity is often the doctor’s. Medical Centre in Dublin - Thorndale Medical Clinic
ReplyDeleteUse CSS Founder's website price calculator and check your Website development cost free.
ReplyDeletesalt likit
ReplyDeletesalt likit
GVYO
Article intéressant et très instructif sur Liferay. Aide beaucoup. Nous proposons également les services Liferay Angular. Contactez-nous pour obtenir plus de détails
ReplyDeleteWelcome to VisitsVisa, your trusted source for all things related to India visa applications. As one of the leading visa service providers, we understand the importance of a seamless and hassle-free visa application process. Whether you are traveling for business or leisure, obtaining an India visa is an essential step.
ReplyDeleteTo attract customers, a web design company in Pune should prioritize an attractive and user-friendly interface. The website should convey the brand identity intuitively using attractive graphics and intuitive navigation. Responsive design is important to ensure optimal performance across all devices. Including strategic calls-to-action and easy-to-find contact information increases user engagement.
ReplyDeleteIf you are looking for the best solar panels dallas then you should connect with us.
ReplyDelete