Developing Page Fragments Reference

Fragment Specific Tags and Attributes Reference

Along with standard HTML, CSS, and JavaScript, you can use Liferay-specific tags and attributes to define editable elements, embed widgets, and more.

Editable elements use data-lfr-editable-* attributes to define text, images, links, HTML, and other supported types. You can configure these elements before publishing to create reusable fragments with consistent structure and adaptable content.

These Liferay-specific tags and attributes are available:

Warning

Use data-lfr-editable* attributes to define editable elements. Each editable element must include a unique data-lfr-editable-id. Do not change the ID after adding the fragment to a page; doing so causes you to lose changes made to the fragment.

Tip

When you start typing a tag name, the HTML editor provides auto-completion for lfr tags like editable elements and embeddable widgets.

This reference lists the available editable elements and attributes with examples.

Editable Elements

Use editable elements to create dynamic, reusable fragments. Define text, images, links, and HTML as default values, then customize them for each page where the fragment is used. You can display the editable content as-is or use filler content to be replaced before publishing.

Warning

FreeMarker code in editable elements runs only once when you add the fragment to the page (to set its default value).

Avoid using it if you need the value re-evaluated. For example, if you localize a value using ${languageUtil.get(locale,'word')}, the word is localized only when you add the fragment to the page. The code does not run again if the portal language changes.

Editable elements have many uses. Imagine you need a title, a small text box, an image, and a link to provide a product description. Create a fragment containing editable filler text, space for an editable image, the appropriate formatting, and an editable link.

You can then add the fragment to multiple pages and define the image, text, and link for each product you must describe.

You can use editable elements to create a fragment with an editable text, image, and link. This fragment can be edited and reused in different contexts.

Warning

Nesting editable elements inside other editable elements in a fragment is not supported.

Making Text Editable

Use the data-lfr-editable-type="text" attribute to make text elements editable. Each element must have a unique data-lfr-editable-id:

<div data-lfr-editable-id="text1" data-lfr-editable-type="text">
   Placeholder
</div>
Note

All block elements and inline elements are supported for editable text.

The text type removes HTML formatting before rendering, displaying only plain text. If you need formatting options like text or color styles, use the rich-text type, which supports full HTML formatting, including block elements and other rich styles.

<div data-lfr-editable-id="text1" data-lfr-editable-type="rich-text">
   Placeholder
</div>
Note

All block elements are supported for editable rich-text. Use a block element like <div> instead of <p> when adding headings or other block elements, since <p> only supports inline content.

Making Images Editable

Use the data-lfr-editable-type="image" attribute to make images editable. Each element must have a unique data-lfr-editable-id:

<img
   src="placeholder.jpg"
   alt="Placeholder"
   data-lfr-editable-id="img1"
   data-lfr-editable-type="image"
>

After adding the data-lfr-editable-type attribute, you can configure the image’s source and properties from the content page editor sidebar once it’s added to a page.

You have several options for defining an image on a content page.

For editable background images, you must set the data-lfr-background-image-id attribute. This ID is added to the fragment’s main div and must match the editable image ID.

<div data-lfr-background-image-id="background-img-unique-id">
   <h1 data-lfr-editable-id="h1-unique-id" data-lfr-editable-type="text">
      Placeholder
   </h1>
   <p data-lfr-editable-id="p-unique-id" data-lfr-editable-type="text">
      Placeholder
   </p>
</div>

Content mapping connects editable elements with fields from asset types such as web content or blogs. For example, you can map an image field to display a preview image for a web content article. For more information on mapping fields, see Fragment Mapping Settings.

Use the data-lfr-editable-type="link" attribute to make link elements editable. Each element must have a unique data-lfr-editable-id:

<a
   href="#placeholder"
   target="_blank"
   data-lfr-editable-id="link1"
   data-lfr-editable-type="link"
>
   Go to placeholder
</a>

Use mailto: URI scheme to associate the link with an email:

<a
   href="mailto:email@liferay.com"
   target="_blank"
   data-lfr-editable-id="link-to-email"
   data-lfr-editable-type="link"
>
   Send a Message
