Search Results summary content for custom Liferay Objects records

A generic approach to customizing the content summary for custom Liferay Objects records

Introduction

If you have surfaced custom Liferay Object records in the Search Results Widget you will know that the Title of the Search Result record can be changed (Entry Display > Entry Title Field) but the content summary section of the Search Result record can't:

This shows the Search Document objectEntryContent field value which contains a set of field names (not labels) and the corresponding field values, sorted alphabetically e.g.:

"objectEntryContent":"field1: orange, field2: aaaaaaaaaa, field3: aaaaaaaaa"

This is not very user friendly as you have no control over the set of fields included and showing the field names may not be desirable.

This blog post introduces 2 approaches to customizing the content summary value, both using a custom ModelDocumentContributor to replace the Search Document objectEntryContent field value for example:

"objectEntryContent":"Swine rump ball tip, tri-tip buffalo ham spare ribs tenderloin fatback pork chop venison prosciutto pastrami turkey pancetta. Kevin chuck pig, pastrami kielbasa brisket beef ribs tri-tip boudin tenderloin leberkas swine pork loin turkey."

 

Approach 1 - Basic: Config file driven

  • Approach 1 uses CustomObjectEntryDocumentContributor.java ModelDocumentContributor<ObjectEntry> custom OSGi component.
  • Build and deploy the com.mw.object.search.contributor.basic-1.0.0.jar custom OSGi module.
  • Add the objectEntryContent field to the custom Liferay Object Definitions that you want to customize. See 'Add objectEntryContent field' section.
  • Configure and deploy the OSGi config file based on the package and class name.
  • File name: 
    • com.mw.object.search.contributor.basic.CustomObjectEntryDocumentContributor.config
  • Sample file content (based on the className values of the custom Liferay Objects, available from the Object Definitions headless REST API or from Search > Index Actions > Object Definitions):

indexer.class.name=[ \

 "com.liferay.object.model.ObjectDefinition#ABCD", \

  "com.liferay.object.model.ObjectDefinition#WXYZ", \
]

  • Once the module is deployed and configured the CustomObjectEntryDocumentContributor.java will be associated with the relevant custom Liferay Object Definitions.
  • Populate the objectEntryContent field value on the EXISTING Liferay Object records, which will update the corresponding Search Document objectEntryContent field values.
  • The className value is part of the custom Liferay Object Definition, so the configuration is portable as long as the same Object Definitions are used in production and non-production environments.
  • When a new custom Liferay Object Definition is added then the config file will need to be updated on each server in the cluster if the new custom Liferay Object Definition is to make use of the customization.

Approach 2 - Advanced: Service Tracker based

  • Approach 2 uses CustomObjectEntryDocumentContributor.java ModelDocumentContributor<ObjectEntry> class and CustomObjectModelDocumentContributorTracker.java custom OSGi component.
  • Build and deploy the com.mw.object.search.contributor.tracker-1.0.0.jar custom OSGi module.
  • Add the objectEntryContent field to the custom Liferay Object Definitions that you want to customize. See 'Add objectEntryContent field' section.
  • Once the module is deployed, the service tracker will automatically be associated to each existing and each future custom Liferay Object Definition (where Enable Indexed Search is enabled) with a new CustomObjectEntryDocumentContributor.java service, without any additional configuration or other manual setup required.
    • When a Liferay Object Definition is deleted the associated CustomObjectEntryDocumentContributor.java will also be deleted by the service tracker.
  • Populate the objectEntryContent field value on the EXISTING Liferay Object records, which will update the corresponding Search Document objectEntryContent field values.

Add objectEntryContent field

For each custom Liferay Object Definition that is to make use of the customization, add a field with the following settings to the custom Liferay Object Definition and Save / Publish:

  • Name: objectEntryContent
  • Type: Text
  • Searchable: False
  • Enable Entry Translation: False

The objectEntryContent field can be either:

  • A user editable field populated by the Liferay Objects record creator / updater.
  • Or alternatively the field can be set to be read only and populated with custom 'On After Add' and 'On After Update' actions for example.
    • These can concatenate other field values or use conditional logic to set the objectEntryContent field value as required.

For custom Liferay Object Definitions where you want to continue to use the default behavior, then don't add the objectEntryContent field to that custom Liferay Object Definition.

The maximum length for a Liferay Objects Text field is 280 characters.

The field can be 'hidden' by excluding it from all Views, Layouts and Data Sets etc.

CustomObjectEntryDocumentContributor

  • When a custom Liferay Object record is indexed in the Search indexes, the class will check for the presence of a field called objectEntryContent in the ObjectEntry values map.
    • This will be triggered when the Liferay Object record is created or updated e.g. in the Liferay Object Widget or using the Liferay Object headless APIs etc.
  • If the objectEntryContent field is present and not empty then the value will be used to set the objectEntryContent field on the Search Document.
    • Otherwise it does nothing and the default objectEntryContent logic is used.

Notes

  • A Feature Request to customize the Search Results Widget content summary for custom Liferay Object records exists, but it has been open for over a year, and when it is implemented it won't be backported to earlier Quarterly Release versions. 
  • Both approaches have been tested with a recent 2025.Q1 in Liferay PaaS and self hosted.
  • Since both approaches are OSGi based, neither approach is compatible with Liferay SaaS.
  • An alternative to the approaches contained here exists:
    • A Search Results Widget Template can be used to change the output of the Search Results Widget. This approach can be used in Liferay SaaS, but this requires FreeMarker knowledge and requires complex logic for parsing the values from the Search Document and to handle different output for different custom Liferay Object Definitions.
    • In addition a Global Template Context Contributor can be used (in Liferay PaaS and self hosted) with the Search Results Widget Template to move the complex logic to a Java class, but that code still needs to differentiate between custom Liferay Object Definitions and will only have access to the fields from the Search Document by default.
  • Both approaches will work in a clustered environment as long as the custom module is deployed and configured (if applicable) in all nodes of the cluster.
  • Do not deploy both approaches in the same environment. Use one, or the other, not both.
  • The Search Document objectEntryContent field is not a localization enabled, so this solution is not either.
  • Either approach can be used with existing custom Liferay Object Definitions once the objectEntryContent is populated, as this will re-index the custom Liferay Object records in the Search.
  • The Search Document objectEntryContent field is not a searchable field, so changing the value won't impact the search behavior other than changing the value displayed in the Search Results Widget.
    • In some cases it may be desirable for the objectEntryContent value to display content that isn't indexed in the Search Document at all.
  • To revert a custom Liferay Object Definition to use the default objectEntryContent logic, delete the objectEntryContent field on the custom Liferay Object Definition and re-index that specific custom Liferay Object.
    • For approach 1, removing the className from the config file is recommended but not required.
  • This is a ‘proof of concept’ that is being provided ‘as is’ without any support coverage or warranty.

Conclusion

If surfacing custom Liferay Object records is important to your solution and the default Search Result Widget content summary value is not suitable, then this blog post provides a straightforward generic yet flexible way to change that behavior without affecting the overall Search Results behavior.