Failed to get value for key "com.liferay.portal.kernel.workflow.WorkflowConstants"; see cause exception. ---- FTL stack trace ("~" means nesting-related): - Failed at: workflowConstants = staticUtil["com.l... [in template "20100#20136#11660304" at line 12, column 5] ----
1<#assign journalArticleId = .vars['reserved-article-id'].data>
2<#assign journalArticleResourceLocalServiceUtil = staticUtil["com.liferay.journal.service.JournalArticleResourceLocalServiceUtil"]>
3<#assign journalArticleLocalServiceUtil = staticUtil["com.liferay.journal.service.JournalArticleLocalServiceUtil"]>
4<#assign assetCategoryLocalServiceUtil = staticUtil["com.liferay.asset.kernel.service.AssetCategoryLocalServiceUtil"]>
5<#assign assetEntryLocalServiceUtil = staticUtil["com.liferay.asset.kernel.service.AssetEntryLocalServiceUtil"]>
6<#assign PortalUtil = staticUtil["com.liferay.portal.kernel.util.PortalUtil"]>
7<#assign assetEntryQuery = objectUtil("com.liferay.asset.kernel.service.persistence.AssetEntryQuery") />
8<#assign ddmStructureLocalServiceUtil = staticUtil["com.liferay.dynamic.data.mapping.service.DDMStructureLocalServiceUtil"]>
9<#assign localizationUtil = staticUtil["com.liferay.portal.kernel.util.LocalizationUtil"]>
10<#assign
11 serviceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext()
12 workflowConstants = staticUtil["com.liferay.portal.kernel.workflow.WorkflowConstants"]
13 themeDisplay = serviceContext.getThemeDisplay()
14 siteName = themeDisplay.getSiteGroupName()
15 group_id = themeDisplay.getScopeGroupId()
16 groupIdArr = [group_id]
17 portal_url = themeDisplay.getPortalURL()
18 path_context = themeDisplay.getPathContext()
19 journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")
20 DLFileEntryLocalService = serviceLocator.findService("com.liferay.document.library.kernel.service.DLFileEntryLocalService")
21 JournalContentSearchLocalService = serviceLocator.findService("com.liferay.journal.service.JournalContentSearchLocalService")
22 LayoutLocalService = serviceLocator.findService("com.liferay.portal.kernel.service.LayoutLocalService")
23>
24<div style="display:none;">siteName: ${siteName}</div>
25<#assign siteName = themeDisplay.getScopeGroup().getNameCurrentValue()>
26<#assign articleResourcePK = journalArticleResourceLocalServiceUtil.getArticleResourcePrimKey(groupId, journalArticleId)/>
27<#assign parentCategoryList = assetCategoryLocalServiceUtil.getCategories("com.liferay.journal.model.JournalArticle",articleResourcePK) >
28<#assign categoryIdList=[] />
29<#if parentCategoryList?has_content>
30 <#list parentCategoryList as parentCategory>
31 <#assign categoryIdList = categoryIdList + [ parentCategory.getCategoryId()] />
32 </#list>
33</#if>
34
35<#-- UAT
36<#assign structureIdArr=[14139468,78491386] /> -->
37
38<#-- PRoD -->
39<#assign structureIdArr=[19610783,297867049] />
40
41<#assign
42 search = assetEntryQuery.setAnyCategoryIds(categoryIdList)
43 search = assetEntryQuery.setAndOperator(true)
44 search = assetEntryQuery.setGroupIds(groupIdArr)
45 search = assetEntryQuery.setOrderByCol1("modifiedDate")
46 search = assetEntryQuery.setStart(0)
47 search = assetEntryQuery.setEnd(15)
48 search = assetEntryQuery.setClassTypeIds(structureIdArr)
49 search = assetEntryQuery.setOrderByType1("DESC")
50>
51<#assign assetEntryresults = assetEntryLocalServiceUtil.getEntries(assetEntryQuery)>
52
53<#assign displayorder ="Ascending" >
54<#if DisplayOrder?has_content>
55<#assign displayorder = DisplayOrder.getData()>
56</#if>
57<input type="hidden" id="videodisplayorder" name="videodisplayorder" value="${displayorder}">
58
59<section class="layout-videoSeason2TopFold padding-default noPaddingTop" data-populateSeason2="3">
60 <div class="videoSeason2TopFoldWrap">
61 <#list LearnmoreVideos.getSiblings() as cur_BrowseForWebContent>
62 <#assign index_proc = cur_BrowseForWebContent?index>
63 <#if index_proc==0>
64 <div class="eachEpisode">
65 <div class="imgWrap" href="">
66 <div class="lazyWrap">
67 <img class="lazy imgLoaded" src="${cur_BrowseForWebContent.Image1.getData()}" loading="lazy">
68 </div>
69 </div>
70 <div class="grad"></div>
71 <div class="g">
72 <div class="r">
73 <div class="lg-5 lg-offset-1 md-10">
74 <div class="wrap">
75 <div class="tagline">
76 <p class="xxs">
77 <#if parentCategoryList?has_content>
78 <#list parentCategoryList as category>
79 <a class="article-tag" href="/${siteName}/topics.html?topic=${category.getName()}">
80 <strong>${category.getName()}</strong>
81 </a>
82 <#break>
83 </#list>
84 </#if>
85 </p>
86 <div class="dot"></div>
87 <p class="article-read xxs">${cur_BrowseForWebContent.ReadTime.getData()}</p>
88 </div>
89 <h3 class="title matchArticle">
90 ${cur_BrowseForWebContent.Title.getData()}
91 </h3>
92 <#if cur_BrowseForWebContent.SubTitle.getData()??>
93 <p class="strap">${cur_BrowseForWebContent.SubTitle.getData()}</p>
94 </#if>
95 <div class="btnsWrap">
96 <a class="redBtn" data-youtubeplayer="${cur_BrowseForWebContent.YoutubeURLID.getData()}"><span>Play</span></a>
97 </div>
98 </div>
99 </div>
100 </div>
101 </div>
102 </div>
103 </#if>
104 </#list>
105 </div>
106 <div class="g moreNavWrap">
107 <div class="r">
108 <div class="xs-12">
109 <div class="moreNav">
110 <h6 class="active">MORE EPISODES</h6>
111 <h6>EXTRAS</h6>
112 </div>
113 </div>
114 </div>
115 </div>
116
117 <div class="owl-carousel owlMoreEpisode1">
118 <div class="owl-carousel owlmoreEpisode moreEpisodeListing">
119 <#list assetEntryresults as assetEntry>
120 <#assign Title = "">
121 <#assign SubTitle = "">
122 <#assign ReadTime = "">
123 <#assign VideoURL = "">
124 <#assign journalArticleResource=journalArticleResourceLocalServiceUtil.getJournalArticleResource(assetEntry.getClassPK()) />
125 <#assign journalArticle = journalArticleLocalService.getLatestArticle(journalArticleResource.getResourcePrimKey(), workflowConstants.STATUS_APPROVED)
126 article_id = journalArticle.articleId
127 article_content = journalArticleLocalService.getLatestArticle(group_id, article_id)
128 document = saxReaderUtil.read(journalArticle.getContent())
129 rootElement = document.getRootElement()>
130 <#assign layout_Ids = JournalContentSearchLocalService.getLayoutIds(group_id,false,article_id)>
131 <#assign layout_IdsSize = layout_Ids?size>
132
133 <#if layout_IdsSize==1>
134 <#list layout_Ids as layoutid>
135 <#assign
136 layout = LayoutLocalService.getLayout(group_id,false,layoutid)
137 friendlyurl = layout.getFriendlyURL()
138 pageurl = PortalUtil.getLayoutFullURL(layout, themeDisplay)
139 >
140 <#else>
141 <#assign pageurl="" />
142 </#list>
143 <#else>
144 <#assign pageurl="" />
145 </#if>
146 <#-- pageurl: ${pageurl} <br /> -->
147 <#list rootElement.elements() as dynamicElement>
148 <#assign articleResourcePK = journalArticleResourceLocalServiceUtil.getArticleResourcePrimKey(group_id, article_id)/>
149 <#assign categoryList=assetCategoryLocalServiceUtil.getCategories("com.liferay.journal.model.JournalArticle", articleResourcePK) >
150 <#assign imageJson = dynamicElement.valueOf("//dynamic-element[@name='Image1']/dynamic-content/text()")>
151 <#attempt>
152 <#if imageJson?has_content> <#-- for article detail -->
153 <#assign datas_res = imageJson ?eval />
154 <#if datas_res?has_content>
155 <#assign entrys_id = datas_res.fileEntryId />
156 <#if entrys_id?has_content>
157 <#assign fileEntrys = DLFileEntryLocalService.getDLFileEntry(entrys_id?number) />
158 <#if fileEntrys?has_content>
159 <#assign plain_sid = fileEntrys.getUuid() />
160 <#if fileEntrys?has_content>
161 <#assign plus_thub = "/documents/" + group_id+"/"+plain_sid />
162 <#else>
163 <#assign plus_thub = "" />
164 </#if>
165 <#else>
166 <#assign plus_thub = "" />
167 </#if>
168 <#else>
169 <#assign plus_thub = "" />
170 </#if>
171 <#else>
172 <#assign plus_thub = "" />
173 </#if>
174 <#else>
175 <#assign plus_thub = "" />
176 </#if>
177 <#recover>
178
179 </#attempt>
180 <#-- plus_thub: ${plus_thub} -->
181 <#if (dateUtil.compareTo(expiration_date,current_time)>=0)>
182 <#assign Title = dynamicElement.valueOf("//dynamic-element[@name='Title']/dynamic-content/text()")>
183 <#assign SubTitle = dynamicElement.valueOf("//dynamic-element[@name='SubTitle']/dynamic-content/text()")>
184 <#assign ReadTime = dynamicElement.valueOf("//dynamic-element[@name='ReadTime']/dynamic-content/text()")>
185 <#assign VideoURL = dynamicElement.valueOf("//dynamic-element[@name='YoutubeURLID']/dynamic-content/text()")>
186
187 </#if>
188 </#list>
189 <#if pageurl?has_content && plus_thub?has_content && ReadTime?has_content && Title?has_content>
190 <div class="default-articleStyle">
191 <a class="articleImg" href="${pageurl}">
192 <div class="lazyWrap">
193 <img class="lazy imgLoaded" src="${plus_thub}" loading="lazy">
194 </div>
195 </a>
196 <div class="articleTagline">
197 <div class="tagline">
198 <p class="xxs">
199 <#list categoryList as category>
200 <a class="article-tag" href="/${siteName}/sparks/index.html">
201 <strong>${category.getName()}</strong>
202 </a>
203 <#break>
204 </#list>
205 </p>
206 <div class="dot"></div>
207 <p class="xxs">${ReadTime}</p>
208 </div>
209 </div>
210 <h6 class="articleTitle matchArticle">
211 <a href="${pageurl}">${Title}</a>
212 </h6>
213 </div>
214 </#if>
215 </#list>
216
217
218 </div>
219
220 <div class="owl-carousel owlmoreEpisode owlEachVideosRow">
221
222 <#if extraVideosBlock??>
223 <#list extraVideosBlock.getSiblings() as extraVideos>
224 <#if extraVideos.videoImageExtra?? && extraVideos.youtubeURLIDExtra?? >
225 <div class="default-articleStyle">
226 <a class="articleImg isVideo" data-youtubeplayer="${extraVideos.youtubeURLIDExtra.getData()}">
227 <div class="lazyWrap">
228 <img class="lazy imgLoaded" src="${extraVideos.videoImageExtra.getData()}" loading="lazy" />
229 </div>
230 </a>
231 <div class="articleTagline">
232 <div class="tagline">
233 <p class="xxs">
234 <strong>
235 <#if parentCategoryList?has_content>
236 <#list parentCategoryList as category>
237 <a class="article-tag" href="/${siteName}/sparks/index.html">
238 <strong>${category.getName()}</strong>
239 </a>
240 <#break>
241 </#list>
242 </#if>
243 </strong>
244 </p>
245 <div class="dot"></div>
246 <p class="xxs">${extraVideos.readTimeExtra.getData()}</p>
247 </div>
248 </div>
249 <h6 class="articleTitle s matchArticle">
250 <a data-youtubeplayer="${extraVideos.youtubeURLIDExtra.getData()}">${extraVideos.titleExtra.getData()}</a>
251 </h6>
252 </div>
253 </#if>
254 </#list>
255 <#else>
256 <!-- extraVideosBlock is empty-->
257 </#if>
258
259
260 </div>
261 </div>
262
263</section>
264<script>
265
266function removeDuplicates() {
267 const st = new Set();
268 for (const div of document.querySelectorAll('.matchArticle')) {
269 if (st.has(div.textContent.trim())) {
270 div.parentNode.remove();
271 }
272 st.add(div.textContent.trim());
273 }
274}
275removeDuplicates();
276
277$(document).ready(function() {
278
279
280 $('.moreNav h6').click(function(){
281 $('.moreNav h6').removeClass('active');
282 $(this).addClass('active');
283 owlMoreEpisode.trigger('to.owl.carousel', $(this).index())
284 });
285 var owlMoreEpisode = $('.owlMoreEpisode1');
286 $('.moreNav h6').removeClass('active');
287 $('.moreNav h6:first-child').addClass('active');
288 owlMoreEpisode.trigger('to.owl.carousel', 0)
289 owlMoreEpisode.owlCarousel({
290 stagePadding: 0,
291 margin: 25,
292 items: 1,
293 autoHeight: true,
294 touchDrag: false,
295 mouseDrag: false,
296
297 });
298
299 $('.owlEachVideosRow').each(function(index) {
300 owlEachVideosRow = $(this);
301 owlEachVideosRow.owlCarousel({
302 stagePadding: 50,
303 margin: 15,
304 items: 1,
305 loop: false,
306 nav: true,
307 dots: false,
308 dotsEach: false,
309 responsive: {
310 468 : {
311 stagePadding: 80,
312 items: 2
313 },
314 1080 : {
315 stagePadding: 100,
316 items: 4
317 }
318 }
319 });
320 });
321
322 $('.owlmoreEpisode').each(function(index) {
323 owlmoreEpisode = $(this);
324 owlmoreEpisode.owlCarousel({
325 stagePadding: 50,
326 margin: 15,
327 items: 1,
328 loop: false,
329 nav: true,
330 dots: false,
331 dotsEach: false,
332 responsive: {
333 468 : {
334 stagePadding: 80,
335 items: 2
336 },
337 1080 : {
338 stagePadding: 100,
339 items: 4
340 }
341 }
342 });
343 });
344
345
346
347})
348!!localStorage.getItem("livemoreArticleID") ? livemoreArticleIds = JSON.parse(localStorage.getItem("livemoreArticleID")) : null;
349
350if($('#videodisplayorder').val() == 'Ascending'){
351
352 function sortCategory(elementContainer)
353{
354 var allElements = document.body.querySelectorAll(elementContainer);
355 Array.prototype.slice.call(allElements).sort(byAlphabet).forEach(function(div)
356 {
357 div.parentElement.appendChild(div);
358 });
359}
360function byAlphabet(first, second)
361{
362 var order = 0;
363 var first = first.querySelector('.articleTitle a').textContent.trim();
364 var second = second.querySelector('.articleTitle a').textContent.trim();
365 first > second ? order = 1 : order = -1;
366 return order;
367}
368//Call sortCategory function and pass in the container you want sorted
369sortCategory('.moreEpisodeListing .default-articleStyle');
370}else{
371
372 function sortCategory(elementContainer)
373{
374 var allElements = document.body.querySelectorAll(elementContainer);
375 Array.prototype.slice.call(allElements).sort(byAlphabet).forEach(function(div)
376 {
377 div.parentElement.appendChild(div);
378 });
379}
380function byAlphabet(first, second)
381{
382 var order = 0;
383 var first = first.querySelector('.articleTitle a').textContent.trim();
384 var second = second.querySelector('.articleTitle a').textContent.trim();
385 first < second ? order = 1 : order = -1;
386 return order;
387}
388//Call sortCategory function and pass in the container you want sorted
389sortCategory('.moreEpisodeListing .default-articleStyle');
390}
391
392</script>
393<style>
394html.darkTheme .default-articleStyle .articleTitle a{
395color: #E9E9E9;
396}
397.owlmoreEpisodeWrap .owl-nav{
398 display:none !important;
399}
400.moreEpisodeListing .owl-nav{
401 display:block !important;
402}
403 .layout-videoSeason2TopFold {
404 z-index: 1;
405 }
406 .season2-content {
407 margin-left: 100PX !IMPORTANT;
408 padding-left: 20PX;
409 }
410 .portlet-column-only {
411 padding: 0;
412 }
413 .portlet-layout {
414 margin: 0;
415 }
416 #main-content {
417 max-width: unset;
418 padding: 0;
419 }
420 .layout-videoSeason2TopFold .owlmoreEpisode .owl-nav>div:before {
421 background-image: url(/o/gsmc-theme/images/livemore/arrow-r.svg);
422 top:0px !important;
423 }
424 .layout-videoSeason2TopFold .owlmoreEpisode .owl-nav .owl-next:before {
425 top: -10px !important;
426 }
427 .layout-videoSeason2TopFold .owlmoreEpisode .owl-nav{
428 top:42% !important;
429 }
430
431 @media (min-width: 1025px){
432.lg-offset-1 {
433 margin-left: 8.33333333% !important;
434}
435}
436@media (max-width: 1279px){
437.layout-videoSeason2TopFold .owlmoreEpisode .owl-stage{
438 left: 0;
439}
440}
441
442.at-expanding-share-button.at-expanding-share-button-mobile+.at-expanding-share-button-mobile-overlay{
443 display:none !important;
444}
445.default-articleStyle .articleImg.isVideo:before, .default-articleStyle .articleImg.isAudio:before{
446 background-image:url(/o/gsmc-theme/images/livemore/playIcon.png);
447}
448 /*.layout-videoSeason2TopFold .owlmoreEpisode .owl-nav>div:before {
449 background-image: url(/o/gsmc-theme/images/${siteName}/arrow-r.svg);
450 }*/
451
452</style>

