Dockbar themes

Welcome to my first post!

As a theme developer in Liferay I start this blog with the goal of sharing all type of useful content.

I want to speak about a little frequent problem with dockbar, sometimes the dockbar could disturb if our portal design collides with it. The first advice that I can give you is to show the dockbar only when the user really needs it, for this we only need to change the permissions and adapt them to your needs. We never should delete the dockbar because the administrator users would lose much of his advantages.
 
Thinking on this problem, I have worked on themes which change the aspect, position, colors and add 'responsive design improvements' of our dockbar. These basic themes work in Liferay 6.2 CE and EE.

 

The first theme is based on _styled and tries to get the style of 'Classic responsive dockbar' adding the posibility of customice colours, for this we only need to add dockbar_classic.css in our _styled theme, into main.css:

main.css, last line:

@import url(dockbar_classic.css);

 

We are going to work with dockbar split because changes will be more visible, to add the class dockbar-split in our Body, like Nate told us time ago:
https://www.liferay.com/es/web/nathan.cavanaugh/blog/-/blogs/the-nitty-gritty-theme-improvements-and-bootstrap-in-liferay-6-6

Or adding a theme variable:

Adding on liferay-look-and-feel.xml:

<setting configurable="true" key="dockbar-split" type="checkbox" value="true" />

and init_custom.vm or portal_normal.vm:

#set ($dockbar = $theme.getSetting("dockbar-split"))

#if ($dockbar == true)
   #set ($css_class = "${css_class} dockbar-split")
#end

If you want to modify the dockbar colours, you only need to open the dockbar_classic.css and modify the next lines:

Some examples:

 

Easy or not? ;)

dockbar-classic-theme Github:
https://github.com/marcoscv-work/experimental-liferay-themes/tree/master/dockbar-classic-theme

 

Now we are going to get our dockbar and give it a new aspect and funcionallity, it will look like this animation:

 

 

I called this theme “dockbar vertical”.

We will follow the same way that we've made at the previus example, adding the css file dockbar_vertical.css into a custom.css (_styled theme based):

@import url(dockbar_vertical.css);

 

And a little script into main.js, to create new icon to open dockbar and detect click over this icon:

if (portletDockbar) {
  var BODY = A.getBody();
  BODY.append('<div class="icon-toggle-dockbar vertical-dockbar-close"><i class="icon-cog"></i></div>');
  BODY.append('<div class="layer-mobile visible-phone vertical-dockbar-close"></div>');
  var toggleDockbar = A.one('.icon-toggle-dockbar');
  var toggleDockbarClose = A.all('.vertical-dockbar-close');
  var toggleDockbarIcon = A.one('.icon-toggle-dockbar .icon-cog');

  if (toggleDockbar) {
    toggleDockbarClose.on(
    'click',
      function() {
        portletDockbar.toggleClass('over');
        toggleDockbar.toggleClass('over');
        toggleDockbarIcon.toggleClass('icon-remove');
        toggleDockbarIcon.toggleClass('icon-cog');
        BODY.toggleClass('lfr-has-dockbar-vertical');
      }
    );
  }
};

 

Obviously we have two new images to create the user background animation:

To customice this animation you can changue the images directly or change the css animation opening the file dockbar_vertical.css at lines 678 to 685, you could delete or remplace for example by a static background:

&>a {
  background: url(@theme_image_path@/dockbar_vertical/back-user.png) no-repeat left top
}

dockbar-vertical-theme Github:
https://github.com/marcoscv-work/experimental-liferay-themes/tree/master/dockbar-vertical-theme

 

The third theme which I called “ bubbles dockbar” works similar to the two previous dockbars, adding the dockbar-bubbles.css into your main.css.
You can see it in this animation:

We could customize the colours and icons sizes:

 

dockbar-bubbles-theme Github:
https://github.com/marcoscv-work/experimental-liferay-themes/tree/master/dockbar-bubbles-theme

 

These themes are going to be updated on my github:
https://github.com/marcoscv-work/experimental-liferay-themes/
If you prefer take a quick look you can download the wars here:
 

Get more live info in my twitter account: @marcoscava

Please, let me know your feedback to keep improving! ;)

