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