LIVE: Thought for Food
Aprons on and green thumbs out... Host Rozz puts comedy peeps Munah and Haresh (Ministry of Funny) to a test in this FB livestream! Find out who proved more future-ready when it came to reducing food waste and living sustainably.
WATCH NOW
Food and access to food
It’s been a reflective time for each of us. And while our individual takeaways are different, there is one global problem which affects us all – and that is food and access to food.
LEARN MORE

Quick facts about food waste
1/3
of all food produced in world
is wasted or lost
This can feed
1/2
the world’s population
Yet,
1/4
suffer from malnutrition
During these difficult times, some of us sought comfort in food, others struggled to fill their plates, even as produce was mounting on farms whose supply chains were suddenly severed.
Yet, despite the necessary lock-downs and challenges, we witnessed so many continue fighting the good fight. This episode is inspired by all the social enterprises & NGOs that DBS works with to conserve and redistribute food waste.
You can be a change-maker
If we each take small steps every day, we can collectively create waves of change. Will you take a small step today?

Gardening with Edibles
Part of creating greater access to food is getting our hands dirty and growing what we eat!
Not only will this healthy hobby yield you and your family fresh veggies for breakfast, lunch and dinner, it’ll also help us all better appreciate food production and raise our awareness of unnecessary waste.
As founding partner of NParks’#GardeningwithEdiblesSG initiative, where households can receive free seeds to grown their own vegetables at home, DBS hopes to get everyone engaged with nature while building social bonds and greening the nation.
If you’re on your way to becoming an urban farmer, share with us on Facebook or Instagram a quick tip about growing your own food! Do remember to tag us in your stories and posts with the hashtag #DBSGrows.
LEARN MORE
Stronger Together
The COVID-19 pandemic also exacerbated the need for food and daily essentials among hard-hit communities in the region.
DBS set up the SGD 10.5 million DBS Stronger Together Fund to help the region. With this fund, we will provide about 4.5 million meals and care packs to those affected, as well as the procurement of diagnostic test kits, personal protective equipment and other medical supplies to help in the fight against Covid-19.


Did you know?
When international travel came to a standstill due to Covid-19, Regional Head of Marketing for DBS Asia Treasures, Adele Tan, found an opportunity to help both the limo drivers who no longer had airport transfers to make, and the beneficiaries of the DBS Stronger Together Fund.
Her efforts to ensure the drivers still had meaningful work in supporting the DBS Stronger Together fund with food deliveries also inspired an important plot point in this episode of Sparks: A Call to Action. Watch out for it!
Meet the #EverydayHeroes working with food
Check out some of our social enterprises and show them a little love and support!