Blogs
how to add sub child in navigation bar dropdown list in "lateral-nav-theme"
for example.
Dashboard
- Profile
- Account
- Option <---- Option has sub child too
- Personalize
- Edit
I'm not sure what you need, by default the child-menu is tabulated, if you need hide the child-menus you could control its visibility into custom.css, using 'child-menu' class, fox example:

@include respond-to(desktop) {
#navigation {
li {
.child-menu {
display: none;
}

&:hover .child-menu {
display: block;
}
}
}
}

If you need something different, I'm sure you can find a lot of information in our forums: http://www.liferay.com/es/community/forums/-/message_boards/message/8796618
Hallo Markus,

Could I integrate the dockbar-Themes in my existing Theme?

Thanks!
Morad.
Of course, you only need delete your dockbar styles (if you have it) and add the css/js which you prefer, also you should add in your body the main class, for example for dockbar-vertical-theme this master class is called 'dockbar-vertical', and is added on portal_normal, line 18:

#set ($css_class = "${css_class} dockbar-vertical")

https://github.com/marcoscv-work/experimental-liferay-themes/blob/master/dockbar-vertical-theme/docroot/_diffs/templates/portal_normal.vm

In summary, only add the CSS, the JS function and a class in your body.
It is a great contribution, congratulations on breaking the ice. Thanks for the theme.
Hi Marco,

First of all, great post. Love your ways of adapting the dockbar - will surely try out your examples.

In the beginning of your post you mention dockbar and permissions:

"The first advice that I can give you is to show the dockbar only when the user really needs it, for this we only need to change the permissions and adapt them to your needs."

I've been looking for dockbar permissions in the control panel when configuring roles. But I have yet not found it.

Best solution so far - check whether user has a certain role. This, however, implies checking for role membership rather than for permissions when including the dockbar (or not) in the theme.

Do you have any good suggestions regarding this?

Cheers,
Erik
Hi Erik,

Another good practice is to bear in mind the dockbar into our designs from first time, on this way the designer could decide what dockbar is better.

Also, sometimes we decide to show the 'dockbar' to guest users, only to show them the login link or hamburguer mobile icon, we should think how many users are going to see the dockbar to decide about it, but we never must delete it.

For example, If we are going to have 99% of guest users because our site is an information site, maybe we could hide the dockbar and show it only to logged users with a simple conditional:

#if ($is_signed_in)
#dockbar()
#else
<a href="$sign_in_url" class="sign-in" rel="nofollow" role="menuitem">
$sign_in_text
</a>
<a href="$portalUtil.getCreateAccountURL($request, $themeDisplay)">
#language ("register")
</a>
#end

If you are not logged, the link to register and login appears.

As you know in our foros and http://dev.liferay.com we have a lot of information about permissions.
now i already implement your projects thanks for this
last question, how to default the "lateral-nav-theme" to be open instead of closed and im not sure if im only encounter this, when scrolling up/down the navigation bar has little bit of glitch or delay in tablet and mobile platform but in desktop it is normal, thanks
Hi Carl,

You need modify the theme, adding a class called "opened" in body, for example, adding in line 26:

#set ($css_class = "${css_class} opened")

With this line you are going to start seeing the navbar open.

About the effect when scrolling up/down, could you send me any example by email? I can not reproduce the error

Thank you.
Hi Marcos,

I already fix the mobile / tablet gliches, i will credit your name your name as part of my projects

Thank you very much
Hello Marcos, I solved the "Unable to import DDM structure Map" error.

Before to deploy your theme, the default language of all portal instances have to be set to English - US.

regards,
Ivano C.
Dear Marcos, I just downloaded the Madrid Theme and deployed but I got the below error - please could you help me to solve it ?

Thank you in advance for your support !

Ivano C.

