App Marketplace

Expand Liferay's portfolio through apps from our partner and developer ecosystems to enhance your digital transformation.
Fasetteja ei löytynyt.
LIFERAY VERSION
EDITION
CATEGORY
Marketplace PRICE
LIFERAY PLATFORM OFFERING
Virhe tapahtui prosessoidessa esitysmallia.
The following has evaluated to null or missing:
==> channel.items[0]  [in template "3192443#3192485#18426537" at line 113, column 30]

----
Tip: It's the final [] step 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#18426537" at line 113, column 9]
----
1<style type="text/css"> 
2		color: var(--black); 
3
4 
5	.lfr-layout-structure-item-com-liferay-site-navigation-breadcrumb-web-portlet-sitenavigationbreadcrumbportlet { 
6		background: #ffffff; 
7		border-radius: 10px; 
8		height: 40px; 
9		padding: 0px 16px; 
10
11 
12	.adt-apps-search-results .card-image-title-container .image-container { 
13		height: 3rem; 
14
15 
16	.adt-apps-search-results .card-image-title-container .title-container { 
17		word-break: break-word; 
18		word-wrap: break-word; 
19
20 
21	.adt-apps-search-results .cards-container .app-search-results-card .card-image-title-container .image-container .app-search-image { 
22		height: 48px; 
23		object-fit: contain; 
24		width: 48px; 
25
26 
27	.adt-apps-search-results .labels .category-label-remainder:hover .category-names { 
28		display: block; 
29
30 
31	.app-search-results-card { 
32		border-radius: 10px; 
33		border: 1px solid #E7EFFF; 
34		display: flex; 
35		height: 298px; 
36		padding: 16px; 
37
38 
39	.banner__product-tag { 
40		background-color: #e6ebf5; 
41		color: #1c3667; 
42		font-size: 0.8125rem; 
43		white-space: nowrap; 
44		width: fit-content; 
45
46 
47	.cards-container { 
48		display: grid; 
49		grid-column-gap: 1rem; 
50		grid-row-gap: 1.5rem; 
51		grid-template-columns: repeat(3, minmax(0, 1fr)); 
52
53 
54	.card-image-title-container { 
55		height: 48px; 
56		margin-bottom: 18px; 
57
58 
59	.developer-name { 
60		color: #54555F; 
61		font-size: 13px; 
62		font-weight: 400; 
63		line-height: 16px; 
64
65 
66	.title-container { 
67		font-size: 18px; 
68		font-weight: 600; 
69		line-height: 20px; 
70
71 
72	@media screen and (max-width: 599px) { 
73		.adt-apps-search-results .cards-container { 
74			grid-column-gap: .5rem; 
75			grid-row-gap: .5rem; 
76			grid-template-columns: 293px; 
77			justify-content: center; 
78
79 
80		.adt-apps-search-results .app-search-results-card { 
81			height: 281px; 
82
83
84 
85	@media screen and (min-width:600px) and (max-width: 899px) { 
86		.adt-apps-search-results .cards-container { 
87			grid-column-gap: .5rem; 
88			grid-row-gap: 1.5rem; 
89			grid-template-columns: repeat(2, minmax(0, 1fr)); 
90
91
92</style> 
93 
94<#if searchContainer?has_content> 
95	<div class="color-neutral-3 d-md-block d-none pb-4 pt-2"> 
96		<strong class="color-black"> 
97			${searchContainer.getTotal()} 
98		</strong> 
99		Applications Available 
100	</div> 
101</#if> 
102 
103<#if themeDisplay?has_content> 
104	<#assign scopeGroupId = themeDisplay.getScopeGroupId() /> 
105</#if> 
106 
107<#assign 
108	channel = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?accountId=-1&filter=name eq 'Marketplace Channel' and siteGroupId eq '${scopeGroupId}'") 
109	productThumbnail1 ="/o/commerce-media/default/?groupId=${scopeGroupId}" 
110/> 
111 
112<#if channel?has_content> 
113	<#assign channelId = channel.items[0].id /> 
114</#if> 
115 
116<div class="adt-apps-search-results"> 
117	<div class="cards-container pb-6"> 
118		<#if entries?has_content> 
119			<#list entries as entry> 
120				<#if entry?has_content> 
121					<#assign 
122						portalURL=portalUtil.getLayoutURL(themeDisplay) 
123						productId=entry.getClassPK() + 1 
124						product=restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/"+ channelId +"/products/"+ productId +"?accountId=-1&images.accountId=-1&nestedFields=productSpecifications,categories,images") 
125						productImage=(product.images![] 
126						)?filter(item -> item.tags?seq_contains("app icon"))![] 
127						remainingCategoriesText = [] 
128					/> 
129						<#if product.categories?has_content && product.productSpecifications?has_content> 
130							<#assign 
131									productCategories = product.categories?filter(productCategory -> productCategory.vocabulary=="marketplace-app-category")![] 
132									categoriesListSize = productCategories?size-1 
133									productSpecifications = product.productSpecifications![] 
134							/> 
135						</#if> 
136 
137					<#if product.name?has_content> 
138						<#assign productName = product.name /> 
139						<#else> 
140							<#assign productName ="" /> 
141					</#if> 
142 
143					<#if product.description?has_content> 
144						<#assign productDescription = stringUtil.shorten(htmlUtil.stripHtml(product.description!""), 150, "...") /> 
145						<#else> 
146							<#assign productDescription = "" /> 
147					</#if> 
148 
149					<#if product.urls?has_content> 
150						<#assign productURL = portalURL?replace("home", "p") + "/" + product.urls.en_US /> 
151						<#else> 
152							<#assign productURL = "" /> 
153					</#if> 
154 
155					<#if productImage?has_content> 
156						<#assign productThumbnail = productImage[0].src?split("/o") /> 
157						<#if productThumbnail?has_content && productThumbnail?size gte 2> 
158							<#assign productThumbnail1 = "/o/${productThumbnail[1]}" !"" /> 
159						</#if> 
160 
161					<#else> 
162						<#if product.urlImage?has_content> 
163							<#assign productThumbnail = product.urlImage?split("/o") /> 
164							<#if productThumbnail?has_content && productThumbnail?size gte 2> 
165								<#assign productThumbnail1 = "/o/${productThumbnail[1]}" !"" /> 
166							</#if> 
167						</#if> 
168					</#if> 
169 
170					<a class="app-search-results-card bg-white border-radius-medium d-flex flex-column mb-0 text-dark text-decoration-none" href=${productURL}> 
171						<div class="align-items-center card-image-title-container d-flex"> 
172							<div class="image-container mr-2 rounded"> 
173								<img alt="${productName}" class="app-search-image" src="${productThumbnail1}" /> 
174							</div> 
175 
176							<div> 
177								<div class="title-container"> 
178									${productName} 
179								</div> 
180 
181								<#if productSpecifications?has_content> 
182									<#assign productDeveloperName = productSpecifications?filter(item -> item.specificationKey == "developer-name") /> 
183									<#list productDeveloperName as developerNameItem> 
184										<#if developerNameItem.value?has_content> 
185											<#assign developerName = developerNameItem.value /> 
186										<#else> 
187											<#assign developerName = "" /> 
188										</#if> 
189 
190										<div class="developer-name mt-1"> 
191											${developerName} 
192										</div> 
193									</#list> 
194								</#if> 
195							</div> 
196						</div> 
197 
198						<div class="d-flex flex-column font-size-paragraph-small h-100 justify-content-between"> 
199							<div class="font-weight-normal mb-2 text-break"> 
200								${productDescription} 
201							</div> 
202 
203							<div class="d-flex flex-column"> 
204								<#if productSpecifications?has_content> 
205									<#assign productPriceModels = productSpecifications?filter(item -> item.specificationKey == "price-model") /> 
206									<#list productPriceModels as productPriceModel> 
207										<#if productPriceModel.value?has_content> 
208											<#assign priceModel = productPriceModel.value /> 
209										<#else> 
210											<#assign priceModel = "" /> 
211										</#if> 
212 
213										<div class="font-weight-semi-bold mb-2 mt-1 text-capitalize"> 
214											${priceModel} 
215										</div> 
216									</#list> 
217								</#if> 
218 
219								<#if productCategories?has_content> 
220									<#assign 
221										principalCategory = productCategories[0] 
222										remainingCategories = productCategories?filter(category -> category.name != principalCategory.name) 
223									/> 
224 
225									<#list remainingCategories as category> 
226										<#assign remainingCategoriesText = remainingCategoriesText + [category.name] /> 
227									</#list> 
228								</#if> 
229 
230								<#if principalCategory?has_content > 
231									<div class="d-flex"> 
232										<span class="banner__product-tag rounded py-1 px-2 mr-2" title="${principalCategory.name}"> 
233											${principalCategory.name} 
234										</span> 
235										<#if categoriesListSize?has_content && remainingCategoriesText?has_content> 
236											<span class="banner__product-tag rounded py-1 px-2" title="${remainingCategoriesText?join('\n')}"> 
237												+ ${categoriesListSize} 
238											</span> 
239										</#if> 
240									</div> 
241								</#if> 
242							</div> 
243						</div> 
244					</a> 
245				</#if> 
246			</#list> 
247		</#if> 
248	</div> 
249</div> 
Lajittele