Fun with Generic Content Templates

I came across the idea of a generic template recently, and put it to good use.  If you don't know what I mean by generic template, let me clear that up right away.
 
A generic template is really just a content template that is not tied to a structure. The point of it is that you can sparate your template code as you see fit, including the generic templates in your main one. All you need to do is add this line of (velocity markup) code in your template.
#parse ("$templatesPath/12345")
where 12345 is the template key of your generic template. That's it. All the code in your generic template gets pulled into your main template and treated as one.
 
There! You know what I mean by generic templates now. So, let's talk about the fun I had with them. I've come to be used to velocity, so the sample code below is all vm.
 
Here's my main template.
<h3>$txtPoemTitle.getData()</h3>

<div>
$htmlVerse.getData()
</div>

<div>
$htmlAbout.getData()
</div>
 
At a glance, you can tell I am displaying three fields:
  • a title
  • a poem (rich text)
  • a few comments about the poem (rich text)

 

Contrived requirement #1: Style it

After one minute of frenzied googling, I have this:
 
  
<style>
.poem-body {
    float: left;
    font-size:16px;
    color: #989898;
    background-color: #B7E2F0;
    border: solid 1px #B7E2F0;
    border-radius: 5px/5px;
    -webkit-box-shadow:0 23px 17px 0 #B7E2F0;
    -moz-box-shadow:0 23px 17px 0 #B7E2F0;
    box-shadow: 0 23px 17px 0 #B7E2F0;    
}
 
.about-poem {
    float: left;
    margin:15px;
    font-size: 16px;
    font-style:italic;
    background-color: #efefef;
    color: #555555;
}
</style>

<h3>$txtPoemTitle.getData()</h3> <div class="poem-body"> $htmlVerse.getData() </div> <div class="about-poem"> $htmlAbout.getData() </div>

Calm down! Ugly, inefficient, but as I said, contrived. I'm just trying to make a point here.
 
All good. Now, let's move the styling into its own template - a generic template - one without a structure association. Now the main template looks like this:
 
#parse ("$templatesPath/73906")
<h3>$txtPoemTitle.getData()</h3>

<div class="poem-body">
$htmlVerse.getData()
</div>

<div class="about-poem">
$htmlAbout.getData()
</div>
 
73906 is indeed the template key of my generic template, as shown below.
 
 
 

Contrived requirement #2: Create an alternate style for our poem template.

A fiery red sonnet style. It looks very similar to the cool blue verse style , just some different colors.
 
   
<style>
.poem-body {
    float: left;
    font-size:16px;
    color: #ffffff;
    background-color: #CC0033;
    border: solid 1px #CC0033;
    border-radius: 5px/5px;
    -webkit-box-shadow:0 23px 17px 0 #CC0033;
    -moz-box-shadow:0 23px 17px 0 #CC0033;
    box-shadow: 0 23px 17px 0 #CC0033;    
}
 
.about-poem {
    float: left;
    margin:15px;
    font-size: 16px;
    font-style:bold;
    background-color: #efefef;
    color: #555555;
}
</style>
 
Now, I can simply change my generic template include in my main template as below to reference the alternate template.
#parse ("$templatesPath/73945")

<h3>$txtPoemTitle.getData()</h3>

<div class="poem-body">
$htmlVerse.getData()
</div>

<div class="about-poem">
$htmlAbout.getData()
</div>
 

Contrived requirement #3: Let the user pick which style to apply

This is slightly more involved. I modify my poem structure to have, in addition to the original three fields, a select field named Mood with three options, as shown below. Take note of the values of those options.
 
Alright! Now over to my main template to use the value from this field.
#parse ("$templatesPath/$selectMood.getData()")

<h3>$txtPoemTitle.getData()</h3>

<div class="poem-body">
$htmlVerse.getData()
</div>

<div class="about-poem">
$htmlAbout.getData()
</div>
 
And we're done. Here's my content with Mood options. The screenshots that follow show the rendered results.
 
The Content Item:
 
Selecting Cool Blue Verse:
 
Selecting Fiery Red Sonnet:

 

In Conclusion

If you don't see this as useful here, you're probably thinking: why go to all this trouble instead of creating an alternate content template altogether and just use that? Well, let me conclude by highlighting what we accomplished.
  1. Separation of code. We separated the template code between a main template and one or more generic templates. Sure, we just did css in the above example, but these are first clas velcity templates; they could have anything a velocity template can have - css, html, javascript, server-side calls into Liferay's universe of APIs. Power!
  2. Reuse. DRY principle and all. Each generic template is now usable in other main templates.
  3. User-empowerment. By adding a select box to the structure, we've now given the user the ability to switch the generic template that gets used. This makes for some useful indirection. 

Quick FYI on template keys: they are maintained through a LAR export/import, just in case you were wondering. 

 


Happy Fourth, America! To the rest of the world, I hear Jeff Goldblum will be peddling USB drives on an alien mothership once again. If you don't get that reference, consider yourself blessed and e njoy your July anyhow.
Blogs
Hello Javeed.

How does liferay handle the template key during import/export ? Did you try to import/export the content ?

Thanks
Yup. As I mentioned at the end of the article, template keys are maintained through a LAR export/import. Template IDs are specific to instance.