Liferay Fragment Collection Contributor

 Liferay Fragment Collection Contributor


Overview

Liferay Fragment Collection Contributor is another way for deploying fragments. This approach has its own pros and cons, which will be reviewed later in this article, but should be considered as an option.


Module structure

Liferay module for a custom fragment collection contributor should have the following structure:


Module files


bnd.bnd:


Bundle-Name: LifeDev Fragment Collection Contributor

Bundle-SymbolicName: com.lifedev.fragment.collection.contributor

Bundle-Version: 1.0.0

Web-ContextPath: /fragment-collection-contributor-lifedev

-dsannotations-options: inherit


As a Bundle-Name we specify a human-readable name of our module, e.g. “LifeDev Fragment Collection Contributor”.


Bundle-SymbolicName is typically a fully-qualified package name, e.g. com.lifedev.fragment.collection.contributor.


Bundle-Version is 1.0.0 initially, but can be increased when a new version is released.


We also need to specify a web content path with Web-ContextPath property. It should start with “/fragment-collection-contributor” prefix, e.g. “/fragment-collection-contributor-lifedev”.


Finally, we need to specify the -dsannotations-options property as “inherit” to enable support of annotated service references in child classes, as we’ll inherit from a class with OSGi references.


build.gradle:


dependencies {

  compileOnly group: "com.liferay.portal", name: "release.portal.api"

  cssBuilder group: "com.liferay", name: "com.liferay.css.builder", version: "3.0.2"

}


Here we just need to specify the liferay portal dependency and a cssBuilder plugin - to be able to implement CSS code as SCSS.


LifeDevFragmentCollectionContributor.java 


@Component(

       property = "fragment.collection.key=lifedev",

       service = FragmentCollectionContributor.class

)

public class LifeDevFragmentCollectionContributor extends BaseFragmentCollectionContributor {


   @Override

   public String getFragmentCollectionKey() {

       return "lifedev";

   }


   @Override

   public ServletContext getServletContext() {

       return _servletContext;

   }


   @Reference(target = "(osgi.web.symbolicname=com.lifedev.fragment.collection.contributor)")

   private ServletContext _servletContext;


}


We need to implement a custom class, which extends the com.liferay.fragment.contributor.BaseFragmentCollectionContributor, define it as a component, specify service as FragmentCollectionContributor and define the fragment.collection.key property. Also, we need to implement getFragmentCollectionKey and getServletContext methods. Bundle-SymbolicName value from bnd.bnd should be specified as osgi.web.symbolicname property for ServletContext @Reference.


collection.json


{

  "name": "LifeDev Fragments"

}


Here we just specify the name of the fragments collection.

This file, as well as folders for fragments, should be located on {package-name}/dependencies path, where {package-name} is a  Bundle-SymbolicName value from bnd.bnd.


Fragment Files


For each fragment to be deployed with a collection contributor a separate folder should be created on the same level as the collection.json file.


fragment.json


{

 "fragmentEntryKey": "lifedev-block",

 "name": "LifeDev Block",

 "type": "component",

 "htmlPath": "index.ftl"

}


In this file we define fragment name and key, type and path to html file (index.ftl in our case).


index.ftl


<div class="lifedev-block">

  <h1 data-lfr-editable-id="lifedev-header" data-lfr-editable-type="text">

     LifeDev Header

  </h1>

  <p data-lfr-editable-id="lifedev-text" data-lfr-editable-type="rich-text">

     Lorem ipsum dolor sit amet…  </p>

</div>


Here we define the fragment’s HTML. FTL extension is used to enable freemarker syntax.


index.js


Here we can define JavaScript code for our fragment.


index.json


{

 "fieldSets": [

 ]

}


Here we can define the fragment's configuration


index.scss


.lifedev-block {

  h1 {

     margin-bottom: 1rem;

  }

  p {

     text-align: justify;

  }

}


Here we can define CSS for our fragment. We can use SCSS syntax with the help of cssBuilder Gradle plugin.

 

Deployment and Results


Once we deploy our fragment collection contributor module - we should see a new collection among “Default” ones:

Fragments from the collection are available now to be used on content pages.


Pros and Cons


Pros

  • Easy way to deploy fragments;

  • Fragment’s code is stored in project/Git;

  • No need to propagate changes for fragments on pages.


Cons

  • No possibility to edit fragments on the portal.


With this, fragment collection contributors can be a good choice for “fundamental” fragments, which are not supposed to be changed after they are developed, as this approach requires redeployment for any changes in fragment’s code. If you need fragments to be more dynamic, and editable by content editors directly on the portal - you can consider other options, such as Liferay Fragments Toolkit


Enjoy 😏




Comments

Popular posts from this blog

Liferay Search Container Example

Liferay DXP - max upload file size

Liferay Keycloak integration