An error occurred while processing the template.
The following has evaluated to null or missing:
==> product.images [in template "3192443#3192485#null" at line 17, column 24]
----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: productImage = product.images?filter(... [in template "3192443#3192485#null" at line 17, column 9]
----
1<#if themeDisplay?has_content>
2 <#assign scopeGroupId = themeDisplay.getScopeGroupId() />
3</#if>
4
5<#assign channel = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?accountId=-1&filter=name eq 'Marketplace Channel' and siteGroupId eq '${scopeGroupId}'") />
6
7<#if channel?has_content>
8 <#assign channelId = channel.items[0].id />
9</#if>
10
11<#if (CPDefinition_cProductId.getData())??>
12 <#assign productId = CPDefinition_cProductId.getData() />
13</#if>
14
15<#assign
16 product = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/"+ channelId +"/products/"+ productId +"?accountId=-1&images.accountId=-1&nestedFields=images")
17 productImage = product.images?filter(item -> item.tags?seq_contains("app icon"))![]
18/>
19
20<#if productImage?has_content>
21 <#assign productThumbnail = productImage[0].src?split("/o") />
22 <#if productThumbnail?has_content && productThumbnail?size gte 2>
23 <#assign productThumbnail1 = "/o/${productThumbnail[1]}"!"" />
24 <#else>
25 <#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" />
26 </#if>
27<#else>
28 <#if product.urlImage?has_content>
29 <#assign productThumbnail = product.urlImage?split("/o") />
30 <#if productThumbnail?has_content && productThumbnail?size gte 2>
31 <#assign productThumbnail1 = "/o/${productThumbnail[1]}"!"" />
32 <#else>
33 <#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" />
34 </#if>
35 <#else>
36 <#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" />
37 </#if>
38</#if>
39
40${productThumbnail1}
The following has evaluated to null or missing:
==> product.images [in template "3192443#3192485#null" at line 17, column 24]
----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: productImage = product.images?filter(... [in template "3192443#3192485#null" at line 17, column 9]
----
1<#if themeDisplay?has_content>
2 <#assign scopeGroupId = themeDisplay.getScopeGroupId() />
3</#if>
4
5<#assign channel = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?accountId=-1&filter=name eq 'Marketplace Channel' and siteGroupId eq '${scopeGroupId}'") />
6
7<#if channel?has_content>
8 <#assign channelId = channel.items[0].id />
9</#if>
10
11<#if (CPDefinition_cProductId.getData())??>
12 <#assign productId = CPDefinition_cProductId.getData() />
13</#if>
14
15<#assign
16 product = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/"+ channelId +"/products/"+ productId +"?accountId=-1&images.accountId=-1&nestedFields=images")
17 productImage = product.images?filter(item -> item.tags?seq_contains("app icon"))![]
18/>
19
20<#if productImage?has_content>
21 <#assign productThumbnail = productImage[0].src?split("/o") />
22 <#if productThumbnail?has_content && productThumbnail?size gte 2>
23 <#assign productThumbnail1 = "/o/${productThumbnail[1]}"!"" />
24 <#else>
25 <#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" />
26 </#if>
27<#else>
28 <#if product.urlImage?has_content>
29 <#assign productThumbnail = product.urlImage?split("/o") />
30 <#if productThumbnail?has_content && productThumbnail?size gte 2>
31 <#assign productThumbnail1 = "/o/${productThumbnail[1]}"!"" />
32 <#else>
33 <#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" />
34 </#if>
35 <#else>
36 <#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" />
37 </#if>
38</#if>
39
40${productThumbnail1}
With it you can use the mobiles rules provided by Liferay to adapt theme, layout template, redirect, etc.
It is intended as an alternative to a repository-type plugin (such as wurfl), considering it is much easier to maintain a small set of rules than a complete repository of any possible device in the world.
This plugin uses simple rules over "User-Agent" Strings to detect devices.
Most of the time you only want to know which OS you are on, and if it is a tablet: the rules set are designed this way.
You can customize and adapt your device detection to your needs:
Rules are declared in portlet.properties, the file is documented.
A simple set of rules is provided; you are free to complete it with the way you like.
If you need to, you can focus on a precise device type by creating a new group of rules over a precise UA match.
You can now support rooted smartphones or tablets, or even unknown and upcoming devices that are not yet supported by other providers !
Be aware that the drawback of this approach is that you can not retrieve detailed features of the devices, such as screen size, presence of a keyboard, etc. Only infos in "User-Agent" header will ever be useable.
With it you can use the mobiles rules provided by Liferay to adapt theme, layout template, redirect, etc.
It is intended as an alternative to a repository-type plugin (such as wurfl), considering it is much easier to maintain a small set of rules than a complete repository of any possible device in the world.
This plugin uses simple rules over "User-Agent" Strings to detect devices.
Most of the time you only want to know which OS you are on, and if it is a tablet: the rules set are designed this way.
You can customize and adapt your device detection to your needs:
Rules are declared in portlet.properties, the file is documented.
A simple set of rules is provided; you are free to complete it with the way you like.
If you need to, you can focus on a precise device type by creating a new group of rules over a precise UA match.
You can now support rooted smartphones or tablets, or even unknown and upcoming devices that are not yet supported by other providers !
Be aware that the drawback of this approach is that you can not retrieve detailed features of the devices, such as screen size, presence of a keyboard, etc. Only infos in "User-Agent" header will ever be useable.
Developer
Publisher Date
January 23, 2024
Deployment Method
Liferay Self-Hosted
Liferay PaaS
App Type
Version
Supported Versions
Standard Price
Help and Support
Share Link
HTML Example
A paragraph is a self-contained unit of a discourse in writing dealing with a particular point or idea. Paragraphs are usually an expected part of formal writing, used to organize longer prose.