Search Articles
An error occurred while processing the template.
The following has evaluated to null or missing:
==> response.parentTaxonomyVocabulary [in template "49724393377863#35335#2124509" at line 419, 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#2124509" at line 419, 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">
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.lxc.liferay.com/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 <a href="${viewUrl}">
283 ${entry.getHighlightedTitle()}
284 </a>
285 </h2>
286
287 <p class="card-text m-0">
288 <#if entry.isContentVisible()>
289 ${entry.getContent()}
290 </#if>
291 </p>
292 <div class="mt-2">
293 <div class="d-flex align-items-center mb-2">
294 <div class="d-flex align-items-center flex-wrap gap-2">
295
296 <#if modelResourceValue == "Web Content Article">
297 <#assign fullDate = entry.getPublishedDateString() />
298
299 <#assign ddmFieldArray = entryDocument.getField("ddmFieldArray").getValues() />
300
301 <#if ddmFieldArray??>
302 <#list ddmFieldArray as ddmField>
303 <#assign fieldFound = false />
304 <#assign articleFields = ddmField?remove_beginning("{")?remove_ending("}")?split(",") />
305
306 <#if articleFields??>
307 <#list articleFields as articleField>
308 <#assign articleFieldValues = articleField?split("=") />
309
310 <#if articleFieldValues?? && articleFieldValues?size == 2>
311 <#if articleFieldValues[0]?trim == "ddmFieldName">
312 <#if articleFieldValues[1] == "ddm__keyword__45357__publicationDate_en_US">
313 <#assign fieldFound = true />
314 </#if>
315 </#if>
316
317 <#if fieldFound && (articleFieldValues[0]?trim == "ddmFieldValueKeyword_en_US_date")>
318 <#assign fullDate = articleFieldValues[1]?datetime("yyyyMMddHHmmss")?string("MMM dd, yyyy") />
319 </#if>
320 </#if>
321 </#list>
322 </#if>
323
324 </#list>
325 </#if>
326
327 <#assign dateOnly = fullDate?split(" ")[0..2]?join(" ") />
328 <small class="text-muted">${dateOnly}</small>
329 </#if>
330
331 <#if entry.isCreationDateVisible() && modelResourceValue == "Document">
332 <#assign fullDate = entry.getCreationDateString() />
333 <#assign dateOnly = fullDate?split(" ")[0..2]?join(" ") />
334 <small class="text-muted">${dateOnly}</small>
335 </#if>
336
337 <#if entry.isCreationDateVisible() && modelResourceValue == "Product" && startDate != "null">
338 <small class="text-muted">${startDate}</small>
339 </#if>
340 <#if modelResourceValue?has_content && modelResourceValue == "Web Content Article">
341 <#if entry.isCreationDateVisible()>
342 <div>|</div>
343 </#if>
344 <strong>Article</strong>
345 </#if>
346 <div>
347 <#if matchedEventCategories?has_content && modelResourceValue == "Product">
348 <#list matchedEventCategories as productEventType>
349 | <strong> ${productEventType.label}</strong>
350 </#list>
351 </#if>
352 <#if startTime?has_content && startTime != "null" && modelResourceValue == "Product">
353 ${startTime}-
354 </#if>
355 <#if endTime?has_content && endTime != "null" && modelResourceValue == "Product">
356 ${endTime}
357 </#if>
358 <#if locationCity?has_content && locationCity != "null" && modelResourceValue == "Product">
359 ${locationCity},
360 </#if>
361 <#if locationState?has_content && locationState != "null" && modelResourceValue == "Product">
362 ${locationState}
363 </#if>
364 </div>
365 <#if cpeCredits?has_content && cpeCredits != "null" && modelResourceValue == "Product">
366 CPE Credits: ${cpeCredits}
367 </#if>
368<!-- <#if modelResourceValue?has_content && modelResourceValue == "Page">
369 <strong>${modelResourceValue} ${entry.getClassPK()}</strong>
370 </#if>-->
371 </div>
372 </div>
373 <div class="d-flex gap-2 align-items-start justify-content-start flex-wrap">
374 <#if modelResourceValue?has_content && modelResourceValue == "Product">
375 <#assign chanelId = "230564"/>
376 <#assign productCategories = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${chanelId}/products/${entryDocument.cpProductId}/categories?pageSize=40")/>
377 <#assign categories = productCategories.items/>
378 <#if categories?has_content>
379 <#assign topicCount = 0/>
380 <#assign displayedCategories = []/>
381 <#assign totalTopicCount = 0/>
382 <#-- First, count total topic categories -->
383 <#list categories as category>
384 <#if category.vocabulary == 'topic'>
385 <#assign totalTopicCount += 1>
386 </#if>
387 </#list>
388 <#-- Now display first 3 topics -->
389 <#list categories as category>
390 <#if category.vocabulary == 'topic' && topicCount < 3>
391 <#assign taxonomyCategoryId = category.id/>
392 <#assign response = restClient.get("/headless-admin-taxonomy/v1.0/taxonomy-categories/${taxonomyCategoryId}?restrictFields=numberOfTaxonomyCategories,taxonomyCategoryUsageCount,taxonomyCategoryProperties,actions") />
393 <#if response.taxonomyCategoryProperties?has_content>
394 <#assign firstProperty = response.taxonomyCategoryProperties[0] />
395 <#assign categoryValue = firstProperty.value />
396 <span class="tag-pill body-13">${categoryValue}</span>
397 <#else>
398 <span class="tag-pill body-13">${category.name}</span>
399 </#if>
400 <#assign topicCount += 1>
401 </#if>
402 </#list>
403 <#-- If more topics exist, show "+X More..." -->
404 <#if (totalTopicCount - topicCount) gt 0>
405 <span class="tag-pill body-13">+${totalTopicCount - topicCount} More...</span>
406 </#if>
407 </#if>
408 </#if>
409 <!-- For Article -->
410 <#if modelResourceValue?has_content && modelResourceValue == "Web Content Article">
411 <#assign topicList = [] />
412 <#assign structuredContentId = entry.getClassPK() />
413 <#assign contentCategories = restClient.get("/headless-delivery/v1.0/structured-contents/${structuredContentId}") />
414
415 <!-- Collect Topic Categories -->
416 <#list contentCategories.taxonomyCategoryBriefs as category>
417 <#assign taxonomyCategoryId = category.taxonomyCategoryId />
418 <#assign response = restClient.get("/headless-admin-taxonomy/v1.0/taxonomy-categories/${taxonomyCategoryId}?restrictFields=numberOfTaxonomyCategories,taxonomyCategoryUsageCount,taxonomyCategoryProperties,actions") />
419 <#if response.parentTaxonomyVocabulary.name == "Topic">
420 <#assign topicList += [response] />
421 </#if>
422 </#list>
423
424 <!-- Display First 3 and '+X More' -->
425 <#assign topicCount = topicList?size />
426 <#if topicCount gt 3>
427 <#list topicList[0..2] as topic>
428 <span class="tag-pill body-13">${topic.name}</span>
429 </#list>
430 <span class="tag-pill body-13">+${topicCount - 3} More...</span>
431 <#else>
432 <#list topicList as topic>
433 <span class="tag-pill body-13">${topic.name}</span>
434 </#list>
435 </#if>
436 </#if>
437
438 <!-- Ends -->
439 <!-- For Page -->
440 <#if modelResourceValue?has_content && modelResourceValue == "Page">
441<#assign topicList = [] />
442<#assign pageId = entry.getClassPK() />
443<#assign url = "/headless-delivery/v1.0/sites/35333/site-pages?fields=id,taxonomyCategoryBriefs&filter=id%20eq%20%27${pageId}%27" />
444<#assign pageDetails = restClient.get(url) />
445<#if pageDetails?has_content && pageDetails.items?has_content>
446 <#assign items = pageDetails.items />
447 <#if items?has_content>
448 <#list items as item>
449 <#if item.taxonomyCategoryBriefs?has_content>
450 <#list item.taxonomyCategoryBriefs as brief>
451 <#assign taxonomyCategoryId = brief.taxonomyCategoryId />
452 <#assign response = restClient.get("/headless-admin-taxonomy/v1.0/taxonomy-categories/${taxonomyCategoryId}?restrictFields=numberOfTaxonomyCategories,taxonomyCategoryUsageCount,taxonomyCategoryProperties,actions") />
453 <#if response.parentTaxonomyVocabulary.name == "Topic">
454 <#assign topicList += [response] />
455 </#if>
456 </#list>
457 </#if>
458 </#list>
459 </#if>
460 <#else>
461
462 </#if>
463<!-- Display First 3 and '+X More' -->
464<#assign topicCount = topicList?size />
465<#if topicCount gt 3>
466<#list topicList[0..2] as topic>
467 <span class="tag-pill body-13">${topic.name}</span>
468</#list>
469<span class="tag-pill body-13">+${topicCount - 3} More...</span>
470<#else>
471<#list topicList as topic>
472 <span class="tag-pill body-13">${topic.name}</span>
473</#list>
474</#if>
475</#if>
476
477
478 <!-- Ends -->
479 </div>
480 <div>
481 <#if entry.isAssetRendererURLDownloadVisible() && modelResourceValue == "Document">
482 <div class="autofit-col">
483 <span
484 class="c-mt-2 lfr-portal-tooltip"
485 title="${languageUtil.format(locale, 'download-x', ['(' + languageUtil.formatStorageSize(entry.getAssetRendererDownloadSize(), locale) + ')'])}"
486 >
487 <@clay.link
488 aria\-label="${languageUtil.format(locale, 'download-x', [entry.getTitle()])}"
489 cssClass="link-monospaced link-outline link-outline-borderless link-outline-secondary"
490 displayType="secondary"
491 href="${entry.getAssetRendererURLDownload()}"
492 >
493 <@clay.icon symbol="download" />
494 </@clay.link>
495 </span>
496 </div>
497 </#if>
498 </div>
499 </div>
500 </div>
501 </div>
502 </#list>
503 </#if>
504</div>