11:30:39,180 INFO [localhost-startStop-2][HotDeployImpl:217] Deploying madrid-theme from queue
11:30:39,180 INFO [localhost-startStop-2][PluginPackageUtil:1016] Reading plugin package for madrid-theme
11:30:39,305 INFO [localhost-startStop-2][HookHotDeployListener:693] Registering hook for madrid-theme
11:30:39,305 INFO [localhost-startStop-2][HookHotDeployListener:821] Hook for madrid-theme is available for use
11:30:39,320 INFO [localhost-startStop-2][ThemeHotDeployListener:98] Registering themes for madrid-theme
11:30:40,896 INFO [localhost-startStop-2][ThemeHotDeployListener:113] 1 theme for madrid-theme is available for use
11:31:10,139 INFO [liferay/hot_deploy-1][ResourcesImporterHotDeployMessageListener:129] Importing resources from madrid-theme to group 3027702 takes 27121 ms
11:31:16,929 WARN [liferay/hot_deploy-1][FileSystemImporter:469] Unable to import DDM structure Map
com.liferay.portlet.dynamicdatamapping.StructureNameException
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.validate(DDMStructureLocalServiceImpl.java:1770)
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.validate(DDMStructureLocalServiceImpl.java:1802)
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.validate(DDMStructureLocalServiceImpl.java:1760)
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.addStructure(DDMStructureLocalServiceImpl.java:158)
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.addStructure(DDMStructureLocalServiceImpl.java:284)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175)
at com.sun.proxy.$Proxy215.addStructure(Unknown Source)
at com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil.addStructure(DDMStructureLocalServiceUtil.java:606)
at com.liferay.resourcesimporter.util.FileSystemImporter.addDDMStructures(FileSystemImporter.java:441)
at com.liferay.resourcesimporter.util.ResourceImporter.addDDMStructures(ResourceImporter.java:212)
at com.liferay.resourcesimporter.util.FileSystemImporter.setUpAssets(FileSystemImporter.java:1665)
at com.liferay.resourcesimporter.util.FileSystemImporter.doImportResources(FileSystemImporter.java:1264)
at com.liferay.resourcesimporter.util.ResourceImporter.importResources(ResourceImporter.java:47)
at com.liferay.resourcesimporter.messaging.ResourcesImporterHotDeployMessageListener.importResources(ResourcesImporterHotDeployMessageListener.java:124)
at com.liferay.resourcesimporter.messaging.ResourcesImporterHotDeployMessageListener.initialize(ResourcesImporterHotDeployMessageListener.java:73)
at com.liferay.resourcesimporter.messaging.ResourcesImporterHotDeployMessageListener.onDeploy(ResourcesImporterHotDeployMessageListener.java:86)
at com.liferay.portal.kernel.messaging.HotDeployMessageListener.doReceive(HotDeployMessageListener.java:55)
at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:26)
at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:72)
at com.liferay.portal.kernel.messaging.SerialDestination$1.run(SerialDestination.java:65)
at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask._runTask(ThreadPoolExecutor.java:682)
at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask.run(ThreadPoolExecutor.java:593)
at java.lang.Thread.run(Thread.java:744)
11:31:16,945 ERROR [liferay/hot_deploy-1][SerialDestination:68] Unable to process message {destinationName=liferay/hot_deploy, response=null, responseDestinationName=null, responseId=null, payload=null, values={groupId=0, command=deploy, companyId=0, servletContextName=madrid-theme}}
com.liferay.portal.kernel.messaging.MessageListenerException: com.liferay.portlet.dynamicdatamapping.StructureNameException
at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:32)
at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:72)
at com.liferay.portal.kernel.messaging.SerialDestination$1.run(SerialDestination.java:65)
at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask._runTask(ThreadPoolExecutor.java:682)
at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask.run(ThreadPoolExecutor.java:593)
at java.lang.Thread.run(Thread.java:744)
Caused by: com.liferay.portlet.dynamicdatamapping.StructureNameException
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.validate(DDMStructureLocalServiceImpl.java:1770)
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.validate(DDMStructureLocalServiceImpl.java:1802)
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.validate(DDMStructureLocalServiceImpl.java:1760)
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.addStructure(DDMStructureLocalServiceImpl.java:158)
at com.liferay.portlet.dynamicdatamapping.service.impl.DDMStructureLocalServiceImpl.addStructure(DDMStructureLocalServiceImpl.java:284)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175)
at com.sun.proxy.$Proxy215.addStructure(Unknown Source)
at com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil.addStructure(DDMStructureLocalServiceUtil.java:606)
at com.liferay.resourcesimporter.util.FileSystemImporter.addDDMStructures(FileSystemImporter.java:441)
at com.liferay.resourcesimporter.util.ResourceImporter.addDDMStructures(ResourceImporter.java:212)
at com.liferay.resourcesimporter.util.FileSystemImporter.setUpAssets(FileSystemImporter.java:1665)
at com.liferay.resourcesimporter.util.FileSystemImporter.doImportResources(FileSystemImporter.java:1264)
at com.liferay.resourcesimporter.util.ResourceImporter.importResources(ResourceImporter.java:47)
at com.liferay.resourcesimporter.messaging.ResourcesImporterHotDeployMessageListener.importResources(ResourcesImporterHotDeployMessageListener.java:124)
at com.liferay.resourcesimporter.messaging.ResourcesImporterHotDeployMessageListener.initialize(ResourcesImporterHotDeployMessageListener.java:73)
at com.liferay.resourcesimporter.messaging.ResourcesImporterHotDeployMessageListener.onDeploy(ResourcesImporterHotDeployMessageListener.java:86)
at com.liferay.portal.kernel.messaging.HotDeployMessageListener.doReceive(HotDeployMessageListener.java:55)
at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:26)
... 5 more
Hi Castro,

