Get that old school page editing touch back again

Since Liferay 7.0 we've been blessed with portlet decorators and themelets. Here's an example of how to put them to practice.

At this years Unconference at DEVCON in Amsterdam, Victor Valle kept a session about changing the look-and-feel of the portal administration. Things like removing the default product menu and creating your own. I missed that discussion because so many other interesting discussions were going on, so I have no idea if someone brought this up. In this blog article, I'm not going to do anything "drastic" like like removing a side menu. I just want to show you how easy it is to get something back which some of us missed since version 6.2.

I've heard some people complain about the way the page editing works since version 7.0, and it seems like themelets are still pretty much an underrated or unknown addition to Liferay theming. I hope this blog will tackle both.

By default you'll have to hover over a portlet or widget to get the configuration options:

Nothing wrong with it. The page is displayed as anyone without editing rights would see the page. No need to toggle that icon which shows/hides the controls. But for those who have to do a lot of page editing or widget configuration, ... every second counts. We just want to click on the ellipsis icon to configure that widget without having to hover over it first.

Some of us want this:

There are different ways to get this toggle controls feature back

After all, the controls icon did not disappear. It only becomes visible when your screensize is small enough. So it's all a matter of tweaking the styles.

Option 1: Portlet decorators

You can easily add your own portlet decorator and make it the default one in your theme. You just need to add the custom decorator in the  look-and-feel.xml of your theme:

<portlet-decorator id="show-controls" name="Show Controls">
   <default-portlet-decorator>true</default-portlet-decorator>
   <portlet-decorator-css-class>portlet-show-controls</portlet-decorator-css-class>
</portlet-decorator>

Then you will want to add some css to the theme so the toggle controls icon is displayed at all time. Toglling the icon will add a css class "controls-visible" to the body element. This is easy, just display the "portlet-topper" everytime "controls-visible" is present.

Why this option is bad for this purpose: I believe portlet decorators are meant for styling purposes. How do you want the user to see the widget when you select a certain decorator. When you want to use portlet decorators for this purpose and you want to display widgets in different ways, with(out) borders or titles... This means you'll lose the controls anyway when you assign a different decorator to a widget. I bet you'll say: "Just put the extra styles on every widget". So just forget I even brought this up.

Option 2: Add some css and js

We'll add the custom css to the theme:

/* old school portlet decorators, don't mind the shameless usage of !important */
.control-menu .toggle-controls {
    display: block !important;
}
.controls-visible.has-toggle-controls {
    .portlet-topper {
        display: -webkit-box !important;
        display: -moz-box !important;
        display: box !important;
        display: -webkit-flex !important;
        display: -moz-flex !important;
        display: -ms-flexbox !important;
        display: flex !important;
        position: relative;
        opacity: 1;
        transform: none !important;
    }
    section.portlet {
	border: 1px solid #8b8b8b;
	border-radius: 0.5rem;
    }
}
.controls-hidden {
    .portlet-topper {
        display: none !important;
    }
}

We're not there yet. We'll need to put a "has-toggle-controls" class on the body element because it seems "controls-visible" is there by default, even when you're not logged in. And in this case I want to display a border around the portlet when the controls are active. So I'll be setting my own css class like this inside main.js:

var toggleControls = document.querySelector('.toggle-controls');

if (toggleControls !== null) {
	document.body.classList.add('has-toggle-controls');
}

But what if we had lots of different themes. Are we really going to add the same code over and over again? And what if business decides to add a box-shadow effect after a few weeks?

Option 3: Themelets

A themelet is an extension of a theme. You can extend all your themes with the same themelet. When some style needs to change, you just edit the themelet and rebuild your themes. This will require you to use the liferay-theme-generator. But I bet everyone does by now, right? More information on how to build and use themelets.

You can find the themelet I wrote on github.

Please be sure your theme's _custom.scss imports the css from themelets:

/* inject:imports */
/* endinject */

And your portal_normal.ftl should contain:

<!-- inject:js -->
<!-- endinject -->

Conclusion

When changing the behaviour or design of certain aspects which are not design (in the eye of the end users or guest users) related, I think its always better to go with themelets. You'll rarely come across a portal with only one theme. So using themelets will make it so much easier to maintain your themes.

Blogs

Nice use case.  It recall Liferay 6.2 toggle feature. we have seen many client asking what you have explain instead of hover for Liferay 7 DXP. 

Very nice post Michael! 

 

I'm very interested in hearing any additional thoughts that you may have regarding how to provide a great administration experience.