An error occurred while processing the template.
The following has evaluated to null or missing:
==> rootElement.selectSingleNode("//dynamic-element[@field-reference='${fieldName}']/dynamic-content")  [in template "20116#20152#608821196" at line 82, column 41]

----
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 node = rootElement.selectSing...  [in template "20116#20152#608821196" in function "getFieldValue" at line 82, column 25]
----
1<#assign serviceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext()> 
2<#assign themeDisplay = serviceContext.getThemeDisplay() /> 
3<#assign layout = themeDisplay['plid'] /> 
4<#assign layoutService = serviceLocator.findService("com.liferay.portal.kernel.service.LayoutLocalService")> 
5<#assign layoutObject = layoutService.getLayout(layout?number) /> 
6<#assign page_group = layoutObject.getGroup() /> 
7<#assign site_title = page_group.getDescriptiveName() /> 
8 
9	 
10	<style> 
11	.imgThumbnail{ 
12		max-width: 300px; 
13		height: auto; 
14
15	<#-- 
16	CDPHP Style for CDPHP News Articles (Can be removed after Theme Modification )  
17	--> 
18   .cdphp .theme .banner-image__heading { 
19		    line-height: 1.2; 
20
21		.cdphp .theme .card { 
22    border-top-color: rgba(0, 0, 0, 0.125); 
23    border-radius: 4px; 
24    border-width: 0.0625rem; 
25
26	 .cdphp .theme .card a { 
27        font-size: 2rem; 
28
29	  .cdphp .theme .bg-secondary { 
30    background-color: #f0ebd8 !important; 
31
32	</style> 
33	 
34<div class="row search-filter-browse__form bg-white"> 
35	<#if site_title?contains("Excellus")> 
36	    <h2>Select by Category</h2> 
37	    <div class="col-12 mb-4"> 
38			<div class="d-flex flex-column flex-md-row justify-content-around"> 
39				<button class="btn btn-secondary mx-auto mb-2 w-50 filter-btn" data-filter="Affordability">Affordability</button> 
40				<button class="btn btn-secondary mx-auto ml-sm-1 mb-2 w-50 filter-btn" data-filter="Community Impact">Community Impact</button> 
41				<button class="btn btn-secondary mx-auto ml-sm-1 mb-2 w-50 filter-btn" data-filter="Company News">Company News</button> 
42				<button class="btn btn-secondary mx-auto ml-sm-1 mb-2 w-50 filter-btn" data-filter="Working Here">Working Here</button> 
43				<button class="btn btn-secondary mx-auto ml-sm-1 mb-2 w-50 filter-btn" data-filter="Your Health">Your Health</button> 
44				<button class="btn btn-primary order-5 mx-auto ml-sm-1 mb-2 w-50" id="resetBtn">Reset</button> 
45			</div> 
46		</div> 
47	</#if> 
48	<div class="col-12 mb-3"> 
49		<input  
50			type="text"  
51			id="searchInput"  
52			class="form-control"  
53			placeholder="Search articles..." 
54		/> 
55	</div> 
56	<div class="col-12 mb-4"> 
57		<select id="dateFilter" class="form-control mx-auto"> 
58			<option value="">All Dates</option> 
59			<option value="1m">Last Month</option> 
60			<option value="3m">Last 3 Months</option> 
61			<option value="6m">Last 6 Months</option> 
62			<option value="cy">Current Year</option> 
63			<option value="py">Prior Year</option> 
64		</select> 
65	</div> 
66</div> 
67<div class="row mt-4"> 
68	<div class="news-count" id="newsCount"> 
69		Showing ${entries?size} article(s) 
70	</div> 
71 
72	<#list entries as entry> 
73 
74		<#assign assetRenderer = entry.getAssetRenderer() /> 
75		<#assign journalArticle = assetRenderer.getArticle() /> 
76 
77		<#assign document = saxReaderUtil.read(journalArticle.getContentByLocale(locale)) /> 
78		<#assign rootElement = document.getRootElement() /> 
79 
80		<#-- Field helper --> 
81		<#function getFieldValue fieldName> 
82			<#assign node = rootElement.selectSingleNode("//dynamic-element[@field-reference='${fieldName}']/dynamic-content") /> 
83			<#if node??> 
84				<#return node.getText() /> 
85			</#if> 
86			<#return "" /> 
87		</#function> 
88 
89		<#function getImageURL fieldName> 
90			<#assign jsonString = getFieldValue(fieldName) /> 
91 
92			<#if jsonString?has_content> 
93				<#assign imgJSON = jsonFactoryUtil.createJSONObject(jsonString) /> 
94 
95				<#assign uuid = imgJSON.getString("uuid") /> 
96				<#assign groupId = imgJSON.getString("groupId") /> 
97 
98				<#if uuid?has_content && groupId?has_content> 
99					<#return themeDisplay.getPortalURL() + "/documents/" + groupId + "/" + uuid /> 
100				</#if> 
101			</#if> 
102 
103			<#return "" /> 
104		</#function> 
105 
106		<#-- Get values --> 
107		<#assign headline = getFieldValue("Headline") /> 
108		<#assign subheadline = getFieldValue("Subheadline") /> 
109		<#assign body = getFieldValue("Body") /> 
110		<#assign dateline = getFieldValue("Dateline")?date.iso?string("MMMM d, yyyy")!"" /> 
111		<#assign imageURL = getImageURL("thumbnailImage") /> 
112			 <#assign imgAlt = getFieldValue("thumbnailAlt")!""> 
113 
114		<#assign categories = entry.getCategories() /> 
115		<#assign categoryTitles = [] /> 
116 
117		<#list categories as cat> 
118			<#assign categoryTitles = categoryTitles + [cat.getTitle(locale)] /> 
119		</#list> 
120 
121 
122 
123		<div class="news-card w-100 mb-4 border p-3" 
124			data-categories="${categoryTitles?join(',')}" 
125			data-headline="${headline?lower_case}" 
126			data-body="${htmlUtil.stripHtml(body)?lower_case}" 
127			data-date="${dateline}" 
128			style="width:100%; margin-bottom:24px; border:1px solid #ddd; padding:16px;"> 
129 
130 
131			<div class="card-content" style="display:flex;"> 
132 
133				<#-- Thumbnail (always reserve space) --> 
134				<div class="media my-auto mx-3"> 
135					<#if imageURL?has_content> 
136						<img src="${imageURL}" class="mr-2 imgThumbnail d-none d-md-block" alt="${imgAlt}"/> 
137 
138					</#if> 
139				</div> 
140 
141				<div class="card-body media-body px-auto py-auto px-md-3 py-md-4"> 
142 
143					<#-- Headline + Dateline row --> 
144					<div> 
145						 
146						<#assign articleId = journalArticle.getArticleId() /> 
147						<#assign classPK = entry.getClassPK() /> 
148 
149						<#assign articleURL = "/news/article?articleId=" + articleId + "&classPK=" + classPK /> 
150 
151						<#if headline?has_content> 
152							<h2 class="my-0"> 
153								<a href="${articleURL}"> 
154									${headline} 
155								</a> 
156							</h2> 
157						</#if> 
158 
159					</div> 
160 
161					<#-- Subheadline --> 
162					<#if subheadline?has_content> 
163						<p class="text-muted">${subheadline} | ${dateline}</p> 
164															<#else>     
165																<p class="text-muted">${dateline}</p> 
166                                </#if> 
167 
168					<#-- Body excerpt --> 
169					<#if body?has_content> 
170						<div style="margin-top:12px;"> 
171							<#assign cleanBody = htmlUtil.stripHtml(body) /> 
172 
173							<#if cleanBody?length <= 250> 
174								${cleanBody} 
175							<#else> 
176								<#assign cut = cleanBody?substring(0, 250) /> 
177								<#assign lastSpace = cut?last_index_of(" ") /> 
178 
179								<#if lastSpace != -1> 
180									${cut?substring(0, lastSpace)}... 
181								<#else> 
182									${cut}... 
183								</#if> 
184							</#if> 
185						</div> 
186					</#if> 
187 
188					<#-- Categories to exclude --> 
189					<#assign excludedCategories = [ 
190						"Excellus", 
191						"Univera", 
192						"CDPHP" 
193					] /> 
194 
195 
196					<#-- Categories as Bootstrap badges --> 
197					<div class="categories mt-3"> 
198 
199						<#assign categories = entry.getCategories() /> 
200 
201						<#list categories as cat> 
202							<#assign catTitle = cat.getTitle(locale) /> 
203 
204							<#-- Skip excluded categories --> 
205							<#if !excludedCategories?seq_contains(catTitle)> 
206								<span class="badge badge-secondary p-2 mt-3"> 
207									${catTitle} 
208								</span> 
209							</#if> 
210						</#list> 
211 
212					</div> 
213 
214				</div> 
215 
216			</div> 
217 
218		</div> 
219 
220	</#list> 
221</div> 
222<div class="flex-container no-results" style="display:none;"> 
223	<div class="flex-item-center m-auto"> 
224		<p><strong>No records found</strong> Try a new search term, or reset your search.</p> 
225		<p><strong>Suggestions:</strong></p> 
226		<ul> 
227			<li>Make sure all words are spelled correctly</li> 
228			<li>Try different keywords</li> 
229			<li>Try more generic keywords</li> 
230			<li>Try fewer keywords</li> 
231		</ul> 
232	</div> 
233</div> 
234 
235<script> 
236	document.addEventListener("DOMContentLoaded", function () { 
237 
238		const buttons = document.querySelectorAll(".filter-btn"); 
239		const cards = document.querySelectorAll(".news-card"); 
240		const resetBtn = document.getElementById("resetBtn"); 
241		const dateDropdown = document.getElementById("dateFilter"); 
242		let activeDateFilter = null; 
243		const countEl = document.getElementById("newsCount"); 
244		const searchInput = document.getElementById("searchInput"); 
245		const noResults = document.querySelector(".no-results"); 
246 
247		let activeFilter = null; 
248 
249		function updateCount() { 
250			let visibleCount = 0; 
251 
252			cards.forEach(card => { 
253				if (card.style.display !== "none") { 
254					visibleCount++; 
255
256			}); 
257 
258			countEl.textContent = "Showing " + visibleCount + " article(s)"; 
259 
260			// Toggle "no results" 
261			if (visibleCount === 0) { 
262				noResults.style.display = "flex"; 
263			} else { 
264				noResults.style.display = "none"; 
265
266
267 
268		function applyFilters() { 
269			const searchTerm = (searchInput.value || "").toLowerCase(); 
270 
271			cards.forEach(card => { 
272				const categories = card.getAttribute("data-categories") || ""; 
273				const headline = card.getAttribute("data-headline") || ""; 
274				const body = card.getAttribute("data-body") || ""; 
275				const date = card.getAttribute("data-date"); 
276 
277				let matchesCategory = true; 
278				let matchesSearch = true; 
279				let matchesDate = true; 
280 
281				if (activeFilter) { 
282					matchesCategory = categories.includes(activeFilter); 
283
284 
285				if (searchTerm) { 
286					matchesSearch = 
287						headline.includes(searchTerm) || 
288						body.includes(searchTerm); 
289
290 
291				if (activeDateFilter) { 
292					matchesDate = isWithinRange(date, activeDateFilter); 
293
294 
295				if (matchesCategory && matchesSearch && matchesDate) { 
296					card.style.display = "block"; 
297				} else { 
298					card.style.display = "none"; 
299
300			}); 
301 
302			updateCount(); 
303
304 
305		// Category buttons 
306		buttons.forEach(button => { 
307			button.addEventListener("click", function () { 
308				activeFilter = this.getAttribute("data-filter"); 
309 
310				buttons.forEach(btn => btn.classList.remove("active")); 
311				this.classList.add("active"); 
312 
313				applyFilters(); 
314			}); 
315		}); 
316 
317		// Search typing (live) 
318		searchInput.addEventListener("input", function () { 
319			applyFilters(); 
320		}); 
321 
322		//Date Filter Event Listener 
323		dateDropdown.addEventListener("change", function () { 
324			activeDateFilter = this.value || null; 
325			applyFilters(); 
326		}); 
327 
328		//Date filtering 
329		function isWithinRange(articleDateStr, range) { 
330			if (!articleDateStr) return false; 
331 
332			const articleDate = new Date(articleDateStr); 
333			const now = new Date(); 
334 
335			let startDate = null; 
336			let endDate = new Date(now); 
337 
338			switch (range) { 
339				case "1m": 
340					startDate = new Date(); 
341					startDate.setMonth(now.getMonth() - 1); 
342					break; 
343 
344				case "3m": 
345					startDate = new Date(); 
346					startDate.setMonth(now.getMonth() - 3); 
347					break; 
348 
349				case "6m": 
350					startDate = new Date(); 
351					startDate.setMonth(now.getMonth() - 6); 
352					break; 
353 
354				case "cy": 
355					startDate = new Date(now.getFullYear(), 0, 1); 
356					endDate = new Date(now.getFullYear(), 11, 31); 
357					break; 
358 
359				case "py": 
360					startDate = new Date(now.getFullYear() - 1, 0, 1); 
361					endDate = new Date(now.getFullYear() - 1, 11, 31); 
362					break; 
363
364 
365			return articleDate >= startDate && articleDate <= endDate; 
366
367 
368		//Reset the page 
369		resetBtn.addEventListener("click", function () { 
370			window.location.reload(); 
371		}); 
372 
373	}); 
374</script> 

 

GDPR Notification Content