Is there any scope of using the dockbar_classic in a classic styled theme.
Hi Sathish,

Yes, you can but there is a CSS in classic called dockbar.css which you can modificate too.

Anyway my dockbar_classic I think is easier to understand and change colors, so it's your decision! emoticon
Hi,
Nice article.

Could you please tell me, what changes I should make so that my dockbar collapses on resolutions width less than 786px?

Currently the dockbar collapses on 979px.

Thanks.
What of these dockbars are you using? emoticon !
I am using the default dockbar which comes with Liferay.
Currently, the dockbar/navbar collapses when screen width is less than 979px.
I want the dockbar/navbar to collapse on screen sizes less than 768px.
I made changes in _variables.scss file as below:

$navbarCollapseWidth: 768px !default;
$navbarCollapseDesktopWidth: $navbarCollapseWidth + 1;

Copied this file inside diff folder. Deployed the code. But, still the dockbar collapses on screen size less than 979px.

Am I supposed to make changes in any other files ?
Oh I see! you are changing the navbar bootstrap component:
http://getbootstrap.com/2.3.2/components.html#navbar

It's not the same for Dockbar, Dockbar is a Liferay custom component, and you can change it in dockbar.css file in your theme, there you will see different respond-to includes:

@include respond-to(

And you can change them to fit it to what you need. ;-) !
I can see the below code in dockbar.css

@media (max-width: 1140px) {
.dockbar-split .dockbar .info-items {
width: 515px;
}
}

@include respond-to(phone, tablet) {
#navigation {
display: none;

&.open {
display: block;
}
}

.dockbar-split .dockbar {
height: auto;
position: relative;

.navbar-inner {
width: auto;
}
}

.user-avatar-image {
width: 18px;
}
}

What changes should I do so that the dockbar collapses on resolution less than 768px. (only on mobile phone).
In a quick view, I would delete all "tablet" referees, for example, this line:

@include respond-to(phone, tablet) {
#navigation {
display: none;

those lines are hiding the navigation in tablet also (979px to 768px) If you only need it in mobile (lees than 768px), deleting "table" from the respond-to include should work:

@include respond-to(phone) {
Hi,
Nice article.

Could you please tell me, what changes I should make so that my dockbar collapses on resolutions width less than 786px?
Currently the dockbar collapses on 979px.

Thanks.
Hi Marcos,

Thanks for the excellent snippets. Just wanted to know, if these dockbars can be used in commercial application(s). I mean do you have some copyright associated with them ?


Thanks and Regards
Narsingh Pal
Hello Marcos. I am a new liferay user and I am loving these dockbar-themes. I have integrated your dockbar-bubbles into my theme. Everything is working fine, but I would like to make the bubble on the right side of my page as opposed to the left. Also id like to flip the resulting bubbles so they look good on the right. Any tips to help me get this accomplished?
Hey Johnathan Hendrix,

Probably changing left for right and right for left in:
https://github.com/marcoscv-work/experimental-liferay-themes/blob/master/dockbar-bubbles-theme/docroot/_diffs/css/dockbar-bubbles.css

If this weekend I have free time I will try to do it in a new branch :-D
Thanks for the quick reply and update Marcos. You advice pointed me in the direction to get the effect I desired. I made the following changes.

Added this to dockbar-bubbles.css:
.aui .dockbar{
left: unset !important;
right: 27px !important;
}
Made the following changed to dockbar-bubbles.css: values of right previously were left.
ul.nav-add-controls {
width: ($dockbarMaCWidth*4);
float: right;

li {
float: right;