</a>

Use tel: URI scheme to associate the link with a telephone number:

<a
   href="tel:555-2368"
   target="_blank"
   data-lfr-editable-id="link-to-phone"
   data-lfr-editable-type="link"
>
   Who You Gonna Call?
</a>

You can edit the type of link, target URL, and link mapping from the content page editor sidebar.

You have several options for defining a link's appearance and behavior.

For more information on editable links, see Editable Links.

Creating Editable HTML

Use the data-lfr-editable-type="html" attribute to make HTML elements editable. Each element must have a unique data-lfr-editable-id:

<article data-lfr-editable-id="text1" data-lfr-editable-type="html">
   <h1>Placeholder</h1>
</article>

Including Widgets Within a Fragment

Each widget has a registered name that corresponds to an lfr-widget-[name] tag. Use this tag to embed it in a fragment. For example, the Menu Display widget is registered as nav, so its tag is <lfr-widget-nav />. You can embed it in a block like this:

<div class="nav-widget">
   <lfr-widget-nav>
   </lfr-widget-nav>
</div>

These are the widgets that can be embedded and their accompanying tags:

Widget NameTag
DDL Display<lfr-widget-dynamic-data-list>
Form<lfr-widget-form>
Asset Publisher<lfr-widget-asset-list>
Breadcrumb<lfr-widget-breadcrumb>
Category Filter<lfr-widget-categories-nav>
Flash<lfr-widget-flash>
Media Gallery<lfr-widget-media-gallery>
Menu Display<lfr-widget-nav>
Polls Display<lfr-widget-polls>
Related Assets<lfr-widget-related-assets>
Site Map<lfr-widget-site-map>
Tag Cloud<lfr-widget-tag-cloud>
Tag Filter<lfr-widget-tags-nav>
Web Content Display<lfr-widget-web-content>
RSS Publisher<lfr-widget-rss>
Iframe<lfr-widget-iframe>
Note

Avoid spaces in IDs when embedding widgets in fragments, as they can cause configuration issues and prevent settings from being retained properly.

Using Date Fragments

Use the data-lfr-editable-type="date-time" attribute to define editable date elements. Each element must have a unique data-lfr-editable-id:

<div data-lfr-editable-type="date-time" data-lfr-editable-id="date-time">
   02/03/11 00:00 AM
</div>

Date Formats

You can choose the most common date formats out-of-the-box or customize your date format following SimpleDateFormat.

There are four out-of-the-box options available:

Date FormatHow it looks
MM/DD/YY08/07/23
DD/MM/YY07/08/23
YY/MM/DD23/08/07
DD/MM/YYYY07/08/2023

If you customize your date format, you can include different date and time patterns (e.g. era designator, time zone, and day name in the week).

Here are some examples:

Date FormatHow it looks
MMMM dd, YYYY. hh:mm aAugust 07, 2023. 11:57 AM
MM.dd.YY08.07.23
hh 'o''clock' a, zzzz11 o’clock AM, Greenwich Mean Time
KK:mm a, z11:57 AM, GMT
EEE, d MMM yyyy HH:mm:ss ZMon, 7 Aug 2023 11:57:00 +0000
Tip

You can localize the date format the same way you localize fragment configuration fields.

Making Buttons Action-ready

Trigger object actions by setting an element’s data-lfr-editable-type to "action". Each element must also have a unique data-lfr-editable-id:

<button class="btn btn-${configuration.buttonSize} btn-${configuration.buttonType}" data-lfr-editable-id="action" data-lfr-editable-type="action">
   Go Somewhere
</button>

Enabling Embedding for Your Widget

Liferay DXP/Portal 7.4+ +U60

Note

Embedding widgets to fragments is deprecated as of Liferay DXP 2024.Q4/Portal GA129 and is scheduled for removal in a future release. Instead, add the widget directly to the content page.

If you have a custom widget that you want to embed in a fragment, you can configure that widget to be embeddable. To embed your widget, it must be an OSGi Component. Inside the @Component annotation for the portlet class you want to embed, add this property:

com.liferay.fragment.processor.PortletRegistry

