Creating a Liferay Marketing Theme

Introduction

So I'm not the best theme person around.  I'm less a UI guy and more of an implementation person.  Honestly I hate working on themes.  Maybe it's just me, but all of the styling work that you have to do in Liferay, well honestly I find it quite daunting.

And when you throw in Bootstrap for responsiveness, SASS for "simplified" stylesheets, FontAwesome, etc., well for me things just go from bad to worse.

I have my head down in the core all day, why would I want to step out of that clean, organized world (wink) to dip my toes into (what I consider) the mess that is theming?

Well, there's no use complaining about it.  I need a theme for a custom personal site I'm working on.  I envison a main page kind of like what Liferay.com is using and support pages that will probably adhere to more of a classic sort of flavor for child pages.  The main page, for a developer, well that will feel pretty worthless, but it's just one of those things that everyone needs these days and I'm itching for a learning experience, so this blog entry is going to follow my effort for creating such a theme in Liferay.

I'm not alone in this kind of need.  Recently my friend Jack Bakker posted in the forum how to put together a theme like the one Liferay has for https://www.liferay.com/web/events2015/northamerica/ and the wordpress-like theme on the child pages such as https://www.liferay.com/web/events2015/northamerica/why-attend.

So since I was creating a similar theme, I thought I'd capture the how-to about it and include it here in a new blog post.

Starting Point

So along with not being a theme person, well I'm not much of an artist.  I can look at web sites and identify things I like and things I don't like, but if you ask me to create a "standard" marketing page I would spend days scratching out ideas and probably come up empty.

So what I needed was a starting point.  Somewhere that I could grab a workable theme idea.  Something that had the marketing-like concept from the North America Symposium site but where I wasn't really stealing their work.

I remembered a story recently on Slashdot that pointed to a site created by a couple of college students that would generate mock startup websites.  The images, etc are all covered by the Creative Commons, so I figure I can borrow from them since I'm more than willing to give appropriate attributions.

So the site is http://tiffzhang.com/startup/ and each time you click on it you should get a completely fresh website.  Do it a couple of times and you'll see familiar patterns on the pages, from a single image which stays permanently in place while the scrollable area slides over it, a consistent color palette based on image colors, responsive layout based on Bootstrap, leverages FontAwesome, etc.  Basically everything that I'm looking to implement.  Since the site is not based on Liferay, I'm just effectively using the CC images and concepts from their site, but like I said all real credit for the look and feel I give to them.

I flipped through a couple of times in Firefox until I found a basic color palette and background image that would work.  I used Firefox's save feature to save the complete web page so I got images, css, and the main page.

I'm sure you're wondering why I'm spending a lot of time explaining how I came up with the starting theme.  It's not really my goal to show everyone how to grab someone else's ideas.

But for many of you developers out there, I'm now at the point where you will be when some whiz-bang UI developer comes to your cube with a zip file full of her excellent UI designs in simple HTML, CSS, JS and imagery and they say "Here you go, now make Liferay look like this..."

That's hopefully what we'll get out of this blog, a fancy front page theme for Liferay to impress your coworkers and bosses.

Creating the Projects

So we're actually going to be creating three different projects - two theme projects and one layouttpl project.  One theme project will cover the main page and the second theme will provide the wordpressy-like child page themes.  The layouttpl project will allow us to define the separate zones that will exist in the pages and allow the themes to define how the zones will look.

Wanting to leave the IDE out of the picture, we can create our theme projects using "mvn archetype:generate".  Use the "liferay-theme-archetype" to create a new theme projects and give them relevant values.  Use the "liferay-layouttpl-archetype" to create a new layout template project and give it the relevant values.

New theme projects use "_styled" as the parent theme in the pom.xml file; that's a good enough starting place for our front page since most other themes would be overkill for what we're doing.

If you're using the SDK, you should do an initial project build of the themes right off.  This will pull in the theme files from the _styled theme so you just have to create the _diffs folders and start adding your override files.  For Maven developers, you can just start adding your overrides to the src/main/webapp folders and when you build the projects, Maven will take care of merging the files.

