App Marketplace
Expand Liferay's portfolio through apps from our partner and developer ecosystems to enhance your digital transformation.
Nenhuma vertente foi encontrada.
Um erro ocorreu enquanto processava o modelo.
The following has evaluated to null or missing: ==> channel.items [in template "3192443#3192485#18426537" at line 113, 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#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>
Welcome, you are now a member of