Site Initializers: Update Support

How to enable "update" support for Site Initializers

Introduction

Several months ago I wrote an article about Site Initializers (read if you missed it šŸ˜‰). It describes how to setup content using Bundle Site Initializer. And it also highlights (in article itself and in comments) that the main issue with Site Initializers was missing "update" support: if any changes to content required - site should be re-created from the initializer each time. We used Site Initializer on a project with lots of content: things were simplified a bit due to the same content in each environment, but site re-creation process was really annoying.

I've been searching for a solution for a while, submitted a ticket on Liferay Issues, and even started an own implementation (including update support with different strategies, additional content types and custom extensions points).  

But recently I've found that update support is already there in Liferay! (Perhaps, Liferay Team was inspired by my blog and Jira requests - feature was implemented 2 months after my submissions šŸ˜Š) This feature is not enabled by default, but can be easily switched on.

How to enable update support

Update Support for Site Initializers was implemented in scope of LPS-165482, but it's still hidden under Feature Flags. This feature can be enabled in the following ways:

1. Using portal properties

Add the following property to portal-ext.properties:

feature.flag.LPS-165482=true

and restart server.

2. Using UI (starting from 7.4 GA 69)

Navigate to Control Panel ā†’ Instance Settings ā†’Platform ā†’ Feature Flags:

 

and enable LPS-165482 feature under Developer tab:

 

How does it work

If feature flag is enabled - an additional property siteInitializerKey is save to site group's typeSettings (see BundleSiteInitializer#_updateGroupSiteInitializerKey). This links the created site with its initializer. If there are any changes in initializers's code - changes can be synced using SiteInitializerPortlet, which is rendered as a panel app under Publishing category (only if feature flag is enabled and site initializer matching siteInitializerKey is registered, see SiteInitializerPanelApp#isShow).  

Example in Action

As an example - let's create a custom bundle based on Masterclass initializer.

bnd.bnd

Bundle-Name: Liferay Site Initializer Masterclass Demo
Bundle-SymbolicName: com.liferay.site.initializer.masterclass.demo
Bundle-Version: 1.0.0
Liferay-Site-Initializer-Name: Masterclass Demo
Provide-Capability: liferay.site.initializer
Web-ContextPath: /site-initializer-masterclass-demo

Resources for site initialization can be copied from the original "Masterclass" initializer (I included only one layout to simplify the deployment). 

Deploy module and create a new site from the deployed initializer:

The following site should be created:

Now let's modify the content definition in the initializer's module - for example, define custom editable values for the fragment fields on the home page:


and re-deploy the initializer module.

Then navigate to the Site Initializer item under Publication menu, and click the Synchronize button:

Once synchronized - changes should be available on the site: 

 

____________________________________________________________________________________

Update: Mar 20 2024 

 

1. Current Feature Status

As of the latest Liferay release (2024-q1) - Update Support for Site Initializers it still under a feature flag and can be enabled in a way described above.

Also, it can be enabled using portal property:

feature.flag.LPS-165482=true

or using the following environment variable:

LIFERAY_FEATURE_PERIOD_FLAG_PERIOD__UPPERCASEL__UPPERCASEP__UPPERCASES__MINUS__NUMBER1__NUMBER6__NUMBER5__NUMBER4__NUMBER8__NUMBER2_

 

2. Update Support for Guest Site

Sometimes instead of new site creation you need to modify the default Guest site. If you want to use Site Initializer for Guest site - you need to associate it with your initializer instance using siteInitializerKey property. This property needs to be defined in SI descripror, and stored in Group_.typeSettings for the Guest site. The best way to save siteInitializerKey value for a site is to create an UpgradeStep that saves this property, sample:

public class SiteInitializerUpgradeStep extends UpgradeProcess {

    private static final String GUEST_GROUP_FRIENDLY_URL = "/guest";
    private static final String PROPERTY_NAME = "siteInitializerKey";
    private static final String SMS_SITE_INITIALIZER_KEY = "com.xxx.my-site-initializer";

    private final long companyId;
    private final GroupLocalService groupLocalService;

    public SiteInitializerUpgradeStep(long companyId, GroupLocalService groupLocalService) {
        this.companyId = companyId;
        this.groupLocalService = groupLocalService;
    }

    @Override
    protected void doUpgrade() throws Exception {
        Group guestGroup = groupLocalService.fetchFriendlyURLGroup(companyId, GUEST_GROUP_FRIENDLY_URL);
        if (Validator.isNotNull(guestGroup)) {
            UnicodeProperties typeSettingsUnicodeProperties = guestGroup.getTypeSettingsProperties();
            typeSettingsUnicodeProperties.setProperty(PROPERTY_NAME, SMS_SITE_INITIALIZER_KEY);
            groupLocalService.updateGroup(guestGroup.getGroupId(), typeSettingsUnicodeProperties.toString());
        }
    }
}

Once  you register the UpgradeStep and deploy the module - Guest site's typeSettings will be updated, so that the site will be "linked" with appropriate site initializier instance.

If you have the upgrade support enabled already - you'll see the "Site Initializer" menu item under "Publishing" menu for Guest site.

Clicking "Synchronize" should update the content of Guest site in accordance with descriptors defined in your Site Initializer module.

____________________________________________________________________________________

 

Leave your comments and feedback.

Stand with Ukraine 

Enjoy šŸ˜‰

 

Vitaliy Koshelenko

Liferay Architect at Aimprosoft

v.koshelenko@aimprosoft.com

Blogs

With a site-initializer, is it possible to synchronize the default 'Guest' site?

By default - no, site should have a "siteInitializerKey" property in typeSettings. 

But if we deploy a site initializer module, and update site's typeSettings (e.g. with an Upgrade Process or via Groovy scripting console) - should be possible, I guess.