Search Articles
An error occurred while processing the template.
The following has evaluated to null or missing:
==> response.parentTaxonomyVocabulary [in template "49724393377863#35335#2125834" at line 423, column 71]
----
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: #if response.parentTaxonomyVocabulary... [in template "49724393377863#35335#2125834" at line 423, column 66]
----
1<#assign
2defaultImgMap = {
3 "Default": {
4 "image": "/documents/d/guest/default_logo.png",
5 "color": "gray"
6 },
7 "Livestream": {
8 "image": "/documents/d/guest/icon-desktop-svg",
9 "color": "purple"
10 },
11 "Recorded":{
12 "image": "/documents/d/guest/icon-play",
13 "color": "red"
14 },
15 "In Person":{
16 "image": "/documents/d/guest/icon-persons",
17 "color": "green"
18 },
19 "Download": {
20 "image": "/documents/d/guest/icon-download-black",
21 "color": "border-color"
22 },
23 "Self-paced": {
24 "image": "/documents/d/guest/icon-mouse-white",
25 "color": "black"
26 },
27 "Bank subscription": {
28 "image": "/documents/d/guest/icon-bank",
29 "color": "blue"
30 }
31 }
32/>
33<script>
34 const urlParams = new URLSearchParams(window.location.search);
35 const sortBy = urlParams.get('sort');
36 console.log('sort: ' + sortBy);
37</script>
38<div class="c-mb-4 c-mt-4 search-total-label">
39 <#if searchContainer.getTotal() == 1>
40 ${languageUtil.format(locale, "x-result-for-x", [searchContainer.getTotal(), "<strong class='ms-1'>" + htmlUtil.escape(searchResultsPortletDisplayContext.getKeywords()) + "</strong>"], false)}
41 <#else>
42 ${languageUtil.format(locale, "x-results-for-x", [searchContainer.getTotal(), "<strong class='ms-1'>" + htmlUtil.escape(searchResultsPortletDisplayContext.getKeywords()) + "</strong>"], false)}
43 </#if>
44 <span class="text-separator mx-2">|</span>
45 <div class="search-sorting-dropdown-ib">
46 <button class="search-dropdown-toggle" data-toggle="dropdown" type="button">
47 Sort By: <span class="current-sorting-value">Relevance</span>
48 <svg class="lexicon-icon lexicon-icon-caret-double-l" role="presentation"><use xlink:href="https://icba.org/o/classic-theme/images/clay/icons.svg#caret-double-l" /></svg>
49 </button>
50 <div class="search-dropdown-menu">
51 <a class="dropdown-item transition-link sortWidgetOptions" id="" style="secondary" href="#" data-href="relevance">Relevance</a>
52 <a class="dropdown-item transition-link sortWidgetOptions" id="-low-to-high" style="secondary" href="#" data-href="title+">Name (ascending)</a>
53 <a class="dropdown-item transition-link sortWidgetOptions" id="-low-to-high" style="secondary" href="#" data-href="title-">Name (descending)</a>
54 <a class="dropdown-item transition-link sortWidgetOptions" id="-low-to-high" style="secondary" href="#" data-href="ddmFieldArray.ddm__keyword__45357__publicationDate_en_US.ddmFieldValueKeyword_en_US_String_sortable-">Newest Publication Date</a>
55 <a class="dropdown-item transition-link sortWidgetOptions" id="-high-to-low" style="secondary" href="#" data-href="ddmFieldArray.ddm__keyword__45357__publicationDate_en_US.ddmFieldValueKeyword_en_US_String_sortable+">Oldest Publication Date</a>
56 </div>
57 </div>
58 </div>
59
60<#assign
61categoryMap = {
62 "webinar": {
63 "label": "Webinar"
64 },
65 "conference": {
66 "label": "Conference"
67 },
68 "institute": {
69 "label": "Institute"
70 },
71 "learning lab": {
72 "label": "Learning lab"
73 },
74 "lunch & learn": {
75 "label": "Lunch & learn"
76 },
77 "roundtable": {
78 "label": "Roundtable"
79 },
80 "seminar": {
81 "label": "Seminar"
82 },
83 "whiteboarding": {
84 "label": "Whiteboarding"
85 }
86}
87/>
88
89<#assign endDate = "null"/>
90<#assign endTime = "null"/>
91<#assign startDate = "null"/>
92<#assign startTime = "null"/>
93<#assign modelResourceValue= ""/>
94<#assign cpeCredits = "null"/>
95<#assign locationCity = "null"/>
96<#assign locationState = "null"/>
97<div class="search-results__results">
98 <#assign index = 0/>
99 <#if entries?has_content>
100 <#list entries as entry>
101 <#assign entryDocument = searchResultsPortletDisplayContext.getDocuments()[index] />
102 <#assign index ++ />
103<!-- Other Lookup -->
104<p>
105 <#if entryDocument.getField("expando__keyword__custom_fields__CPE Credits")?has_content >
106 <#assign cpeCredits = entryDocument.getField("expando__keyword__custom_fields__CPE Credits").getValue()/>
107 </#if>
108 </p>
109 <p>
110 <#if entryDocument.getField("expando__keyword__custom_fields__Location City")?has_content >
111 <#assign locationCity = entryDocument.getField("expando__keyword__custom_fields__Location City").getValue()/>
112 </#if>
113 </p>
114 <p>
115 <#if entryDocument.getField("expando__keyword__custom_fields__Location State")?has_content >
116 <#assign locationState = entryDocument.getField("expando__keyword__custom_fields__Location State").getValue()/>
117 </#if>
118 </p>
119 <p>
120 <#if entryDocument.getField("expando__keyword__custom_fields__Event End Date")?has_content >
121 <#assign endDates = entryDocument.getField("expando__keyword__custom_fields__Event End Date").getValue()?datetime("yyyyMMddHHmmss")/>
122 <#assign endDate = endDates?string("MMM dd, yyyy")/>
123 <#assign endTime = endDates?string("hh:mm a")/>
124 </#if>
125 </p>
126 <p>
127 <#if entryDocument.getField("expando__keyword__custom_fields__Event Start Date")?has_content >
128 <#assign startDates = entryDocument.getField("expando__keyword__custom_fields__Event Start Date").getValue()?datetime("yyyyMMddHHmmss")/>
129 <#assign startDate = startDates?string("MMM dd, yyyy")/>
130 <#assign startTime = startDates?string("hh:mm")/>
131 </#if>
132 </p>
133 <div>
134 <#if entryDocument.getField("assetCategoryIds")?has_content >
135 <#list entryDocument.getField("assetCategoryIds").getValues() as categoryId>
136
137 </#list>
138 </#if>
139 </div>
140 <#assign matchedCategories = [] />
141 <#assign matchedEventCategories = [] />
142 <div>
143 <#if entryDocument.getField("assetCategoryTitles_en_US")?has_content>
144 <#assign categoryTitle = entryDocument.getField("assetCategoryTitles_en_US").getValues()/>
145 <#assign categoryList = categoryTitle?join(", ") />
146 <#assign categoryArray = categoryList?split(",") />
147
148 <#list categoryArray as category>
149 <#assign cleanCategory = category?trim />
150 <#if defaultImgMap[cleanCategory]?has_content>
151 <#assign match = {
152 "name": cleanCategory,
153 "image": defaultImgMap[cleanCategory]["image"],
154 "color": defaultImgMap[cleanCategory]["color"]
155 } />
156 <#assign matchedCategories = matchedCategories + [match] />
157 </#if>
158 </#list>
159 </#if>
160 <#if entryDocument.getField("assetCategoryTitles_en_US")?has_content>
161 <#assign eventCategoryTitle = entryDocument.getField("assetCategoryTitles_en_US").getValues()/>
162 <#assign eventCategoryList = eventCategoryTitle?join(", ") />
163 <#assign eventCategoryArray = eventCategoryList?split(",") />
164 <#list eventCategoryArray as events>
165 <#assign cleanEventCategory = events?trim />
166 <#if categoryMap[cleanEventCategory]?has_content>
167 <#assign match = {
168 "name": cleanEventCategory,
169 "label": categoryMap[cleanEventCategory]["label"]
170 } />
171 <#assign matchedEventCategories = matchedEventCategories + [match] />
172 </#if>
173 </#list>
174 </#if>
175 </div>
176
177 <div>
178 <#assign tagArray = [] />
179 <#if entryDocument.getField("assetTagNames")?has_content >
180 <#assign tagTitle = entryDocument.getField("assetTagNames").getValues()/>
181 <#assign tagList = tagTitle?join(", ") />
182 <#assign tagArray = tagList?split(",") />
183 </#if>
184 </div>
185 <div>
186 <#if entryDocument.getField("assetTagIds")?has_content >
187 <#list entryDocument.getField("assetTagIds").getValues() as assetTagId>
188
189 </#list>
190 </#if>
191 </div>
192
193 <#if entry.isModelResourceVisible()>
194 <#assign modelResourceValue = entry.getModelResource()/>
195 </#if>
196<!-- -->
197 <div class="card overflow-hidden bg-white">
198 <div class="card-body d-flex flex-column align-items-start gap-3">
199 <#if modelResourceValue == "Document">
200 <div class="autofit-col">
201 <#if entry.isThumbnailVisible()>
202 <span class="sticker">
203 <span class="sticker-overlay">
204 <img
205 alt="${languageUtil.get(locale, "thumbnail")}"
206 class="sticker-img"
207 src="${entry.getThumbnailURLString()}"
208 />
209 </span>
210 </span>
211 <#elseif entry.isUserPortraitVisible() && stringUtil.equals(entry.getClassName(), userClassName)>
212 <@liferay_ui["user-portrait"] userId=entry.getAssetEntryUserId() />
213 <#elseif entry.isIconVisible()>
214 <span class="sticker sticker-rounded sticker-secondary sticker-static">
215 <@clay.icon symbol="${entry.getIconId()}" />
216 </span>
217 </#if>
218 </div>
219 </#if>
220
221 <#if matchedCategories?has_content>
222 <div class="card-badges d-flex align-items-start gap-4">
223 <div class="d-inline-flex align-items-center gap-2 text-black fs-7 fw-semibold">
224 <#list matchedCategories as item>
225 <div class="bg-${item.color} rounded-bottom-4 py-1 px-3 me-2 text-center">
226 <img src="${item.image}" alt="" class="category-img bg-${item.color}" />
227 <span>${item.name?cap_first}</span>
228 </div>
229 </#list>
230 </div>
231 </div>
232 </#if>
233 <h2 class="card-title m-0 fw-normal">
234
235 <!-- BEGIN GATED CONTENT CHECK -->
236
237 <#assign viewUrl = entry.getViewURL() />
238
239 <#assign gatedContentUrl = "/e/gated-article-check/"+portal.getClassNameId(entry.getClassName())+"/"+entry.getClassPK()+"?p_l_back_url="+urlCodec.encodeURL(searchContainer.getIteratorURL())+"&p_l_back_url_title=Search+Articles" />
240
241 <#if entryDocument.getField("assetCategoryTitles_en_US")?has_content>
242 <#assign categoryTitle = entryDocument.getField("assetCategoryTitles_en_US").getValues()/>
243 <#assign categoryList = categoryTitle?join(",") />
244 <#assign categoryArray = categoryList?split(",") />
245 </#if>
246 <#if categoryArray?has_content >
247 <#assign isGatedContent = (categoryArray?seq_contains("gated")) />
248 <#assign hasPermissionToGatedContent = false />
249
250 <#if isGatedContent >
251 <#if themeDisplay.isSignedIn() >
252 <#assign usersUserGroupsUrl = "/headless-admin-user/v1.0/user-accounts/"+themeDisplay.getUserId()+"/user-groups" />
253 <#assign usersUserGroups = restClient.get(usersUserGroupsUrl) />
254
255 <#if usersUserGroups??>
256 <#list usersUserGroups.items as userGroup>
257 <#if hasPermissionToGatedContent >
258 <#break />
259 </#if>
260
261 <#if categoryArray?seq_contains(userGroup["name"]?trim?lower_case)>
262 <#assign hasPermissionToGatedContent = true />
263 <!--Matched Category: ${userGroup["name"]?trim?lower_case}<br/>-->
264 </#if>
265 </#list>
266 </#if>
267 </#if>
268 </#if>
269
270 <!--
271 Is Gated? ${isGatedContent?c}<br/>gat
272 <#if isGatedContent>
273 Has Permission to Gated? ${hasPermissionToGatedContent?c}<br/>
274 </#if>-->
275
276 <#if isGatedContent && !hasPermissionToGatedContent>
277 <#assign viewUrl = gatedContentUrl />
278 </#if>
279 </#if>
280 <!-- END GATED CONTENT CHECK -->
281
282 <#if modelResourceValue == "Product" && entry.getViewURL()?contains("/p/")>
283 <#assign viewUrl = ("https://icba.lxc.liferay.com/p/" + entry.getViewURL()?keep_after("/p/")) />
284 </#if>
285
286 <a href="${viewUrl}">
287 ${entry.getHighlightedTitle()}
288 </a>
289 </h2>
290
291 <p class="card-text m-0">
292 <#if entry.isContentVisible()>
293 ${entry.getContent()}
294 </#if>
295 </p>
296 <div class="mt-2">
297 <div class="d-flex align-items-center mb-2">
298 <div class="d-flex align-items-center flex-wrap gap-2">
299
300 <#if modelResourceValue == "Web Content Article">
301 <#assign fullDate = entry.getPublishedDateString() />
302
303 <#assign ddmFieldArray = entryDocument.getField("ddmFieldArray").getValues() />
304
305 <#if ddmFieldArray??>
306 <#list ddmFieldArray as ddmField>
307 <#assign fieldFound = false />
308 <#assign articleFields = ddmField?remove_beginning("{")?remove_ending("}")?split(",") />
309
310 <#if articleFields??>
311 <#list articleFields as articleField>
312 <#assign articleFieldValues = articleField?split("=") />
313
314 <#if articleFieldValues?? && articleFieldValues?size == 2>
315 <#if articleFieldValues[0]?trim == "ddmFieldName">
316 <#if articleFieldValues[1] == "ddm__keyword__45357__publicationDate_en_US">
317 <#assign fieldFound = true />
318 </#if>
319 </#if>
320
321 <#if fieldFound && (articleFieldValues[0]?trim == "ddmFieldValueKeyword_en_US_date")>
322 <#assign fullDate = articleFieldValues[1]?datetime("yyyyMMddHHmmss")?string("MMM dd, yyyy") />
323 </#if>
324 </#if>
325 </#list>
326 </#if>
327
328 </#list>
329 </#if>
330
331 <#assign dateOnly = fullDate?split(" ")[0..2]?join(" ") />
332 <small class="text-muted">${dateOnly}</small>
333 </#if>
334
335 <#if entry.isPublishedDateVisible() && modelResourceValue == "Document">
336 <#assign fullDate = entry.getPublishedDateString() />
337 <#assign dateOnly = fullDate?split(" ")[0..2]?join(" ") />
338 <small class="text-muted">${dateOnly}</small>
339 </#if>
340
341 <#if entry.isPublishedDateVisible() && modelResourceValue == "Product" && startDate != "null">
342 <small class="text-muted">${startDate}</small>
343 </#if>
344 <#if modelResourceValue?has_content && modelResourceValue == "Web Content Article">
345 <#if entry.isPublishedDateVisible()>
346 <div>|</div>
347 </#if>
348 <strong>Article</strong>
349 </#if>
350 <div>
351 <#if matchedEventCategories?has_content && modelResourceValue == "Product">
352 <#list matchedEventCategories as productEventType>
353 | <strong> ${productEventType.label}</strong>
354 </#list>
355 </#if>
356 <#if startTime?has_content && startTime != "null" && modelResourceValue == "Product">
357 ${startTime}-
358 </#if>
359 <#if endTime?has_content && endTime != "null" && modelResourceValue == "Product">
360 ${endTime}
361 </#if>
362 <#if locationCity?has_content && locationCity != "null" && modelResourceValue == "Product">
363 ${locationCity},
364 </#if>
365 <#if locationState?has_content && locationState != "null" && modelResourceValue == "Product">
366 ${locationState}
367 </#if>
368 </div>
369 <#if cpeCredits?has_content && cpeCredits != "null" && modelResourceValue == "Product">
370 CPE Credits: ${cpeCredits}
371 </#if>
372 <!-- <#if modelResourceValue?has_content && modelResourceValue == "Page">
373 <strong>${modelResourceValue} ${entry.getClassPK()}</strong>
374 </#if>-->
375 </div>
376 </div>
377 <div class="d-flex gap-2 align-items-start justify-content-start flex-wrap">
378 <#if modelResourceValue?has_content && modelResourceValue == "Product">
379 <#assign chanelId = "230564"/>
380 <#assign productCategories = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${chanelId}/products/${entryDocument.cpProductId}/categories?pageSize=40")/>
381 <#assign categories = productCategories.items/>
382 <#if categories?has_content>
383 <#assign topicCount = 0/>
384 <#assign displayedCategories = []/>
385 <#assign totalTopicCount = 0/>
386 <#-- First, count total topic categories -->
387 <#list categories as category>
388 <#if category.vocabulary == 'topic'>
389 <#assign totalTopicCount += 1>
390 </#if>
391 </#list>
392 <#-- Now display first 3 topics -->
393 <#list categories as category>
394 <#if category.vocabulary == 'topic' && topicCount < 3>
395 <#assign taxonomyCategoryId = category.id/>
396 <#assign response = restClient.get("/headless-admin-taxonomy/v1.0/taxonomy-categories/${taxonomyCategoryId}") />
397 <#if response.taxonomyCategoryProperties?has_content>
398 <#assign firstProperty = response.taxonomyCategoryProperties[0] />
399 <#assign categoryValue = firstProperty.value />
400 <span class="tag-pill body-13">${categoryValue}</span>
401 <#else>
402 <span class="tag-pill body-13">${category.name}</span>
403 </#if>
404 <#assign topicCount += 1>
405 </#if>
406 </#list>
407 <#-- If more topics exist, show "+X More..." -->
408 <#if (totalTopicCount - topicCount) gt 0>
409 <span class="tag-pill body-13">+${totalTopicCount - topicCount} More...</span>
410 </#if>
411 </#if>
412 </#if>
413 <!-- For Article -->
414 <#if modelResourceValue?has_content && modelResourceValue == "Web Content Article">
415 <#assign topicList = [] />
416 <#assign structuredContentId = entry.getClassPK() />
417 <#assign contentCategories = restClient.get("/headless-delivery/v1.0/structured-contents/${structuredContentId}") />
418
419 <!-- Collect Topic Categories -->
420 <#list contentCategories.taxonomyCategoryBriefs as category>
421 <#assign taxonomyCategoryId = category.taxonomyCategoryId />
422 <#assign response = restClient.get("/headless-admin-taxonomy/v1.0/taxonomy-categories/${taxonomyCategoryId}") />
423 <#if response.parentTaxonomyVocabulary.name == "Topic">
424 <#assign topicList += [response] />
425 </#if>
426 </#list>
427
428 <!-- Display First 3 and '+X More' -->
429 <#assign topicCount = topicList?size />
430 <#if topicCount gt 3>
431 <#list topicList[0..2] as topic>
432 <span class="tag-pill body-13">${topic.name}</span>
433 </#list>
434 <span class="tag-pill body-13">+${topicCount - 3} More...</span>
435 <#else>
436 <#list topicList as topic>
437 <span class="tag-pill body-13">${topic.name}</span>
438 </#list>
439 </#if>
440 </#if>
441
442 <!-- Ends -->
443 <!-- For Page -->
444 <#if modelResourceValue?has_content && modelResourceValue == "Page">
445<#assign topicList = [] />
446<#assign pageId = entry.getClassPK() />
447<#assign url = "/headless-delivery/v1.0/sites/35333/site-pages?fields=id,taxonomyCategoryBriefs&filter=id%20eq%20%27${pageId}%27" />
448<#assign pageDetails = restClient.get(url) />
449<#if pageDetails?has_content && pageDetails.items?has_content>
450 <#assign items = pageDetails.items />
451 <#if items?has_content>
452 <#list items as item>
453 <#if item.taxonomyCategoryBriefs?has_content>
454 <#list item.taxonomyCategoryBriefs as brief>
455 <#assign taxonomyCategoryId = brief.taxonomyCategoryId />
456 <#assign response = restClient.get("/headless-admin-taxonomy/v1.0/taxonomy-categories/${taxonomyCategoryId}") />
457 <#if response.parentTaxonomyVocabulary.name == "Topic">
458 <#assign topicList += [response] />
459 </#if>
460 </#list>
461 </#if>
462 </#list>
463 </#if>
464 <#else>
465
466 </#if>
467<!-- Display First 3 and '+X More' -->
468<#assign topicCount = topicList?size />
469<#if topicCount gt 3>
470<#list topicList[0..2] as topic>
471 <span class="tag-pill body-13">${topic.name}</span>
472</#list>
473<span class="tag-pill body-13">+${topicCount - 3} More...</span>
474<#else>
475<#list topicList as topic>
476 <span class="tag-pill body-13">${topic.name}</span>
477</#list>
478</#if>
479</#if>
480
481
482 <!-- Ends -->
483 </div>
484 <div>
485 <#if entry.isAssetRendererURLDownloadVisible() && modelResourceValue == "Document">
486 <div class="autofit-col">
487 <span
488 class="c-mt-2 lfr-portal-tooltip"
489 title="${languageUtil.format(locale, 'download-x', ['(' + languageUtil.formatStorageSize(entry.getAssetRendererDownloadSize(), locale) + ')'])}"
490 >
491 <@clay.link
492 aria\-label="${languageUtil.format(locale, 'download-x', [entry.getTitle()])}"
493 cssClass="link-monospaced link-outline link-outline-borderless link-outline-secondary"
494 displayType="secondary"
495 href="${entry.getAssetRendererURLDownload()}"
496 >
497 <@clay.icon symbol="download" />
498 </@clay.link>
499 </span>
500 </div>
501 </#if>
502 </div>
503 </div>
504 </div>
505 </div>
506 </#list>
507 </#if>
508</div>
