/o//commerce-media/accounts/-1/images/18648322?download=true

Dockbar Integration
Se ha producido un error al procesar la plantilla.
The following has evaluated to null or missing:
==> channel.items  [in template "3192443#3192485#null" at line 109, column 30]

----
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: #assign channelId = channel.items[0].id  [in template "3192443#3192485#null" at line 109, column 9]
----
1<style> 
2	.app-container { 
3		border-color: #2e5aac !important; 
4		color: #2e5aac; 
5		font-size: MEDIUM; 
6
7 
8	.app-category { 
9		display: block; 
10		flex: 1; 
11		max-width: 200px; 
12		overflow: hidden; 
13		text-overflow: ellipsis; 
14		white-space: nowrap; 
15
16 
17	.app-container .app-category { 
18		background-color: #e6ebf5; 
19		color: #1c3667; 
20		padding: 4px 8px; 
21
22 
23	.app-container .app-product-type { 
24		min-width: 0; 
25		overflow: hidden; 
26		text-overflow: ellipsis; 
27		white-space: nowrap; 
28
29 
30	.client-extension-product-type { 
31		background-color: #FFE6C6; 
32		color: #9D4C00; 
33
34 
35	.cloud-product-type { 
36		background-color: #D1EEDC; 
37		color: #0E7835; 
38
39 
40	.composite-app-product-type { 
41		background-color: #FBE0FF; 
42		color: #720086; 
43
44 
45	.diamond-icon-container { 
46		color: #C9C9CF; 
47		height: 4px; 
48		width: 4px; 
49
50 
51	.dxp-product-type { 
52		background-color: #D1ECFA; 
53		color: #166E9E; 
54
55 
56	.low-code-configuration-product-type { 
57		background-color: #DCD7E9; 
58		color: #503690; 
59
60 
61	@media screen and (max-width: 768px) { 
62		.app-container { 
63			font-size: small; 
64
65
66 
67	@media screen and (max-width: 576px) { 
68		.app-container { 
69			font-size: x-small; 
70
71 
72		.app-container .app-category, 
73		.app-container .app-product-type { 
74			padding: 2px 4px; 
75
76
77</style> 
78 
79<#assign 
80	productTypeValues = 
81
82			"client-extension": "Client Extension", 
83			"cloud": "Cloud App", 
84			"composite-app": "Composite App", 
85			"dxp": "DXP App", 
86			"low-code-configuration": "Low-Code" 
87
88 
89	VOCABULARY_PRODUCT_CATEGORY = "MARKETPLACE-APP-CATEGORY" 
90/> 
91 
92<#if themeDisplay?has_content> 
93	<#assign scopeGroupId = themeDisplay.getScopeGroupId() /> 
94</#if> 
95 
96<#if currentURL?has_content> 
97	<#if currentURL?contains('web')> 
98		<#assign 
99			index = 2 
100			partsUrl = currentURL?split('/') 
101			siteName = partsUrl[index..index]?join('/') 
102		/> 
103	</#if> 
104</#if> 
105 
106<#assign channel = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?accountId=-1&filter=name eq 'Marketplace Channel' and siteGroupId eq '${scopeGroupId}'") /> 
107 
108<#if channel?has_content> 
109	<#assign channelId = channel.items[0].id /> 
110</#if> 
111 
112<#if (CPDefinition_cProductId.getData())??> 
113	<#assign productId = CPDefinition_cProductId.getData() /> 
114</#if> 
115 
116<#assign 
117	product = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/"+ channelId +"/products/"+ productId +"?accountId=-1&nestedFields=productSpecifications,categories") 
118	categories = product.categories![] 
119	productSpecifications = product.productSpecifications![] 
120/> 
121 
122<div class="app-container color-neutral-3 d-flex flex-wrap font-size-paragraph-small justify-content-between w-100"> 
123	<div class="d-flex"> 
124		<#if productSpecifications?has_content> 
125			<#assign productTypes = productSpecifications?filter(item -> stringUtil.equals(item.specificationKey, "type")) /> 
126 
127			<#list productTypes as productType> 
128				<#if productType?has_content> 
129					<#assign appType = (productTypeValues[productType.value]!) /> 
130 
131					<#if appType?has_content> 
132						<div class="align-items-center app-product-type border border-radius-small d-flex mb-1 mr-2 px-2 rounded-lg ${productType.value}-product-type"> 
133							<div class="bg-neutral-8">${appType}</div> 
134						</div> 
135					</#if> 
136				</#if> 
137			</#list> 
138		</#if> 
139 
140		<#if categories?has_content> 
141			<#assign filteredCategories = categories?filter(category -> category.vocabulary?upper_case == VOCABULARY_PRODUCT_CATEGORY) /> 
142 
143			<#if filteredCategories?has_content && appType?has_content> 
144				<span class="align-items-center d-flex justify-content-between"> 
145					<span class="align-items-center d-flex diamond-icon-container justify-content-between mr-3"> 
146						<@clay["icon"] symbol="diamond" /> 
147					</span> 
148				</span> 
149			</#if> 
150 
151			<#list categories as category> 
152				<#if category.vocabulary?upper_case == VOCABULARY_PRODUCT_CATEGORY> 
153					<span class="app-category bg-neutral-8 border-radius-small mb-1 mr-2 px-3 rounded-lg" title="${category.name}"> 
154						${category.name} 
155					</span> 
156				</#if> 
157			</#list> 
158		</#if> 
159	</div> 
160</div> 
18647768
The application adds a new custom permission called VIEW_DOCKBAR inside the "General Permissions" section of the role configuration (except for Guest role).
With this new custom permission, frontend developers can leverage the Liferay permission system to show/hide the portal dockbar inside a custom theme.

Here's how to initialize a Freemarker variable inside the init_custom.ftl file of a custom theme:
<#assign viewDockbar = permissionChecker.hasPermission(themeDisplay.scopeGroupId, "90", "90", "VIEW_DOCKBAR") />

And here's how to use the Freemarker variable:
<#if viewDockbar>
<@liferay.control_menu />
</#if>

On Liferay 7.4+ you need to add this property to your portal-ext.properties file in order to make it working:
resource.actions.strict.mode.enabled=false
DEVELOPER
Se ha producido un error al procesar la plantilla.
The following has evaluated to null or missing:
==> publisePages.items  [in template "3192443#3192485#null" at line 36, column 38]

----
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: #assign publisePage = publisePages.items  [in template "3192443#3192485#null" at line 36, column 17]
----
1<#if themeDisplay?has_content> 
2	<#assign scopeGroupId = themeDisplay.getScopeGroupId() /> 
3</#if> 
4 
5<#if currentURL?has_content> 
6	<#if currentURL?contains('web')> 
7		<#assign 
8			index = 2 
9			partsUrl = currentURL?split('/') 
10			siteName = partsUrl[index..index]?join('/') 
11		/> 
12	</#if> 
13</#if> 
14 
15<#assign channel = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?accountId=-1&filter=name eq 'Marketplace Channel' and siteGroupId eq '${scopeGroupId}'") /> 
16 
17<#if channel?has_content> 
18	<#assign channelId = channel.items[0].id /> 
19</#if> 
20 
21<#if (CPDefinition_cProductId.getData())??> 
22	<#assign productId = CPDefinition_cProductId.getData() /> 
23</#if> 
24 
25<#assign 
26	product = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/"+ channelId +"/products/"+ productId +"?accountId=-1&nestedFields=productSpecifications") 
27	productSpecifications = product.productSpecifications![] 
28	catalogName=product.catalogName 
29/> 
30 
31<#if catalogName?has_content> 
32	<#assign publisePages=restClient.get("/c/publisherdetailses?filter=publisherName eq '${catalogName}'" ) /> 
33	<#assign redirectPath="https://marketplace.liferay.com/e/publisher-details/29282497"/> 
34	 
35	<#if publisePages?has_content> 
36		<#assign publisePage=publisePages.items /> 
37			<#if publisePage?has_content> 
38						<#assign publisherDetail=publisePage[0]/> 
39			</#if> 
40	</#if> 
41</#if> 
42 
43<div> 
44	<#if productSpecifications?has_content> 
45		<#assign developerNames = productSpecifications?filter(item -> stringUtil.equals(item.specificationKey, "developer-name")) /> 
46 
47		<#if developerNames?has_content> 
48			<#list developerNames as developerName> 
49				<#if publisherDetail?has_content> 
50					<a class="bg-neutral-8" href="${redirectPath}/${publisherDetail.id}"> 
51						${developerName.value} 
52					</a> 
53				<#else> 
54					<a class="bg-neutral-8" 	href="/?developer-name=${developerName.value}"> 
55						${developerName.value} 
56					</a> 
57				</#if> 
58			</#list> 
59		</#if> 
60	</#if> 
61</div> 
DEVELOPER
21/11/24 18:40
Published date
21/11/24 18:40
Published Date
21/11/24 18:40
SUPPORTED OFFERINGS
Liferay PaaS
Supported Versions
7.4
Resource Requirements
Edition
CE
PRICE
Free
help & support
SHARE LINK
Copy & Share

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.