I'm using Maven for these projects (as I'm doing for all of my projects these days), so if you're using the SDK you'll have to modify the instructions appropriatiately.  I would recommend that you get off of the SDK as soon as you can since that's the apparent direction Liferay is giving us.

The themes that I'm creating have CSS, images, JS and, of course, their own Velocity templates, so we should create the src/main/webapp/css, src/main/webapp/images, src/main/webapp/js and src/main/webapp/templates folders where our files will go.

Images are further divided by type.  The marketing theme I'm using really only needs the background image (I'm not going to be using the face images), but I'll put it in a src/main/webapp/images/theme folder (use your theme project as the folder name) to keep it (and possibly others) separate from regular theme images.

The layout template project is pretty much ready to start editing right away, so we'll actually tackle that first.

Creating the Layout Template

The layout template is really important for the marketing type themes.  These themes typically take up 100% of the width of the browser (I love that) and a bunch of different rows each styled differently.

From  http://tiffzhang.com/startup/, we see 7 different rows that contain different content: Hero, Quote, Why, Quote, Team, Quote, Sponsors and Footer.  There's also the header (with navigation).  Most of the rows are a single column, but the Why and Team sections are actually 3 column.

We'll mimic the same layout and use as our row types: hero, quote, why, team, sponsors and footer.  These are going to be the basis for our classes for the sections of the layout.  Our final layout is going to be, in Liferay naming venacular, 1-1-3-1-3-1-1-1  cheeky

Here's the content for our marketing layout template file:

<div class="full-screen-layout" id="main-content" role="main">
    <div class="portlet-layout row-fluid vol-hero">
        <div class="portlet-column portlet-column-only span12" id="column-1">
            $processor.processColumn("column-1", "portlet-column-content portlet-column-content-only")
        </div>
    </div>
    <div class="portlet-layout row-fluid vol-quote">
        <div class="portlet-column portlet-column-only span12" id="column-2">
            $processor.processColumn("column-2", "portlet-column-content portlet-column-content-only")
        </div>
    </div>
    <div class="portlet-layout row-fluid vol-why">
        <div class="portlet-column portlet-column-first span4" id="column-3">
            $processor.processColumn("column-3", "portlet-column-content portlet-column-content-first")
        </div>

        <div class="portlet-column span4" id="column-4">
            $processor.processColumn("column-4", "portlet-column-content")
        </div>

        <div class="portlet-column portlet-column-last span4" id="column-5">
            $processor.processColumn("column-5", "portlet-column-content portlet-column-content-last")
        </div>
    </div>
    <div class="portlet-layout row-fluid vol-quote">
        <div class="portlet-column portlet-column-only span12" id="column-6">
            $processor.processColumn("column-6", "portlet-column-content portlet-column-content-only")
        </div>
    </div>
    <div class="portlet-layout row-fluid vol-team">
        <div class="portlet-column portlet-column-first span4" id="column-7">
            $processor.processColumn("column-7", "portlet-column-content portlet-column-content-first")
        </div>

        <div class="portlet-column span4" id="column-8">
            $processor.processColumn("column-8", "portlet-column-content")
        </div>

        <div class="portlet-column portlet-column-last span4" id="column-9">
            $processor.processColumn("column-9", "portlet-column-content portlet-column-content-last")
        </div>
    </div>
    <div class="portlet-layout row-fluid vol-quote">
        <div class="portlet-column portlet-column-only span12" id="column-10">
            $processor.processColumn("column-10", "portlet-column-content portlet-column-content-only")
        </div>
    </div>
    <div class="portlet-layout row-fluid vol-sponsors">
        <div class="portlet-column portlet-column-only span12" id="column-11">
            $processor.processColumn("column-11", "portlet-column-content portlet-column-content-only")
        </div>
    </div>
    <div class="portlet-layout row-fluid vol-footer">
        <div class="portlet-column portlet-column-only span12" id="column-12">
            $processor.processColumn("column-12", "portlet-column-content portlet-column-content-only")
        </div>
    </div>
