Blogs

Liferay DXP Tutorial: Carousel Template

Liferay DXP ships with a default carousel Application Display Template in global site. But this one is an old fashion AUI one that has been used often before DXP. Since Liferay DXP support Lexicon, I am going to show you how to utilize Lexicon and Bootstrap to create a true mobile responsive carousel in web content. It's remarkably easy with Lexicon and Bootstrap to create responsive UI component in Liferay DXP.
 
Basic requirement:
A carousel with images.
When the screen resolution changes the images are not out of shape.
Change images without work of modifying the code.
No plugin development.
Reusable.
 
 
Analysis:
We can utilize Bootstrap 3(the default bootstrap in Liferay DXP) carousel component to support the basic carousel feature.( https://www.w3schools.com/bootstrap/bootstrap_carousel.asp )
We can utilize Lexicon Image Aspect Ratios to keep the image in shape when screen resolution changes.( http://liferay.github.io/lexicon/content/images-and-thumbnails/#image-aspect-ratios )
 
We can utilize Web Content Structure to save image information with a repeatable field and a Web Content Template to put HTML and CSS as a framework.
No OSGi module plugin development at all. The JSON format structure and FTL format template are easy to migrate.
 
Step 1: Building our web content structure.
 
We can simply create a web content structure with a, aspect ratio field and repeatable image field.
 
Step 2: Create template for the carousel structure
 
We can simply create a template for the newly created carousel structure.
 
 
Step 3: define your image aspect ratio.
As lexicon documented, you can define a custom aspect ratio for your carousel through CSS. For mobile, I just simply hard-code the ratio.
<style>
 #carousel-<@portlet.namespace /> .aspect-ratio-custom {
    padding-bottom: ${aspectRatio.getData()};
 }
@media (max-width: 799px) {
    #carousel-<@portlet.namespace /> .aspect-ratio-custom {
        padding-bottom: 67%;
    }
 }
</style>
 
Step 4: implement by Bootstrap carousel and Lexicon aspect ratio
You can simply apply boot strap HTML and CSS and loop out the image indexed and images. And apply the aspect-ratio and aspect-ratio-custom to the div contains the image.
<#if image.getSiblings()?has_content>

    <section class="carousel-container">

        <div class="carousel slide" data-ride="carousel" id='carousel-<@portlet.namespace />'>

            <ol class="carousel-indicators hidden-sm hidden-xs">

                <#list image.getSiblings() as cur_img>

                   <li class="${(cur_img?counter == 1)?then('active', '')}" data-slide-to="${(cur_img?counter == 1)?then(0, (cur_img?counter - 1))}" data-target='carousel-<@portlet.namespace />'></li>

                </#list>

            </ol>


            <div class="carousel-inner" role="listbox">

                <#list image.getSiblings() as cur_innerImage>

                    <div class="${(cur_innerImage?counter == 1)?then('active', '')} item">

                        <div class="aspect-ratio aspect-ratio-custom aspect-ratio-middle">

                            <img alt="${cur_innerImage.getAttribute("alt")}" src="${cur_innerImage.getData()}">

                        </div>

                    </div>

                </#list>

            </div>


            <a class="left carousel-control" href='#carousel-<@portlet.namespace />' role="button" data-slide="prev">

                <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>


                <span class="sr-only">Previous</span>

            </a>


            <a class="right carousel-control" href='#carousel-<@portlet.namespace />' role="button" data-slide="next">

                <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>


                <span class="sr-only">Next</span>

            </a>

        </div>

    </section>

</#if>
Step 5: add you content
You can upload some images to your Document and Media Folder.
Then add a web content article based on Carousel structure and template.
For the Aspect Ratio, I put 26%(width/height)
 
You can also utilize Liferay DXP's embedded image editor to edit your image and apply filters.
 
Step 6 Publish and Preview
Publish the web content and display it on the page using Web Content Display portlet.
 
You can change your screen size check if the aspect ratio works.
You can use the Simulation tool to preview if the responsive selector works. Right now the ratio is 67% as I set it in the template.
 

For the structure and template, you can visit the following link to download: http://samples.liferayee.com/tree/master/sample-templates/web-content/carousel

I cannot find the Aspect Ratio Field. Can you please guide where it is located?
Actually the Aspect Ratio Field is just a text field.
Can you help me with one more thing? If I need to link an image with a blog post or news article in Liferay. How can I do that?
Then you can add the link in the structure and html in template accordingly.
Actualy there is a little bug in your template. In data-target you forgot a # ;)

wrong:
<li class="${(cur_img?counter == 1)?then('active', '')}" data-slide-to="${(cur_img?counter == 1)?then(0, (cur_img?counter - 1))}" data-target='carousel-<@portlet.namespace />'></li>

right: <li class="${(cur_img?counter == 1)?then('active', '')}" data-slide-to="${(cur_img?counter == 1)?then(0, (cur_img?counter - 1))}" data-target='#carousel-<@portlet.namespace />'></li>
In my case I used "${.vars['reserved-article-id'].data}" instead of "<@portlet.namespace />"

You can find the structure in the Javascript field. Template is in the css and html field.
<script async src="//jsfiddle.net/rhg7o359/embed/"></script>
You can find the structure in the Javascript field. Template is in the css and html field.

https://jsfiddle.net/rhg7o359/
Hi Christian, Thanks for pointing that out!
I think using ${.vars['reserved-article-id'].data} may cause duplicated id if you add 2 web-content-display portlet to the same page with the same web content. Uisng portlet namespace can gurantee the id is unique in the page.
For the name space, you can use <@portlet.namespace /> or ${request.get("portlet-namespace")} or ${request["portlet-namespace"]} depends on what version of Liferay you are using.

Hello,

I am using Liferay version 7.1.1 CE GA2 and none of these alternatives to get namespace work for me.

There is any other way to do this? So that I can have two carousels in the same page....

Thank you.

Hello, I used the carousel code in Liferay 7, and it worked properly.

Then, I used it in Liferay 7.1, then, the carousel was not seen. Rather, all images selected in the webcontent, appeared like a vertical list. At the end of last image, two images were seen "<>" (coming from glyphicon).

Please suggest how to make the code compatible with Liferay 7.1; and the points to be kept while writing structure & template for the new version.

Hello All, Following up on my previous post, I got following document sharing about creating carousel in Liferay 7.1:

 https://dev.liferay.com/de/discover/portal/-/knowledge_base/7-1/adt-example

 

The carousel works properly, however, I am unable to add anchor tag, aspect ratio to the images in carousel. Thus, please help to add such properties to the images in carousel.

For those who has problem running this code in 7.1, I found the missing bit.

The class "item" needs to be changed to "carousel-item".

Hello Jason,

 

Thank you for sharing the change in class name for carousel. The new class "carousel-item" works properly.

 

When we use above structure-template for multiple webcontents on same page, it causes issue due to same id.

Thus, we need to create multiple templates and then use unique ids in each.

Can you suggest a better method to resolve the issue and help to create new ids dynamically?

Hi,

After adding this the slide show is working but still those arrows are coming down .Also please suggest how can we change the color of the arrow and add background color as a box to it.And how can we add text on the image.Thanks