CREATE DYNAMIC WEB PAGES USING SCROLL VIEWPORT

We are very excited to launch a new website based on the Atlassian Confluence platform and Marketplace Apps. Since we are Atlassian Platinum Solution Partner, using Confluence was a no brainer. This is a platform we use day in and day out to collaborate on our Consulting activities and our Marketplace apps, as well as deploy Confluence and its integrations to our clients.

How did we do this?

We used Scroll Viewport to build our Mumo website so that it could be maintained easily through Confluence, without having to update the underlying HTML whenever we add new products and services. It provides a nice separation between our data and how it's displayed, mimicking principles from the MVC design pattern. Scroll Viewport allows us to display Confluence page content in custom built templates using Velocity templates. 

To get data from a Confluence page, Scroll Viewport provides Placeholders which can represent a number of components, including a page, attachment, comment, or page property. For instance, including the title and body of a page in the Velocity template would look like this…

<div class="main-container">
    <h2 class="page-title">$page.title</h2>
    $page.renderContent()
</div>

Here you can see we’re accessing the title and content from a Confluence page and rendering an HTML page from a Velocity template using that data. This gives us the power to display our page content however we like on a web page we’ve designed.

The real power of Scroll Viewport, however, is in using page properties and the page hierarchy to create a dynamic web UI that can be altered and extended from Confluence without making any changes to the templates. As an example, look how we’ve displayed our list of services on our Services page. Here’s one example of how a service is displayed…

Rather than hardcoding this list of services in the HTML, how can we use Viewport to update these services from Confluence? First, we need a Confluence page for each service. We’ll define the same Confluence page properties in each of those pages. We need each page to provide the service name, description, and a logo. The service name can just be the page title, so we only need two properties…

In our Velocity template, we’re going to have to iterate over a list containing references to each of the service pages. How do we represent a list in Confluence? We could create a page property with a comma separated list of the services and then parse the list, but this adds more work than is necessary when the list needs updated. Instead, we’re going to put our services beneath a parent page named Services.


The list of services can be derived from this page tree. How the pages are ordered in the hierarchy determines the order they’ll be displayed on the web page. How do we access the list of services in the Velocity template?

We already have access to the $page variable, which is the Page Placeholder for the Confluence page we’re currently rendering through Scroll Viewport. In this case, we’re rendering the Services parent page mentioned earlier.

#set($services = $page.children)

Here we’re setting a variable equal to the children of the Services page. This creates an array containing the Placeholder objects of the service pages. Now we can iterate over them and decide how to display the contents.

<div class="services-container">
    #foreach($service in $services)
        #set($serviceTitle = $service.title)
        #set($serviceProperties = $service.properties)
        #set($iconImgSrc = $serviceProperties.icon.asImgSrc)
        #set($description = $serviceProperties.description.asHtml)
        #set($anchorTag = $service.title.replace(" ", "-").toLowerCase())
        <div class="service" id="${anchorTag}">
            <div class="service-logo">
                <img src="${iconImgSrc}" alt="${serviceTitle}">
            </div>
            <h2>$serviceTitle</h2>
            <div class="service-description">
                $serviceProperties.description.asHtml
            </div>     
        </div>
    #end
</div>

A lot is happening here. We’re using Velocity to iterate the list of services. For each service, we’re fetching the service name from the page title, and the page properties. The page properties give us the logo and service description, as we saw earlier. Then we’re creating a unique anchor tag that we can link to from our list of services on the Home page. You can see how these variables are used in the actual HTML. Notice the description property is fetched using $serviceProperties.description.asHtml. The .asHtml retains the text formatting set in Confluence.

This menu is rendered using the same Services page tree, and the same page properties. The template is similar, but since we’re viewing the home page we need to first “find” the Services page so we can access its page tree.

#set($servicesPage = $find.page("Services"))
#set($servicesUrl = $servicesPage.link)
#set($services = $servicesPage.children)

We also need a link to the Services page, and then just like before we fetch the list of services by setting the children of the Services page to a variable, $services.

<ul class="service-list">
    #foreach($service in $services)
        #set($serviceTitle = $service.title)
        #set($serviceProperties = $service.properties)
        #set($iconImgSrc = $serviceProperties.icon.asImgSrc)
        #set($anchorTag = $service.title.replace(" ", "-").toLowerCase())
        <li>
            <a href="${servicesUrl}#${anchorTag}">
                        <span class="service-logo">
                            <img src="${iconImgSrc}" alt="${serviceTitle}">
                        </span>
                <span class="service-title">$serviceTitle</span>
            </a>
        </li>
    #end
</ul>

Once again we’re generating an anchor tag as the same method as before, this allows us to link from the home page back to the services as they appear on the Services page.

Velocity allows us to re-use the template for creating this menu of services. In addition to the home page, you can find it in the main menu dropdown and on the Services page.

Here we’ve seen the real power of Scroll Viewport. Displaying Confluence pages as web pages using your own templates and stylesheets is one advantage, but if you get creative with the page properties and page tree you can keep all aspects of your site up-to-date from Confluence.



Recent posts