</div>

This defines our layout (I've already copied to the wap template so they both match).  The important aspect to notice here is the addition of classes to the divs for the separate rows.  I've prefixed my classes with "vol-" to avoid namespace conflicts, but otherwise you'll see I've used the types that we picked out earlier.

For the child pages such as Why Attend, well this page has specific theming support but uses a standard 1 column layout template, so we don't need a custom template here.

Layout templates are fairly easy to create, but they're just as easy to build, deploy and test.  Build your layout template project and deploy it to your portal (verifying deployment is completed without error).  Now you should be able to log in and use the layout template to test the results.

Using the classic theme and your new layout, you can drop web content displays into each area (Classic gives you a big drop zone for each column).  Here's what I got when I did it locally:

Not very flashy for certain, but it does give you an idea of where we're headed.

Building the Marketing Theme

Next we'll start on the marketing theme.  I'm not really going to get into the CSS stuff myself, I managed to get it all working and frankly this is a Liferay site, not a CSS site, so we'll leave you to find some other source for the CSS details.

I do want to highlight some of the important parts, though, the ones that make the theme work.

Navigation

So there's two basic forms that the navigation menu take.  The first, such as the one on liferay.com, has the navigation at the top of the page above the hero image.  The second, such as the one on the 2015 Symposium, has the hero image above the navigation.

The first case is the close to the classic Liferay navigation found in many themes, even classic.  The big difference would be the absence of the big company image in the upper left corner, now there's typically a much smaller image (sized per the nav area) that is part of and to the left of the navigation on the right.  For this implementation, you're really going to be tweaking the portal_normal.vm file to get rid of the big company logo above navigation in lieu of a smaller image that is integrated right into the navigation bar.  You can still stick with Liferay's use of the dynamic company logos as long as you keep em small or something that will scale correctly to the nav bar size.  The rest is just a little bit of HTML and CSS magic to get it to work.

The second option with the hero above the navigation, well that one is a little more interesting.  In this case it's a heck of a lot easier if you can just build your hero stuff right into portal_normal.vm to appear above the normal navigation area.  The 2015 Symposium uses this technique to lay out all the hero image above where the navigation fits in.  What makes this so easy is that you can then stick the nav bar to the top of the page as you scroll and you don't have to worry about embedding a dynamic journal article in the header.  Makes the theme specific for your particular need (i.e. the 2015 Symposium theme can only be used for the 2015 Symposium, you'd have to create a new theme for the 2016 Symposium).

Alternatively you could try to use a dynamic hero section in the content area then use funky CSS and JS tricks to manipulate the dom and get it above the nav bar.  It might allow you to use a dynamic hero, but honestly I'd be reluctant to go down this road because it just seems to fragile to me.  I think you'd always be worried about how to get it to work on all past, present and future browsers, mobile, etc.  I cannot say it's not possible cuz I'm sure it is, I guess I'm saying that you'd probably burn through too much time, money and resources just getting it to work and keeping it working.

For my implementation, I'm going with the first version, the nav bar at the top of the page above the content area.  So my portal_normal.vm file starts like this:

<header id="banner" role="banner">
	#if ($has_navigation || $is_signed_in)
		#parse ("$full_templates_path/navigation.vm")
	#end
</header>

Wait, where's the logo?  Where's the sign in link stuff?  Well, like I said, my implementation now has those items embedded within the nav bar.  So I've moved them into navigation.vm.  Basically the logo stuff is right before the <ul> tag for navigation and the sign in link stuff is next after the closing </ul> tag.  Since I'm trying to mimic a marketing page that has greatly simplified the menus, I've taken out the second level navigation stuff too.  Note that to mimic the marketing sites that have menus with links to anchors in the page, just add initial static links as <li /> items in the nav bar just before the normal velocity processing for pages.  You may even choose to exclude the regular nav logic altogether moving it instead to, say, a hamburger menu.  The choice is yours.

Without any styling applied, the top of our page now looks like:

Not significantly different, but we have the basis for our actual nav bar.  All we need to do is apply styles to the appropriate elements and we'll be good to go.

The Hero

So the hero, for those that don't know, is that big worthless image at the top of most marketing sites that have no practical purpose but to show some sort of artwork but mostly it will include happy faces of people you're supposed to think really like the products of the company they're on, but most of the time they are just stock images purchased for use on the page.  Hmm, I wonder if that statement will come across as a bit cynical?

The hero image these days is usually placed as a background image.  Sometimes they stay at the top of the page, but the latest trend is to keep the image at the top of the browser window and let the page content scroll overtop of it, often with one transparent box that scrolls over the window and the rest are opaque and hide the background as the user scrolls down in the page.

My implementation is going to use a similarly placed background image that will be at the top of the browser window and will not scroll.  However, the vol-hero row should be transparent so the background shows through and the content of the hero row will scroll over the image.

So how exactly are we going to build this piece?  Well, it's actually pretty simple.  So first I got my background image and added it to the theme.  The full path for the image is /vol-theme/images/vol/metaldeer.jpg.  I deployed my theme so it would be available.

The rest is done within a web content display.  In the web content display for the vol-hero column, I used the following web content:

<div id="hero-007">
  <p style="text-align: center;"><span style="font-size:24px;"><span style="color:#FFFFFF;">This is the hero page.</span></span></p>
  <p style="text-align: center;">&nbsp;</p>
  <p style="text-align: center;">&nbsp;</p>
  <p style="text-align: center;">&nbsp;</p>
  <p style="text-align: center;">&nbsp;</p>
  <p style="text-align: center;">&nbsp;</p>
  <p style="text-align: center;">&nbsp;</p>
  <p style="text-align: center;">&nbsp;</p>
  <p style="text-align: center;"><span style="font-size:24px;"><span style="color:#FFFFFF;">It is quite large.</span></span></p>
  <p style="text-align: center;">&nbsp;</p>
  <p>&nbsp;</p>
</div>

Pretty simple, but I want to highlight the div which surrounds the content - hero-007.

That's important because we're going to use that for applying the styling.  Here's the rule that was used in custom.css in the theme:

#hero-007 {
    background: url(../images/vol/metaldeer.jpg);
    background-position: top center;
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-size: cover;
    min-height: 500px;
}

If you didn't want to embed this in the theme, another option is to use advanced styling under the look and feel for the web content display portlet.  Load your background image into Docs and Media and get the link to it, that would be the URL to use, otherwise this rule can be used as-is.

Here's how it looks:

Since the background is positioned at the top center and has attachement fixed, it will stay in place as you scroll the page.  Since the lower rows in our layout don't have the background, the image is just the background for the hero area.

A quick note about opacity...  There are some CSS things and JS things you can do to tweak the opacity of the background image.  My big question is simply "why?"  I mean, unless you don't have an image tool on your computer and/or you don't have direct access to the image there's simply no reason not to tweak the image for the right opacity and use that image.  The upside is it will work on all browsers and versions, including mobile, and it won't suffer the fragility of a CSS/JS solution.

Quotes

After seeing the floating background for the hero, tackling the quote sections will be a breeze.  Here we're going to add a class to our theme for the background and the text styling and we'll use a simple web content display area.  The CSS is both long and boring, so it's left out of the blog, but here's how it looks so far:

Note the cool addition of FontAwesome quotes in here, I didn't have to do a thing but reference it in the web content.

There are two options to get the Font Awesome images, the easiest is to output HTML like <i class="icon-left-quote"></i> and the _styled theme actually took care of the rest.  To see the available images in Liferay 6.2, I went to Nick Piesco's Alloy UI Font Awesome Cheat Sheet.  The other option is to use a content style to set the code for the Font Awesome glyph, although the problem you have here is that some codes from FA do not work because of Liferay's own version.

Note that I am perturbed that I can't use normal Font Awesome classes and that Alloy has to have their own implementation because, of course, it's already out of date and even if they shipped an update tomorrow it would probably be out of date the day after. 

The quote itself is really not very special.  It's a <blockquote /> tag with a two-line right-justified <h2 /> underneath.  The blockquote has styles applied to it from the theme:

blockquote:before, .aui blockquote:before {
    top: -20px;
    left: -10px;
    content: "\201C";
}
blockquote:after, .aui blockquote:after {
    top: -20px;
    right: 5%;
    content: "\201D";
}

The important part is the content style, the two codes given are for the left and right quotes respectively.

The Why

So the why row is labeled as such because it supposedly answers the question "Why Us" and has 3 boxes to drop quick imagery that provide the top 3 reasons.  I don't really have reasons, but I will fill in the boxes to see how it looks...

These FontAwesome guys are created by using a div that is styled with a background color circle and an <i class="icon-beer"></i> HTML code (different values for the other icons) to overlay the FontAwesome images.  Again these come from Nick Piesco's Cheat Sheet so any of the listed icon types will work for 6.2.

When laying this out I realized that I wanted a simple header for the 3 cells so I inserted a one-column row above the previous vol-team row in the layout above and dropped this web content in.

The others are basically 3 different web content displays dropped in each of the cells.  Yes, the icons are not centered very well, but that is something that you would fix when tweaking the output.

Conclusion

Sure, the theme is not done, but at this point I think it's clear that I'm just going to keep adding content into web content displays and providing some stuff in the theme to style it the way it should look, to make it the way I want.

I hope, at this point, that it's clear that although some aspects of Liferay theming can be daunting, creating a Marketing theme is not really too difficult.  Trust me, as I said earlier I am not a strong CSS person so if I can do this, you can do it too.

So what's next?  Well, the theme is not very responsive.  I tried shrinking the page and it didn't do what I want so I'm going to look into that.  And I don't like the old dockbar look you get from the _styled theme so I'm going to pull in the classic dockbar.  Finally the nav bar is not sticking at the top of the page when I scroll, so I'll have to flush out the javascript to flip the classes and keep it in place.

Who knows, maybe one or more of these will make it into a future blog post...  wink

ブログ
Good article, David. Additionally, I would take a look at the brand new Manzanita theme here: https://www.liferay.com/marketplace/-/mp/application/52212526, which has a lot of features and was made by an awesome theme developer.
Will definitely check it out Juan. I'm not a theme guy so sometimes diving into a perfect theme just leads me down the rabbit hole. Hopefully there's enough here to help others avoid the rabbit hole with some basics and then fall back to Manzanita for actual implementation details ;-)
Thanks David for the post, very complete! I also like the Manzanita theme as well. As an FYI comment, I recently found this in a google search http://psd2liferay.com/ Looks like another out of the box solution for custom themes. Hope this contributes in a way!

Dears

I was trying to have this nice scrolling since 2015 and it always come to hard. Finally it works in the right way. To have your Parallax Scrolling working and scrolling follow the fowllosing steps:

1. Download Manzanita theme, it is open source, just point your browser to https://web.liferay.com/marketplace/-/mp/application/52212526

2. Download the zipped file Java script  from https://github.com/pixelcog/parallax.js/archive/v1.3.1.zip

THANKS to [http://pixelcog.github.io/parallax.js/]

3. Create a portlet using Liferay studio and copy and paste the html codes from the downoaded zip folder. Also copy the css, img, and js, folders to your template. Do not forget to add <%=request.getContextPath()%> when you need to reference the css, img, and js folders.

4. create a site and/or page

5. deploy or export the war file to Liferay portal

6. Make the theme Manzanita Theme.

It works and you need to change the images and section with the desired one.