Home/Knowledge Hub/Frontend & presentation
Frontend & presentation
Widget Templates in Liferay 7.4
Application Display Templates, FreeMarker, presentation, reuse, security and best practices
Introduction
A Liferay widget generally contains two broad concerns:
- Business/data logic
- Presentation logic
For example, an Asset Publisher may retrieve a collection of assets and render them using its default presentation. Conceptually:
Widget
|
+--> Retrieve Data
|
+--> Default RenderingSometimes the data retrieval is correct, but the presentation must change. For example, instead of:
Title
Description
Title
Description
Title
Descriptionwe may want:
+------------+ +------------+ +------------+
| Image | | Image | | Image |
| Title | | Title | | Title |
| Button | | Button | | Button |
+------------+ +------------+ +------------+A Widget Template provides this presentation customization.
Application Display Templates
Widget Templates are closely related to what Liferay traditionally called:
The fundamental idea is:
Therefore, the same widget data can have multiple visual representations.
Why Use Widget Templates?
Widget Templates are useful when:
- Default widget rendering is not suitable
- A list should become cards
- Additional HTML structure is needed
- Business data should remain unchanged
- The same display should be reusable
- A developer wants to avoid modifying Liferay core JSPs
The design principle is:
Simple Architecture
Without a custom template:
Database
|
v
Liferay Service
|
v
Widget
|
v
Default DisplayWith a Widget Template:
Database
|
v
Liferay Service
|
v
Widget
|
v
Widget Template
|
v
Custom HTMLThe Widget Template operates mainly at the presentation layer.
Presentation Separation
Conceptually:
Then:
The same data:
can therefore be rendered by:
without changing the underlying data.
Example
Suppose an Asset Publisher returns three news articles. The default presentation may be:
Quantum Computing Workshop
New Quantum Research Published
Photonics Laboratory OpensA Widget Template could instead produce:
+-----------------------+ |
|---|
| Image | |
| Quantum Computing | |
| Workshop | |
| [Read More] | |
+-----------------------+ |
+-----------------------+ |
| Image | |
| New Quantum Research | |
| Published | |
| [Read More] | |
+-----------------------+The content has not changed. Only its presentation has changed.
Where Widget Templates are Managed
Depending on the Liferay 7.4 release and site configuration, Widget Templates can be managed through the site administration interfaces associated with design/templates. The typical workflow is:
Site Administration
|
v
Design / Templates
|
v
Widget Templates
|
v
Create TemplateCreating a Widget Template
The general process is:
- Open the appropriate Site Administration area.
- Navigate to Widget Templates.
- Click Add.
- Select the widget/application for which the template is being created.
- Enter a template name.
- Write the template logic.
- Save the template.
- Add/configure the target widget on a page.
- Select the new Widget Template from the widget’s display configuration where supported.
Template Language
FreeMarker is the primary templating language used for many modern Liferay templates. FreeMarker uses syntax such as:
${variable}for values. Conditions use:
<#if condition>
...
</#if>Loops use:
<#list entries as entry>
...
</#list>Basic FreeMarker Example
Consider:
<h2>My Widget Template</h2>
<#if entries?has_content>
<ul>
<#list entries as entry>
<li>
${entry}
</li>
</#list>
</ul>
</#if>The exact objects available in the template depend on the widget.
Template Context
A Widget Template executes with a template context. Conceptually:
The exact variables depend on the application. For example, a collection-oriented widget might expose something conceptually similar to:
entriesThe template then iterates through those entries.
Using Variables
Basic FreeMarker output:
${title}Another example:
<h2>${title}</h2>A variable should be checked where it may be absent. For example:
<#if title??>
<h2>${title}</h2>
</#if>The operator:
??checks whether a value exists.
Default Values
FreeMarker can provide a fallback value. Conceptually:
${title!"Untitled"}If:
then:
Untitledis displayed. This improves template robustness.
Conditional Rendering
Example:
<#if entries?has_content>
<p>Entries are available.</p>
<#else>
<p>No entries found.</p>
</#if>This prevents blank or confusing output.
Looping Through Entries
A common Widget Template operation is:
<#list entries as entry>
<div class="item">
${entry}
</div>
</#list>Conceptually:
and the template performs:
Card-Based Example
Suppose a widget exposes a list of items. A card-style template might conceptually be:
<div class="row">
<#list entries as entry>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h3>
${entry}
</h3>
</div>
</div>
</div>
</#list>
</div>This demonstrates the primary purpose:
Using Clay/Bootstrap Classes
Liferay’s frontend uses Clay and Bootstrap-oriented styling conventions.
A template can use available classes such as:
<div class="container">
<div class="row">
<div class="col-md-6">
Content
</div>
</div>
</div>This helps custom output visually integrate with the surrounding Liferay UI.
Example: Grid Layout
<div class="row">
<#if entries?has_content>
<#list entries as entry>
<div class="col-lg-4 col-md-6 mb-4">
<div class="card h-100">
<div class="card-body">
<h4 class="card-title">
${entry}
</h4>
</div>
</div>
</div>
</#list>
</#if>
</div>Widget Configuration
After creating a template, the relevant widget normally needs to be configured to use it. Conceptually:
Page
|
vWidget
|
v
Configuration
|
v
Display / Template
|
v
Custom Widget TemplateThis allows the same widget to use different templates in different contexts.
Reusable Presentation
Suppose a template called:
Corporate Card Layoutis created. It can potentially be reused by multiple instances of the supported widget. Thus:
This improves consistency.
Widget Templates and Asset Publisher
Asset Publisher is a classic use case for display templates. Conceptually:
Asset Publisher
|
+--> Web Content
+--> Documents
+--> Blogs
+--> Other Assets
|
v
Widget Template
|
v
Custom DisplayFor example, assets could be rendered as:
- News cards
- Image gallery
- Featured content
- Compact list
- Timeline
Widget Templates and Asset Lists
A collection-oriented widget can provide data while the template controls how that data appears. This separation can be expressed as:
The widget selects entries. The template renders entries.
Localization
A production template should consider multilingual portals. Instead of hard-coding:
Read Morea localized value should be used where the template context and supported APIs provide localization helpers. Conceptually:
For example:
English -> Read More
French -> Lire la suite
Hindi -> Aur padhenEscaping Output
Output security is important whenever dynamic values are rendered. Conceptually:
rather than:
because unsafe output can contribute to cross-site scripting (XSS) risks.
FreeMarker Restrictions
A template environment should not be viewed as unrestricted Java execution. For security reasons, Liferay controls what can be accessed from templates. A template should primarily perform:
- Presentation
- Formatting
- Simple conditions
- Iteration
It should not become a replacement for the application’s service layer.
Bad Template Design
A poor design is:
Widget Template
|
+--> Complex Database Logic
|
+--> Remote API Calls
|
+--> Business Transactions
|
+--> Complex Permission LogicA better design is:
Service / Widget
|
v
Prepared Data
|
v
Widget Template
|
v
PresentationThus:
Avoid Heavy Processing
Suppose a template renders:
entries. If each iteration performs an expensive operation of cost:
the total cost becomes approximately:
If:
then:
or approximately:
before considering other processing. Therefore, expensive service calls inside loops should be avoided.
N+1 Problem
Consider:
<#list entries as entry>
getAdditionalData(entry)
</#list>If each item causes a database or service call:
then:
operations are performed. For:
this becomes:
operations. Prepare data efficiently before rendering wherever possible.
Template Error Handling
A template can fail if it assumes a value always exists. For example:
${entry.title}may fail or behave unexpectedly if the expected value is unavailable. Safer logic can include:
<#if entry.title??>
${entry.title}
</#if>or an appropriate fallback.
Inspecting Available Variables
When developing a template, determine which variables the selected widget exposes. Conceptually:
Widget
|
+--> Template Context
|
+--> entries
+--> request
+--> themeDisplay
+--> helper objects
+--> application-specific valuesThe exact set varies by widget and Liferay version. Use the editor’s available variable/reference information and official documentation instead of guessing object methods.
themeDisplay
In supported template contexts, themeDisplay provides information related to the current portal request. Conceptually it can provide access to contextual information such as:
- Current user
- Company
- Site/group
- Locale
- Portal URL context
Example concept:
<#if themeDisplay??>
Current Site Context Available
</#if>The actual accessible methods depend on the template environment.
URLs in Templates
A template often needs links. For example:
<a href="${viewURL}">
Read More
</a>The URL should normally come from the widget/template context rather than being hard-coded. Bad:
<a href="/web/guest/news?id=123">Better:
<a href="${viewURL}">This improves portability.
Avoid Hard-Coded Site URLs
Hard-coded URLs can break when:
- Site friendly URL changes
- Virtual host changes
- Environment changes
- Portal context changes
- Application moves between development and production
Therefore:
Custom Widget Support
Developers can also design custom Liferay applications to support Application Display Templates / Widget Templates where the relevant Liferay extension APIs are used. Conceptually:
Custom Portlet
|
+--> Provides Data
|
+--> Registers Template Support
|
v
Widget Template
|
v
Custom PresentationThis provides administrators with presentation flexibility without requiring a new application deployment for every visual variation.
Custom Portlet Architecture
Suppose a custom application displays quantum assessments. Without templates:
Quantum Assessment Portlet
|
v
Fixed JSPWith template support:
Quantum Assessment Portlet
|
v
Assessment Entries
|
+----------------+
| |
v v
Card Template Table Template
| |
v v
Card UI Table UIThe same data can therefore support multiple presentations.
Example Quantum Assessment Template
Conceptually:
<div class="row">
<#if entries?has_content>
<#list entries as assessment>
<div class="col-md-4 mb-3">
<div class="card h-100">
<div class="card-body">
<h3>
${assessment}
</h3>
<p>
Quantum assessment
</p>
<button
class="btn btn-primary">
Start Assessment
</button>
</div>
</div>
</div>
</#list>
</#if></div>The exact assessment properties depend on the custom widget’s template context.
Widget Templates vs Fragments
Widget Templates and Fragments solve different problems.
| Characteristic | Widget Template | Fragment |
|---|---|---|
| Primary purpose | Render widget data | Build page components |
| Data source | Widget/application | Fragment context/configura- |
| Typical language | FreeMarker | tion HTML/CSS/JavaScript/FreeMarker features |
| Relationship to widget | Strong | Usually independent |
| Use case | Alternative widget display | Page composition |
| Example | Asset cards | Hero banner |
Widget Template vs Fragment Example
Requirement:
“Display Asset Publisher news entries as cards.”
Use:
Requirement:
“Create a reusable hero section containing heading, image and button.”
Use:
Widget Templates vs Themes
A Theme affects broad site presentation. A Widget Template affects a specific supported widget’s rendering. Conceptually:
while:
Widget Template vs CSS Client Extension
CSS Client Extension:
Widget Template:
For example, if the HTML is already correct but the color must change:
If:
<ul>
<li>...</li>
</ul>must become:
<div class="card">
...
</div>then:
is more appropriate.
Widget Template vs Custom Element
A Widget Template renders data supplied by a Liferay widget. A Custom Element Client Extension is an independently developed frontend application.
| Widget Template | Custom Element | |
|---|---|---|
| Data | Widget-provided | Application-controlled |
| Technology | FreeMarker | React/Vue/Angular/JS |
| Complexity | Lower | Higher |
| Use case | Custom rendering | Full frontend application |
| Runtime | Liferay template rendering | Browser/external frontend |
Decision Guide
A useful decision model is:
Need UI customization?
|
+--> Existing Widget Data?
| |
| +--> Change Rendering?
| |
| +--> Widget Template|
+--> Reusable Page Component?
| |
| +--> Fragment
|
+--> Full React/Vue Application?
| |
| +--> Custom Element CX
|
+--> Styling Only?
|
+--> CSS / Theme CSS CXPermissions
Widget Templates can have permissions governing who can:
- View
- Update
- Delete
- Manage
The exact actions depend on the Liferay version and resource. Templates containing important presentation logic should not be editable by unauthorized users.
Security Considerations
Template authors should consider:
- Cross-site scripting
- Dynamic output escaping
- Unsafe HTML
- Excessive service access
- Sensitive data exposure
- Permissions
- User-generated content
A useful rule is:
Do Not Use Templates to Bypass Permissions
A Widget Template should not be treated as a mechanism for bypassing Liferay permissions. Correct architecture:
User
|
v
Permission Check
|
v
Widget Data
|
v
Template
|
v
Displaynot:
Template
|
v
Retrieve Unauthorized DataPerformance Best Practices
A good Widget Template should:
- Keep logic simple.
- Avoid expensive operations inside loops.
- Avoid unnecessary service calls.
- Check for missing values.
- Avoid excessive nested loops.
- Render only necessary data.
- Use appropriate pagination at the widget/data layer.
- Avoid large amounts of inline JavaScript.
Separation of Responsibilities
A well-designed architecture is:
Service Layer
|
| Retrieves Data
v
Widget |
| Prepares Context
v
Widget Template
|
| Renders
v
HTMLTherefore:
Template Reusability
Suppose three pages use the same visual design:
Page A -> Asset Publisher
Page B -> Asset Publisher
Page C -> Asset PublisherInstead of implementing the card layout three times:
use one shared template:
This improves maintainability.
Development Lifecycle
A practical development process is:
Requirement
|
v
Choose Widget
|
v
Inspect Template Context
|
v
Create Widget Template
|
v
Write FreeMarker
|
v
Test with Real Data |
v
Check Permissions
|
v
Test Empty/Missing Values
|
v
Performance Test
|
v
Publish / UseTesting Checklist
Test:
- Zero entries
- One entry
- Many entries
- Missing optional fields
- Long titles
- Special characters
- Multiple languages
- Guest user
- Authenticated user
- Mobile layout
- Tablet layout
- Desktop layout
Responsive Design
Templates should consider responsive layouts. For example:
<div class="
col-12
col-md-6
col-lg-4
">
...
</div>Conceptually:
Desktop = 3 Cards/Row
Accessibility
Custom templates should preserve accessibility. Consider:
- Semantic HTML
- Heading hierarchy
- Alternative image text
- Keyboard navigation
- Accessible links
- Button labels
- Color contrast
For example:
<img
src="${imageURL}"
alt="${imageAlt}"
/>is preferable to an image with no meaningful alternative text.
Troubleshooting: Template Not Visible
Check:
- Was the correct widget/application selected?
- Was the template saved successfully?
- Does the widget support Widget Templates?
- Is the template available in the current site context?
- Does the user have permission?
Troubleshooting: Invalid Reference
An error such as a missing FreeMarker variable may indicate that the template expects a variable not supplied by the widget. For example:
${articleTitle}when:
Use the actual variables available to the template.
Troubleshooting: Template Works for Some Entries
If some entries render while others fail, check for optional fields. Bad:
${entry.image.url}when some entries have no image. Safer conceptually:
<#if entry.image??>
...
</#if>Troubleshooting: Slow Rendering
Check for:
- Service calls inside loops
- Deep nested loops
- Too many entries
- Large images
- Excessive HTML
- Expensive template operations
If:
reduce either:
or:
Troubleshooting: Layout Looks Different
Check:
- Theme CSS
- Clay/Bootstrap classes
- Custom CSS Client Extensions
- Browser developer tools
- CSS specificity
- Responsive breakpoints
Remember:
Practical Example Architecture
Suppose a portal has:
- Liferay Objects storing Assessments
- A widget retrieving Assessments
- A Widget Template rendering cards
- FastAPI performing quantum calculations
Architecture:
+----------------------+
| Liferay Objects |
| Assessment Data |
+----------+-----------+
|
v
+----------------------+
| Assessment Widget |
+----------+-----------+
|
v
+----------------------+
| Widget Template |
| Card Presentation |
+----------+-----------+
|
v
+----------------------+
| User |
+----------+-----------+
|
| Start
v
+----------------------+
| FastAPI / Quantum |
| Service |
+----------------------+The responsibilities remain clean:
Interview Questions and Answers
Multiple Choice Questions
Question 1
What is the main purpose of a Widget Template?
A. Change database schema
B. Customize widget presentation
C. Configure Elasticsearch
D. Create users
Answer: B
Question 2
Widget Templates were traditionally associated with which term?
A. ADT
B. OSGi
C. JDBC
D. JNDI
Answer: A
Question 3
Which template language is commonly used for Widget Templates?
A. SQL
B. FreeMarker
C. Java bytecode
D. YAML only
Answer: B
Question 4
Which FreeMarker construct performs iteration?
A. #list
B. SELECT
C. forEach() only
D. GROUP BY
Answer: A
Question 5
What should normally remain outside a Widget Template?
A. Presentation
B. HTML markup
C. Complex business logic
D. Conditional display
Answer: C
Question 6
Which is a classic application of Widget Templates?
A. Asset Publisher custom display
B. Database clustering
C. JVM heap tuning
D. DNS configuration
Answer: A
Question 7
Which is more appropriate for a reusable page hero component?
A. Fragment
B. Widget Template
C. Database trigger
D. Search index
Answer: A
Question 8
Which is more appropriate for rendering Asset Publisher entries as cards?
A. Widget Template
B. Database View
C. Cluster Link
D. OAuth Provider
Answer: A
Question 9
Why should service calls inside template loops be minimized?
A. They can create performance problems
B. FreeMarker cannot display HTML
C. They disable CSS
D. They delete entries
Answer: A
Question 10
Which expression conceptually checks whether a FreeMarker variable exists?
A. ??
B. DROP
C. JOIN
D. DELETE
Answer: A
Question 11
Which Client Extension is generally more suitable for a full React application?
A. Custom Element
B. Widget Template
C. Theme Favicon
D. Batch
Answer: A
Question 12
What does the Widget Template primarily receive?
A. Widget/application context and data
B. Database passwords
C. JVM bytecode
D. Search cluster credentials
Answer: A
Question 13
What should be done with optional values?
A. Assume they always exist
B. Check them or provide fallbacks
C. Delete the widget
D. Disable permissions
Answer: B
Question 14
What is the main security concern when rendering untrusted dynamic content?
A. XSS
B. Database replication
C. JVM garbage collection
D. DNS caching
Answer: A
Question 15
Which statement best describes good template design?
A. Put all application logic in FreeMarker
B. Keep presentation in the template and business logic in the application/service layer
C. Access the database directly from every loop
D. Hard-code all URLs
Answer: B
Quick Revision Table
| Concept | Meaning |
|---|---|
| Widget Template | Alternative presentation for a supported widget |
| ADT | Application Display Template |
| FreeMarker | Common Liferay template language |
| Template Context | Variables and objects available to a template |
#list | FreeMarker iteration |
#if | Conditional rendering |
?? | Checks whether a value exists |
| Default Value | Fallback when a value is absent |
| Asset Publisher | Classic Widget Template use case |
| Fragment | Reusable page-building component |
| Custom Element | Independent frontend application integration |
| Theme | Site-wide presentation mechanism |
| CSS Client Extension | External/custom styling mechanism |
| Localization | Render text according to current locale |
| Escaping | Protect output from unsafe dynamic content |
| N+1 Problem | Repeated expensive calls while rendering a collection |
Complete Architecture
A practical Liferay presentation architecture can be visualized as:
LIFERAY DATA
|
v
+---------------+
| Service Layer |
+-------+-------+
|
v
+---------------+
| Widget |
+-------+-------+
|
| Template Context
v
+---------------+
| Widget |
| Template |
| FreeMarker |
+-------+-------+
|
| HTML
v
+---------------+
| Browser |
+---------------+The division of responsibility is:
Key Takeaway
The simplest way to remember Widget Templates is:
For example:
without changing the underlying Asset Publisher business logic.
A good Liferay architecture therefore follows:
with:
and:
Use a Widget Template when an existing widget already supplies the correct data and behavior but its presentation needs to change.
Version Considerations
Liferay 7.4 spans many GA and quarterly releases. Before implementing a production Widget Template, verify:
- Exact Liferay DXP/Portal release
- Whether the target widget supports Widget Templates
- Available template context variables
- Supported FreeMarker capabilities
- Security restrictions
- Available frontend/Clay classes
- Site permissions
The template context supplied by the target widget should be treated as the authoritative source for the variables and objects that the template can use.
Official Reference
For exact configuration and release-specific details, consult Liferay’s official documentation for creating Widget Templates.
Prefer to read offline? Download the PDF edition (34 pages).
