Integrating Clarity's Application with Fragments
Liferay provides a method to merge the power of page fragments with your custom elements, turning standalone applications into modular, configurable page elements. Clarity wants to enable their content creator team to highlight promoted distributor stores. To achieve this, they want to make the distributor locator app’s components configurable through the UI.
In these exercises, you’ll wrap the Distributor Map custom element into a fragment and add configurations to pass data from the page editor to the component.
Exercise: Preparing Clarity’s Custom Element to Use Fragment Configurations
Clarity’s planned fragment contains configuration fields for the Distributor Map custom element. They want to prepare their application to receive and handle this data. Here, you’ll modify the Distributor Map custom element to use fragment configurations.
- In your file explorer, go to the
clarity-distributor-map-custom-element/src/components/folder and open theMap.jsxfile. -
For the
Mapconstant, add a{ promoStore }parameter within the parentheses.The
promoStoreparameter represents the fragment’s configuration field for promoting a distributor store on the map. - Scroll down to the
returnblock and find the<Marker>element. -
Below the
positionattribute, add this:icon={ location?.name === promoStore ? new L.Icon({ iconUrl: "https://maps.gstatic.com/mapfiles/ms2/micons/blue-dot.png", iconSize: [32, 32], iconAnchor: [16, 32], }) : new L.Icon({ iconUrl: "https://maps.gstatic.com/mapfiles/ms2/micons/red-dot.png", iconSize: [32, 32], iconAnchor: [16, 32], }) }This checks the name of the specified promoted store against each distributor’s name. If the store name matches, the marker’s color changes to blue. If not, it remains red.
- Save the file.Now that you’ve updated the component to handle the fragment’s configuration field, you can edit the
App.jsxfile to pass the data to it. - From the parent
src/folder, open theApp.jsxfile. -
For the
Appfunction, add apropsparameter within the parentheses.This parameter saves data from the component’s attributes in an object structure.
-
Within the function, add this:
const promoStoreValue = props.promoStore;This constant stores the value of the
promoStoreattribute within thepropsobject. - Scroll down to the
returnblock. -
For the
<Map />component, add this attribute within the tags:promoStore={promoStoreValue}This passes the
promoStorevalue from the parentAppcomponent to the childMapcomponent. - Save the file. Now, you can add the
promoStoreattribute to theAppcomponent within themain.jsxfile. - From the parent
src/folder, open themain.jsxfile. -
For the
<App />component, add this attribute within the tag:promoStore={this.getAttribute('promoStore')}This attribute stores and passes the root element’s
promoStorevalue into theAppcomponent. -
Add the following import to
main.jsxbelow the existing import section:import leafletCssText from 'leaflet/dist/leaflet.css?inline';This changes the way you embed the CSS.
-
Within the
connectedCallbackfunction, replace everything above the<StrictMode>section with the content from the snippet below to update the styling:connectedCallback() { const style = document.createElement('style'); style.textContent = leafletCssText; const mountPoint = document.createElement('div'); this.appendChild(style); this.appendChild(mountPoint); this.root = createRoot(mountPoint); this.root.render( <StrictMode> <App promoStore={this.getAttribute('promoStore')} /> </StrictMode> ); } - Go to the
client-extensions/clarity-distributor-map-custom-element/folder and open theclient-extension.yamlfile. -
Below the
clarity-distributor-map-custom-elementdefinition, add this:clarity-distributor-map-import-map: name: Clarity Distributor Map Import Map type: jsImportMapsEntry bareSpecifier: clarity-distributor-map-custom-element url: assets/*.jsThis defines a new JS import map client extension to expose the custom element’s resources. Notice that the
urlattribute matches the custom element’surlsvalue to correctly retrieve the necessary resources. - Save the file and deploy the client extension.
Great! You’ve updated the Distributor Map custom element to handle the fragment’s promoStore configuration. Next, you’ll create the fragment and configure that configuration option.
You’ve also made your custom element more versatile so that it can not only be used as a widget but also as a reusable component you can use in fragments and templates by using a JS import map client extension to import the custom element’s resources.
The
jsImportMapsEntry only bundles JavaScript, while customElement client extension types bundle both JavaScript and CSS. As a result when working with JS import maps, you’ll need to implement embedded inline CSS or leverage a globalCSS client extension.Exercise: Creating the Custom Distributor Map Fragment
With Clarity’s Distributor Map custom element configured, they’re ready to use it as a page fragment. Here, you’ll create the Custom Distributor Map fragment and wrap the custom element within it.
- In your Liferay instance, open the Site Menu (
), expand Design, and click Fragments.
- Click the (+) to create a new Fragment Set named
Clarity Distributors. -
Within the fragment set, create a new Basic Fragment called
Custom Distributor Map.Before adding the code, you’ll add configuration options to the fragment.
- Go to the Configuration tab.
-
Within the JSON window, replace the current content with this:
{ "fieldSets": [ { "fields": [ { "dataType": "string", "defaultValue": "", "label": "Promoted Store", "name": "promoStore", "description": "Name of the store that is promoted on the map", "type": "text", "typeOptions": { "placeholder": "Enter the full name of the store" } } ], "label": "Promotions" } ] }This creates a new
Promotionsconfiguration set and an editablePromoted Storeoption. You can now reference this option in the fragment’s code.NOTE
Notice that the configuration can have a default value using thedefaultValuefield. You can define this value directly within the JSON or the custom element’sclient-extension.yamlfile. -
Go to the Code tab and add this code within the HTML window:
<div class="fragment_clarity_map"> <clarity-distributor-map-custom-element promoStore="${configuration.promoStore}"></clarity-distributor-map-custom-element> </div>This creates a
divelement that wraps the Distributor Map custom element, which retrieves thepromoStorefield’s value. However, the fragment doesn’t render anything because it doesn’t include the custom element’s source.To fix this, import the custom element using the previously defined JS Import Map directly in the fragment’s JavaScript window.
This makes the Distributor Map element available to the fragment. It should now display in the preview window.import 'clarity-distributor-map-custom-element'; - Click Publish.
- Navigate to the Distributor Details page and start editing the page.
- Replace the Clarity Distributor Map widget with the Custom Distributor Map fragment.
-
Select the fragment.
Notice there is a new Promotions setting in the configuration side panel. - For the Promoted Store field, enter
Retro Eyewear. - Click Publish to publish the page.
-
Verify the map marker associated with Retro Eyewear is blue.
By default, changes made to a custom fragment’s code are not propagated to deployed instances of the fragment. Whenever you make changes to a fragment, propagation is required to apply those updates to your deployed fragments.
Great! You’ve wrapped the Distributor Map custom element in a configurable fragment and included it in the Distributor Details page. This enables Clarity’s content creators to modify the application without changing the code.
Conclusion
Wrapping custom elements within fragments empowers you to turn applications into modular, configurable page elements. This enables non-technical teams to tailor custom elements and deliver content-rich, dynamic digital experiences without touching any code.
Next, you’ll learn how to leverage the Shadow DOM with Fragments in Liferay.
Capabilities
Product
Education
Knowledge Base
Contact Us