Also, set the @Activate and the @Deactivate life cycle methods to register and unregister an alias for the portlet using the PortletRegistry:

public class MySamplePortlet extends MVCPortlet {

	@Activate
	protected void activate() {
		_portletRegistry.registerAlias(
			_ALIAS,
			MySamplePortletKeys.SAMPLE);
	}

	@Deactivate
	protected void deactivate() {
		_portletRegistry.unregisterAlias(_ALIAS);
	}

	private static final String _ALIAS = "sample";

	@Reference
	private PortletRegistry _portletRegistry;
}

When you deploy your widget, it’s available to add. The name you specify in the property must be appended to the lfr-widget tag like this:

<lfr-widget-app-name>
</lfr-widget-app-name>
Note

According to the W3C HTML standards, custom elements can’t be self-closing. Therefore, even though you can’t add anything between the opening and closing <lfr-widget...> tags, you can’t use the self-closing notation for the tag.

Localizing Fragment Configurations

You can localize fragment configuration for a page’s target language. For example, on a button fragment you can define one button type when the page language is en-US, and a different button type when the page language is es-ES. To localize a fragment configuration field, use the localizable attribute.

Note

The localizable attribute is not available for fields where the configurationRole property is set to style.

In the following code excerpt, the button fragment configuration sets the localizable attribute to true for the fields section under fieldSets. The localizable attribute is set at the field level. In the example, there is only one buttonType field. If you have a fragment with multiple fields, you can set the localizable attribute for each one:

"fieldSets": [
  {
    "fields": [
      {
        "name": "buttonType",
        "label": "type",
        "type": "select",
        "dataType": "string",
        "defaultValue": "primary",
        "localizable": true,
        "typeOptions": {
          "validValues": [
            { "value": "primary" },
            { "value": "secondary" },
            { "value": "link" },
            { "value": "outline-primary" },
            { "value": "outline-secondary" }
          ]
        }
      }
    ]
  }
]

You can use this sample code to change the button type depending on the page’s target language. In the following example, the Contact Us/Contacto button fragment sets the localizable attribute to true for the buttonType field. The example uses this attribute to configure the Primary button type when the page uses the en-US language (A) and the Outline Primary type when the page uses es-ES (B).

Localizable elements in the fragment show the flag icon under the General tab and support different configurations for different languages.

Tip

The flag icon under the fragment’s General settings indicates the configuration field as localizable.

Fragments with the localizable attribute that do not specify a custom configuration for a language use the default page language’s configuration.

Using JavaScript Variables

When adding JavaScript to a fragment, Liferay makes several pre-defined variables available for you to use, making it easier to manage your fragment’s behavior. Here are some of the variables you can use:

  • fragmentElement is the root HTML element that contains your fragment. You can use it to access and manipulate the DOM elements within your fragment.

    const button = fragmentElement.querySelector('.my-button');
    button.addEventListener('click', () => {
       console.log('Button clicked!');
    });
    
  • configuration is an object containing the fragment’s configuration options. If the fragment has configurable fields (like colors, text, or URLs), their values are stored here.

    const textColor = configuration.textColor;
    fragmentElement.style.color = textColor;
    
  • fragmentEntryLinkNamespace is a unique string that can be used to identify the fragment within the page, even if there are multiple instances of the same fragment. It’s useful when you must create unique IDs or scopes in your JavaScript.

    const uniqueId = `${fragmentEntryLinkNamespace}-button`;
    const button = document.createElement('button');
    button.id = uniqueId;
    fragmentElement.appendChild(button);
    
    Note

    fragmentEntryLinkNamespace was called fragmentNamespace, but fragmentNamespace has been deprecated. It’s still available for compatibility, but you should use fragmentEntryLinkNamespace in new code.

  • layoutMode indicates whether the fragment is being edited or viewed. You can adjust the fragment’s behavior based on whether the page is in edit mode (layoutMode === "edit") or being viewed live (layoutMode === "view").

    if (layoutMode === 'edit') {
       console.log('Page is in edit mode');
    } else {
       console.log('Page is being viewed');
    }