Context Contributor Concept in Liferay 7/DXP

context-contributor


Context Contributor simply provides contextual information to template files like Velocity or Free Marker Template. Templates are widely used in Application Display Template (ADT), Web Content Display Portlet and Liferay Theme. Using Context Contributor we can write piece of code to inject contextual information which can be reused in various template files. In this article we will explain the use of Context Contributor.


Whats exactly Context Contributor?

To make it little simple lets consider that you are developing a liferay theme. So its obvious that you will use either FreeMarker Template(FTL) or Velocity Template(VM). Now you want to display the greeting message (for example Hello John, welcome to our portal) some where in the Theme Level for logged in user with his full name. Similarly for not logged in user you want to display You are not logged in. In liferay 6.2 you might be thinking to  to write your logic in  init.vm /init.ftl file which is very simple. But think that you are developing another Theme where you need the same functionality. You will simply copy & paste the existing logic to the new theme. Using Context Contributor you can overcome this kind of situation. You can write your logic only once and reuse all the time whenever required.

Writing the Sample Context Contributor:

Maven can be used to write the Context Contributor and it has archetype for it. The name of the archetype is com.liferay.project.templates.template.context.contributor. Lets create the sample project using this archetype. Below is the whole command (should be in single Line) which is used to create the project.

 mvn archetype:generate
    -DarchetypeGroupId=com.liferay
    -DarchetypeArtifactId=com.liferay.project.templates.template.context.contributor
    -DgroupId=com.proliferay
    -DartifactId=sample-context-contributor
    -DinteractiveMode=false
    -DclassName=Sample
    -Dauthor=Hamidul

The above command will create the project and we can import the project as maven project in the eclipse. Below is the class file

package com.proliferay.context.contributor;

import com.liferay.portal.kernel.template.TemplateContextContributor;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.WebKeys;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.osgi.service.component.annotations.Component;

/**
 * @author Hamidul
 */
@Component(
    immediate = true,
    property = {"type=" + TemplateContextContributor.TYPE_GLOBAL},
    service = TemplateContextContributor.class
)
public class SampleTemplateContextContributor
    implements TemplateContextContributor {

    @Override
    public void prepare(
        Map<String, Object> contextObjects, HttpServletRequest request) {
        String welcomeMessage = "";
        ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(WebKeys.THEME_DISPLAY);

        if(themeDisplay.isSignedIn()){
            String fullName = themeDisplay.getUser().getFullName();
            welcomeMessage = "Hi "+fullName+", welcome to our portal";
        }else{
            welcomeMessage = "You are not logged in";
        }
        
        contextObjects.put("welcomeMessage",welcomeMessage);
    }

}

Explanation:

1.  We must implement the prepare method of TemplateContextContributor interface

2. We have request object in the prepare method. So retrieving contextual information is easy

3. contextObjects.put(“welcomeMessage”,welcomeMessage). That means welcomeMessage is injected as key in contextObjects which is a map. Later on we can retrieve the key value in any template file.

4. property = {“type=” + TemplateContextContributor.TYPE_GLOBAL} means the context information would be available for the entire portal. It can also be property = {“type=” + TemplateContextContributor.TYPE_THEME} which means that the contextual information is only for the theme level.

5. Give attention to service = TemplateContextContributor.class. For the context contributor project  this is must.

Deploy:

The final artifact of the above project would be an OSGI Module which need to be deployed before testing. For better understanding of the artifact refer the below pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.proliferay</groupId>
    <artifactId>sample-context-contributor</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>com.liferay.portal.kernel</artifactId>
            <version>2.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.service.component.annotations</artifactId>
            <version>1.3.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <archive>
                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-maven-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>default-bnd-process</id>
                        <goals>
                            <goal>bnd-process</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>biz.aQute.bnd</groupId>
                        <artifactId>biz.aQute.bndlib</artifactId>
                        <version>3.2.0</version>
                    </dependency>
                    <dependency>
                        <groupId>com.liferay</groupId>
                        <artifactId>com.liferay.ant.bnd</artifactId>
                        <version>2.0.32</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

How to retrieve value of welcomeMessage?

Its quite simple.In velocity template(VM) just add $welcomeMessage or in FreeMarker Template (FTL) it should ${welcomeMessage}. 

Download:

sample-context-contributor

 

About The Author

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top
%d