null Rakas lähiö: Mediapersoona Seksikäs-Suklaalle Roihuvuori on paikka, jossa voi jutella kenelle vaan

Virhe tapahtui prosessoidessa esitysmallia.
The following has evaluated to null or missing:
==> slot.videoFile  [in template "20116#20160#45930" at line 918, column 42]

----
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: #assign videoFile = slot.videoFile.ge...  [in template "20116#20160#45930" in macro "printRemainingVideoContents" at line 918, column 21]
	- Reached through: @printRemainingVideoContents articleV...  [in template "20116#20160#45930" at line 379, column 9]
----
1<#----------------------------------------------------------------------------- 
2    INIT (Single article template) 
3------------------------------------------------------------------------------> 
4<#setting time_zone="Europe/Helsinki"> 
5<#assign serviceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext()> 
6<#assign themeDisplay = serviceContext.getThemeDisplay() /> 
7<#assign javascript_folder = "/o/kirkkojakaupunki-site-theme/js" > 
8 
9 
10<#assign JournalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")> 
11<#assign articleContentService = serviceLocator.findService("com.ch5finland.helsinginseurakuntayhtyma.kirkkojakaupunki.article.content.service.ArticleContentService")> 
12 
13<#assign currentArticle = JournalArticleLocalService.getArticle(groupId, .vars['reserved-article-id'].data) /> 
14<#setting url_escaping_charset="UTF-8"> 
15 
16<#-- 
17    Kirkkojakaupunki-site-theme-blank is used pages that are meant for mobile app  
18    Figure out if article is shown on mobile app based on theme id  
19     
20    It is also possible to show article with default kirkkojakaupunki-site-theme when request comes 
21    from mobile app. We can check this with x-prenly-client-type header 
22--> 
23<#assign mobileAppView = themeDisplay.getThemeId()?contains("kirkkojakaupunkisitethemeblank") ||  
24                         request.getHeader('x-prenly-client-type')?? && request.getHeader('x-prenly-client-type')?has_content 
25
26 
27 
28<#-- Helper variables --> 
29<#assign includeOwlScript = false> 
30 
31<#assign previewMode = false > 
32<#-- Check if article is viewed in preview mode --> 
33 
34<#if themeDisplay.getURLCurrent()?contains("preview_article_content.jsp") > 
35    <#-- this aplies if preview is selected via folder/list view. Site css is included  --> 
36    <#assign previewMode = true > 
37</#if> 
38<#if themeDisplay.getURLCurrent()?contains("preview_article_content_template.jsp") > 
39    <#-- this aplies if preview is selected via article edit. Site css is not included for some reason so here is little hack --> 
40    <#assign previewMode = true > 
41    <link rel="stylesheet" type="text/css"  href="/o/kirkkojakaupunki-site-theme/css/main.css" /> 
42    <script>$.getScript("/o/kirkkojakaupunki-site-theme/js/main.js");</script> 
43</#if> 
44 
45<#-- 
46    Counters for keeping track of now many elements 
47    have been placed with a tag. 
48--> 
49<#global tagReplaceCounter = 0 /> 
50<#assign kainaloTagCounter = 0 /> 
51<#assign infoTagCounter = 0 /> 
52<#assign faktaTagCounter = 0 /> 
53<#assign quoteTagCounter = 0 /> 
54<#assign videoTagCounter = 0 /> 
55<#assign audioTagCounter = 0 /> 
56<#assign imageComparisonTagCounter = 0 /> 
57 
58<#-- Article ID --> 
59<#assign articleId = .vars['reserved-article-id'].data> 
60<#assign articleCategories = getCategoryNames(articleId)> 
61 
62 
63<#-- Article --> 
64<#assign article = JournalArticleLocalService.getArticle(groupId, articleId) /> 
65 
66<#-- Article complete URL --> 
67<#assign urlTitle = article.urlTitle?trim /> 
68<#assign articleCompleteUrl = themeDisplay.getPortalURL() + "/-/" + urlTitle /> 
69 
70<#-- available author names : Those authors which have author card --> 
71<#assign authorCardFolderIds = [140767, 140764] /> <#-- Toimittjat, Kolumnistit --> 
72<#assign availableAuthorNames = getAvailableAuthorNames(authorCardFolderIds) /> 
73<#assign authorCardBaseUrl = "/toimittajat?author=" /> 
74 
75<#-- Article title --> 
76<#assign title = .vars['reserved-article-title'].data> 
77 
78<#-- Article lead --> 
79<#assign lead = .vars['reserved-article-description'].data> 
80 
81<#-- Get and format article publish date --> 
82<#assign displayDate = .vars['reserved-article-display-date'].data> 
83 
84    <#-- Save the original page locale for later --> 
85    <#assign originalLocale = locale> 
86 
87    <#-- Set the page locale to the portals default locale --> 
88    <#setting locale = localeUtil.getDefault()> 
89 
90    <#-- Parse the date to a date object --> 
91    <#assign displayDate = displayDate?datetime("EEE, d MMM yyyy HH:mm:ss Z")> 
92 
93    <#-- Set the page locale back to the original page locale --> 
94    <#assign locale = originalLocale> 
95 
96 
97<#-- Article body tags --> 
98<#assign tagKainalo = "[[kainalo]]"> 
99<#assign tagInfo = "[[info]]"> 
100<#assign tagFakta = "[[fakta]]"> 
101<#assign tagQuote = "[[sitaatti]]"> 
102<#assign tagImage = "[[kuva]]"> 
103<#assign tagVideo = "[[video]]"> 
104<#assign tagAudio = "[[audio]]"> 
105<#assign tagCarousel = "[[kuvakaruselli#]]"> <#-- # will be replaced with carousel number --> 
106<#assign tagImageComparison = "[[vaihtokuva]]"> 
107<#assign tagEmbeddedHTML = "[[upotus]]"> 
108 
109<#-- lisäksi käytössä  
110  [[mainos]] 
111  [[eimainosta]] 
112--> 
113 
114<#-- wrapper css classes --> 
115<#assign wrapperCSSKainalo = "article-section article-tail"> 
116<#assign wrapperCSSInfo = "article-box article-info"> 
117<#assign wrapperCSSFakta = "article-box article-fact"> 
118<#assign wrapperCSSQuote = "template-quote"> <#-- should not be changes. It is used in switch --> 
119 
120<#-- Article tags --> 
121<#assign articleTags = .vars['reserved-article-asset-tag-names'].data> 
122 
123<#-- Article raw body --> 
124<#assign articleBody = articleBody.getData()> 
125 
126<#-- Ad :  
127 https://tiketti.ch5.fi/issues/24425 
128  
129    Lähtökohta: Artikkelin sisäinen mainos näkyy aina neljän leipätekstin <p>-tagin jälkeen. 
130    Tarvittaessa artikkelin muokkaaja voi muuttaa mainoksen näyttöpaikkaa [[mainos]]-tagilla 
131    Tarvittaessa artikkelin muokkaaja voi estää mainoksen näkemisen yksittäisessä artikkelissa [[eimainosta]]-tagilla. 
132    Mainos ei näy ”erikoisartikkeleissa” eikä ”kuva-artikkeleissa”, ainoastaan ”Koko artikkeleissa”. 
133    Artikkelin sisäinen mainos ei näy koskaan artikkeleissa, joissa on tägi ”pääkirjoitus” tai ”hyvää pyhää” tai joiden leipäteksti on hyvin lyhyt (pituus alle 8 <p>) 
134    Mainos näytetään kaikissa palvelun vanhoissa artikkeleissa edellä mainituin rajoituksin. 
135    Artikkelin sisäisiä mainospaikkoja voidaan tehdä montakin, mutta ehkä lähdetään yhdellä liikkeelle… 
136    Pyritään testaamaan artikkelin sisäisen mainospaikan toimivuus kehitysympäristössä. 
137 
138     
139    --> 
140<#assign insertAdAfterNthParagraph = 4 /> 
141<#assign insertAdIfContainsMoreThanParagraphs = 8 /> 
142<#assign tagPreventsShowingAd = articleTags?contains("pääkirjoitus") || articleTags?contains("hyvää pyhää") /> 
143 
144<#if !articleBody?contains("[[eimainosta]]") && !tagPreventsShowingAd> 
145 
146    <#if !articleBody?contains("[[mainos]]")> 
147        <#-- no ad tag so inject --> 
148        <#assign articleBody = articleContentService.injectAdMarker(articleBody, insertAdAfterNthParagraph, insertAdIfContainsMoreThanParagraphs) /> 
149    </#if> 
150    <#assign articleBody = replaceAdTag(articleBody) /> 
151<#else> 
152 
153    <#-- Clean [[eimainosta]] and possible [[mainos]] tags -->  
154     
155    <#assign articleBody = articleBody?replace("<p>[[eimainosta]]</p>", "") /> 
156    <#assign articleBody = articleBody?replace("[[eimainosta]]", "") /> 
157    <#assign articleBody = articleBody?replace("<p>[[mainos]]</p>", "") /> 
158    <#assign articleBody = articleBody?replace("[[mainos]]", "") />     
159</#if> 
160 
161<#-- // END OF AD stuff --> 
162 
163<#if articleTail?has_content> 
164    <#assign articleBody = replaceTags(articleBody, tagKainalo, articleTail, wrapperCSSKainalo)> 
165    <#assign kainaloTagCounter = tagReplaceCounter /> 
166</#if> 
167<#if articleInfo?has_content> 
168    <#assign articleBody = replaceTags(articleBody, tagInfo, articleInfo, wrapperCSSInfo)> 
169    <#assign infoTagCounter = tagReplaceCounter /> 
170</#if> 
171<#if articleFacts?has_content> 
172    <#assign articleBody = replaceTags(articleBody, tagFakta, articleFacts, wrapperCSSFakta)> 
173    <#assign faktaTagCounter = tagReplaceCounter /> 
174</#if> 
175<#if articleQuotes?has_content> 
176    <#assign articleBody = replaceTags(articleBody, tagQuote, articleQuotes, wrapperCSSQuote)> 
177    <#assign quoteTagCounter = tagReplaceCounter /> 
178</#if> 
179<#if articleEmbeddedHTML?has_content> 
180    <#assign articleBody = replaceTags(articleBody, tagEmbeddedHTML, articleEmbeddedHTML, 'no-wrapper')> 
181</#if> 
182<#if articleImages?has_content> 
183    <#assign articleBody = replaceImageTags(articleBody, tagImage, articleImages)> 
184    <#assign articleBody = replaceCarouselTags(articleBody, tagCarousel, articleImages)> 
185</#if> 
186<#if articleVideos?has_content> 
187    <#assign articleBody = replaceVideoTags(articleBody, tagVideo, articleVideos)> 
188    <#assign videoTagCounter = tagReplaceCounter /> 
189</#if> 
190<#if articleAudio?has_content> 
191    <#assign articleBody = replaceAudioTags(articleBody, tagAudio, articleAudio)> 
192    <#assign audioTagCounter = tagReplaceCounter /> 
193</#if> 
194<#if imageComparisons?has_content> 
195    <#assign articleBody = replaceImageComparisonTags(articleBody, tagImageComparison, imageComparisons)> 
196</#if> 
197 
198<#-- 25209 - iframe is wrapped inside p-tags and for that reason gets extra text-indent. Replace p-tags. -->  
199<#assign articleBody = articleBody?replace("<p><iframe", "<iframe")?replace("</iframe></p>", "</iframe>") > 
200<#assign articleBody = cleanSpecialChars(articleBody) > 
201 
202<#----------------------------------------------------------------------------- 
203    OUTPUT ARTICLE 
204------------------------------------------------------------------------------> 
205 
206<#if previewMode> 
207    <script> 
208            inPreviewMode = true; 
209            var iframeContainer = jQuery('.modal-body-iframe', window.parent.document).parent().parent(); 
210            jQuery(iframeContainer).addClass("custom-preview-dialog"); 
211            jQuery(iframeContainer).css("width", "940px"); 
212            jQuery(iframeContainer).css("margin", "auto"); 
213            jQuery(iframeContainer).find("iframe").css("width", "900px"); 
214            jQuery('body', window.parent.document).addClass("custom-in-preview-mode"); 
215    </script> 
216</#if> 
217 
218<article class="voice-intuitive"> 
219     
220    <#-- Show article url in preview mode --> 
221    <#if previewMode?? && previewMode> 
222	    <div><span>${articleCompleteUrl}</span></div> 
223    </#if> 
224 
225    <#-- Article image(s) --> 
226 
227    <#if articleImages?has_content> 
228        <#assign headerImages = getHeaderImages(articleImages) > 
229        <#assign contentCarouselImages = getContentCarouselImages(articleImages) > 
230    </#if> 
231 
232    <#if contentCarouselImages?has_content> 
233        <#if (contentCarouselImages?size > 1) > 
234            <#assign includeOwlScript = true> 
235        </#if> 
236    </#if> 
237     
238     
239 
240    <#if headerImages?has_content> 
241 
242        <#-- Container with bottom margin --> 
243        <div class="article-header-img"> 
244 
245 
246 
247            <#-- More than one image > create owl-carousel --> 
248            <#if (headerImages?size > 1) > 
249 
250                    <#list headerImages as image> 
251 
252            		    <#if image.getData()?? && image.getData()?has_content> 
253 
254                            <#-- Open carousel container on first image --> 
255                            <#if image?is_first> 
256                                <div class="owl-carousel owl-theme"> 
257 
258                                <#-- Load carousel script at the end of display template --> 
259                                <#assign includeOwlScript = true> 
260                            </#if> 
261 
262                            <#-- Output carousel slides --> 
263                            <div class="item"> 
264                                <#if image.getAttribute("alt")?has_content> 
265                                    <div class="aspect-ratio aspect-ratio-middle aspect-ratio-xs"> 
266                                        <img  class="aspect-ratio-item-fluid" src="${getImageURLByTemplateModel(image, '1200')}" alt="${image.getAttribute("alt")}" /> 
267                                    </div> 
268                                    <span class="caption voice-no-read">${image.getAttribute("alt")}</span> 
269                                <#else> 
270                                    <div class="aspect-ratio aspect-ratio-middle aspect-ratio-xs"> 
271                                        <img class="aspect-ratio-item-fluid" src="${getImageURLByTemplateModel(image, '1200')}" alt="" /> 
272                                    </div> 
273                                </#if> 
274                            </div> 
275 
276                            <#-- Close carousel contaner after last item --> 
277                            <#if image?is_last> 
278                                </div> <#-- div.owl-carousel --> 
279                            </#if> 
280 
281            		    </#if> 
282            	    </#list> 
283 
284            <#else> 
285 
286            <#-- Display a single image without carousel --> 
287            <#list headerImages as image> 
288 
289    		    <#if image.getData()?? && image.getData()?has_content> 
290 
291                    <#-- <@adaptive_media_image["img"] fileVersion=dlAppServiceUtil.getFileEntry(.getFileVersion())/>  --> 
292         
293                    <#if image.getAttribute("alt")?has_content> 
294            	        <img  
295                            src="${getImageURLByTemplateModel(image, '1200')}"  
296                            alt="${image.getAttribute("alt")}" /> 
297                             
298                        <p class="caption voice-no-read">${image.getAttribute("alt")}</p> 
299                    <#else> 
300            	        <img  
301                            src="${getImageURLByTemplateModel(image, '1200')}" alt="" /> 
302                   </#if> 
303    		    </#if> 
304    	    </#list> 
305 
306            </#if> 
307 
308        </div> <#-- div.article-header-img --> 
309 
310    </#if> 
311 
312    <#if articleCategories?has_content> 
313        <div class="voice-no-read"> 
314            <#list articleCategories as cat> 
315                <span data-cat="${cat?lower_case}" class="category-item">${cat}</span> 
316            </#list> 
317        </div> 
318    </#if> 
319 
320    <h1>${title}</h1> 
321 
322    <#if lead?? && lead?has_content> 
323        <#-- Remove possible HTML-tags --> 
324        <#assign leadCleaned = htmlUtil.stripHtml(lead) /> 
325        <p class="lead">${leadCleaned}</p> 
326    </#if> 
327 
328    <ul class="list-inline article-meta voice-no-read""> 
329        <li class="list-inline-item"><span class="date">${displayDate?string["dd.MM.yyyy HH:mm"]}</span></li> 
330 
331        <#if articleAuthors.authors.getData()?? && articleAuthors.authors.getData()?has_content> 
332            <#assign articleAuthor = articleAuthors.authors.getData()> 
333            <li class="list-inline-item"> 
334                <span class="author authortext-no-margin author-text"></span> 
335                <span class="author author-name"> 
336                    <#if mobileAppView> 
337                        ${articleAuthor} 
338                    <#else> 
339                        ${makeAuthorLinks(articleAuthor,availableAuthorNames, authorCardBaseUrl)} 
340                    </#if> 
341                </span> 
342            </li> 
343        </#if> 
344 
345        <#if articleAuthors.photographers.getData()?? && articleAuthors.photographers.getData()?has_content> 
346            <li class="list-inline-item"> 
347                <span class="author author-name author-photo"> 
348                    <#if mobileAppView> 
349                        ${articleAuthors.photographers.getData()} 
350                    <#else> 
351                        ${makeAuthorLinks(articleAuthors.photographers.getData(),availableAuthorNames, authorCardBaseUrl)} 
352                    </#if> 
353                </span> 
354            </li> 
355        </#if> 
356    </ul> 
357 
358    <div id="voice-intuitive-root"></div> 
359     
360    ${articleBody} 
361 
362    <#-- Output article quotes --> 
363    <#if articleQuotes?has_content && articleQuotes.getSiblings()?has_content> 
364    <@printRemainingTagContents articleQuotes quoteTagCounter wrapperCSSQuote /> 
365    </#if> 
366 
367    <#-- Print article factbox(es) --> 
368    <#if articleFacts?has_content && articleFacts.getSiblings()?has_content> 
369        <@printRemainingTagContents articleFacts faktaTagCounter wrapperCSSFakta /> 
370    </#if> 
371 
372    <#-- Print article infobox(es) --> 
373    <#if articleInfo?has_content && articleInfo.getSiblings()?has_content> 
374        <@printRemainingTagContents articleInfo infoTagCounter wrapperCSSInfo/> 
375    </#if> 
376 
377    <#-- Print article video(s) --> 
378    <#if articleVideos?has_content && articleVideos.getSiblings()?has_content> 
379        <@printRemainingVideoContents articleVideos videoTagCounter  /> 
380    </#if> 
381 
382    <#-- Print remaining audio embeds --> 
383    <#if articleAudio?has_content && articleAudio.getSiblings()?has_content> 
384        <@printRemainingAudioContents articleAudio audioTagCounter  /> 
385    </#if> 
386     
387    <#-- Print article tail(s) --> 
388    <#if articleTail?has_content && articleTail.getSiblings()?has_content> 
389        <@printRemainingTagContents articleTail kainaloTagCounter wrapperCSSKainalo /> 
390    </#if> 
391 
392     
393    <div class="voice-no-read">  
394 
395     
396    <#--  NEWSLETTER SUBSCRIPTION BANNER  --> 
397    <@printNewsletterAd articleTags /> 
398 
399     <#-- R&S sharing buttons --> 
400        <div class="article-sharing"> 
401            <p class="sans text-uppercase">Jaa t&auml;m&auml; artikkeli:</p> 
402            <div class="rns-share-plugin"></div> 
403        </div> 
404         
405<#if !mobileAppView>         
406    <#-- City --> 
407        <#if articleTags?has_content> 
408 
409            <#assign cityTags = 0> 
410 
411            <#list articleTags?split(",") as tag> 
412                <#assign cities = ["Helsinki", "Espoo", "Vantaa", "Kauniainen", "helsinki", "espoo", "vantaa", "kauniainen"]>  
413                <#assign isCityTag = cities?seq_contains(tag)>  
414                <#if isCityTag == true> 
415                    <#assign cityTags = cityTags + 1> 
416                </#if> 
417            </#list> 
418 
419            <#if cityTags gt 0> 
420                <div class="article-section article-tags"> 
421                    <p class="sans text-uppercase d-inline">Lis&auml;&auml; aiheesta:</p> 
422                    <ul class="list-inline d-inline"> 
423                        <#list articleTags?split(",") as tag> 
424 
425                            <#assign cities = ["Helsinki", "Espoo", "Vantaa", "Kauniainen", "helsinki", "espoo", "vantaa", "kauniainen"]>  
426                            <#assign isCityTag = cities?seq_contains(tag)>  
427 
428                            <#if isCityTag> 
429                                <li class="list-inline-item"><a href="/artikkelit/-/tag/${htmlUtil.escapeURL(tag)}?article=${article.getResourcePrimKey()}" class="tag tag-map-icon">${tag}</a></li> 
430                            </#if> 
431                        </#list> 
432                    </ul> 
433                </div> 
434            </#if> 
435        </#if> 
436</#if> <#-- end of !mobileAppView -->         
437         
438        <#-- 
439            Output author card for the main author. 
440        --> 
441 
442        <#-- <#if articleAuthors.mainAuthor.getData()?? && articleAuthors.mainAuthor.getData()?has_content> 
443            <#assign authorCard = articleAuthors.mainAuthor.getData()?eval /> 
444            <@liferay_ui["asset-display"] 
445                className=authorCard.className 
446                classPK=getterUtil.getLong(authorCard.classPK, 0) 
447                template="full_content" 
448            /> 
449        </#if> --> 
450 
451        <#-- react&share buttons --> 
452         
453        <#-- Hide Kiinostavimmat nyt --> 
454        <#if mobileAppView>  
455        <style> 
456            #rns-post-recommender { display: none; } 
457        </style> 
458        </#if> <#-- end of mobileview --> 
459         
460         
461        <div class="rns"></div> 
462         
463        <script type="text/javascript"> 
464        (function() { 
465        'use strict'; 
466        var a=document.querySelector(".article-meta .date"), 
467            b=b?b.innerHTML:"", 
468            d=document.querySelector("article h1"), 
469            e=document.querySelector("a.author-name"); 
470        var rnsRecommend = function() { window.rnsRecommend() }; 
471        window.rnsData={ 
472            recommenderToggle: '.article-assets', 
473            apiKey:"oyrv5xd6dmwj3lkm", 
474            reactionCallback: rnsRecommend, 
475            maxRecommendations: 3, 
476            date:function(f){ 
477                try{ 
478                    var a=f.match(/(\d{1,2})\.(\d{1,2})\.(\d{4})(\s+(\d{1,2}):(\d{2}))*/), 
479            c=new Date(Date.UTC.apply(this,a[4]?[a[3],a[2]-1,a[1],a[5],a[6]]:[a[3],a[2]-1,a[1]]));return c.setHours(c.getHours()-2),c.toISOString()}catch(g){return""}}(b),title:d?d.innerHTML:"",author:e?e.innerHTML:"", 
480        canonicalUrl:"${articleCompleteUrl}"}; 
481        b=document.createElement("script"); 
482        b.src="https://cdn.reactandshare.com/plugin/rns.js";document.body.appendChild(b); 
483        b=document.createElement("script"); 
484        b.src="https://cdn.reactandshare.com/recommender/rnsrw.js"; 
485        document.body.appendChild(b); 
486 
487    })(); 
488        </script> 
489 
490 
491        <#-- MORE FROM AUTHOR --> 
492 
493        <#assign hasAuthor = articleAuthors.authors.getData()?? && articleAuthors.authors.getData()?has_content /> 
494        <#assign hasPhotographer = articleAuthors.photographers.getData()?? && articleAuthors.photographers.getData()?has_content /> 
495         
496        <#if hasAuthor || hasPhotographer> 
497            <#assign articleAuthor = articleAuthors.authors.getData()> 
498            <#assign articlePhotographer = articleAuthors.photographers.getData() /> 
499             
500            <#assign authorObjs = [] /> 
501 
502            <#-- Find which authors (author card titles) appears in author field and make list of those... 
503            We need no maintain order of appearance 
504            --> 
505            <#list availableAuthorNames as authorName> 
506                <#assign authorPos = articleAuthor?index_of(authorName) /> 
507                <#assign photographerPos = articlePhotographer?index_of(authorName) /> 
508                 
509                <#-- Keep the order... first authors then photographers --> 
510                <#if authorPos != -1 || photographerPos != -1> 
511                    <#assign pos = authorPos /> 
512                    <#if authorPos == -1 && photographerPos != -1> 
513                        <#assign pos = 1000 + photographerPos /> 
514                    </#if> 
515                    <#assign authorObj = {"pos" : pos, "name": authorName} /> 
516                    <#assign authorObjs = authorObjs + [authorObj] /> 
517                </#if> 
518            </#list> 
519 
520            <#if authorObjs?size gt 0> 
521                <#assign authorObjs = authorObjs?sort_by("pos") /> 
522 
523                <#-- <div class="article-tags"> 
524                    <p class="sans text-uppercase">Lis&auml;&auml; tekij&auml;lt&auml;:</p> 
525                    <ul class="list-inline"> 
526                        <#list authorObjs as authorObj> 
527                            <li class="list-inline-item"> 
528                                <#assign authorSearchURL = "/toimittajat?author=" /> 
529                                <a class="tag tag-default" href="${authorCardBaseUrl}${authorObj.name?url}">${authorObj.name}</a> 
530                            </li>		   
531                        </#list> 
532                    </ul> 
533                </div> --> 
534            </#if> 
535 
536        </#if> 
537 
538 
539        <#-- RELATED CONTENT  
540             
541            By default related content are ordered by publish date - newest first. 
542             
543            It is possible to prioritized content in article. Article must be added as related content AND  
544            it is selected into priotized content field. Editor can choose multiple prioritized content and then 
545            order is kept as it is organized in  
546         
547        -->  
548         
549        <#assign assetLinkLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetLinkLocalService") /> 
550        <#assign assetEntryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService") /> 
551        <#assign currentArticleResourcePrimKey = currentArticle.getResourcePrimKey() /> 
552        <#assign currentArticleAssetEntry = assetEntryLocalService.getEntry("com.liferay.journal.model.JournalArticle", currentArticleResourcePrimKey) /> 
553        <#assign currentArticleAssetEntryId = currentArticleAssetEntry.getEntryId() /> 
554        <#assign currentArticleRelatedLinks = assetLinkLocalService.getDirectLinks(currentArticleAssetEntryId) /> 
555         
556 
557        <#if currentArticleRelatedLinks?has_content> 
558            <#assign relatedLinks = []> 
559            <#assign prioritizedLinks = []> 
560            <#assign alreadyHandledRelatedLinksAssetEntryIds = ""> 
561             
562            <#assign relatedLinksEntryIds = "" /> 
563            <#list currentArticleRelatedLinks as related_entry> 
564                <#assign relatedLinksEntryIds = relatedLinksEntryIds + related_entry.getEntryId2() + ", " /> 
565            </#list> 
566             
567            <#if prioritizedRelatedContent?? && prioritizedRelatedContent?has_content && prioritizedRelatedContent.getSiblings()?has_content> 
568                <#list prioritizedRelatedContent.getSiblings() as prioritizedContent> 
569                    <#assign prioritizedContentAsJSON = jsonFactoryUtil.createJSONObject(prioritizedContent.getData()) > 
570                    <#if prioritizedContentAsJSON.className??> 
571                        <#if prioritizedContentAsJSON.className == "com.liferay.journal.model.JournalArticle"> 
572                            <#assign assetEntry = assetEntryLocalService.fetchEntry(prioritizedContentAsJSON.className, prioritizedContentAsJSON.classPK?number)!"" > 
573                            <#if assetEntry?has_content && relatedLinksEntryIds?contains(assetEntry.entryId?string)> 
574                                <#assign prioritizedLinks += [getRelatedLinkObjectForAssetEntry(assetEntry.entryId)] /> 
575                                <#assign alreadyHandledRelatedLinksAssetEntryIds = alreadyHandledRelatedLinksAssetEntryIds + "," + assetEntry.entryId > 
576                            </#if> 
577                        </#if> 
578                    </#if> 
579                </#list> 
580            </#if>             
581            <#list currentArticleRelatedLinks as related_entry> 
582                <#if !alreadyHandledRelatedLinksAssetEntryIds?contains(related_entry.getEntryId2()?string)> 
583                    <#assign relatedLinks += [getRelatedLinkObjectForAssetEntry(related_entry.getEntryId2())] /> 
584                </#if> 
585            </#list> 
586            <#if relatedLinks?has_content> 
587 
588                <#-- <div class="article-assets"> 
589                    <h2 class="heading-decor-section">Lue lis&auml;&auml;:</h2> --> 
590 
591                <div class="blue-wrapper"> 
592                    <div class="container entry-columns"> 
593                        <div class="row"> 
594                            <div class="entry-column col-md-12"> 
595                                <h2 class="header--top-stripe">Toimitus suosittelee</h2> 
596                                <#assign relatedLinksSorted = prioritizedLinks + relatedLinks?sort_by("date")?reverse /> 
597                                <#list relatedLinksSorted as link> 
598 
599                                    <#-- Get entry categories --> 
600                                    <#-- <#assign categories = link.getCategories()> --> 
601                                     
602                                    <#-- Get article main images --> 
603                                    <#-- <#assign docXml = saxReaderUtil.read(link.getAssetRenderer().getArticle().getContent()) /> --> 
604                                    <#-- <#assign image = docXml.valueOf("//dynamic-element[@name='articleImages']/dynamic-content/text()") /> --> 
605 
606                                <#-- 25557 show maximum 7 related links --> 
607                                 
608                                <#if link?index gt 6> 
609                                    <#break /> 
610                                </#if> 
611                                 
612                                <div class="entry-card news-pick-list-cards"> 
613                                    <div class="row"> 
614 
615                                        <#if link?is_first> 
616                                            <div class="col col-xs-12 mb-3 col-md-4 mb-md-0"> 
617                                                <div class="xaspect-ratio xaspect-ratio-4-to-3"> 
618                                                    <#-- <img class="xaspect-ratio-item xaspect-ratio-item-center xaspect-ratio-item-middle" src="${getThumbnailUrl(image, 2) }" alt="" /> --> 
619                                                    <#if link.urlImage?? && link.urlImage?has_content > 
620                                                        <#assign imageJSON = jsonFactoryUtil.createJSONObject(link.urlImage)> 
621                                                        <#assign fileEntryId = imageJSON.getString("fileEntryId")> 
622                                                        <#assign fileName = imageJSON.getString("name")> 
623                                                        <img src="${getImageURL(imageJSON, '600')}" class="media-object"  alt=""  /> 
624                                                         
625                                                    <#else> 
626                                                        <div class="xaspect-ratio xaspect-ratio-top xaspect-ratio-3-to-2"> 
627                                                            <div class="placeholder placeholder-colored"></div>  
628                                                        </div> 
629                                                    </#if> 
630                                                </div> 
631                                            </div> 
632 
633                                        <#else> 
634                                            <div class="col col-sm-2 d-none d-md-block"> 
635                                                <div class="xaspect-ratio xaspect-ratio-4-to-3"> 
636                                                    <#-- <img class="xaspect-ratio-item xaspect-ratio-item-center xaspect-ratio-item-middle" src="${getThumbnailUrl(image, 2) }" alt="" /> --> 
637                                                    <#if link.urlImage?? && link.urlImage?has_content > 
638                                                        <#assign imageJSON = jsonFactoryUtil.createJSONObject(link.urlImage)> 
639                                                        <#assign fileEntryId = imageJSON.getString("fileEntryId")> 
640                                                        <#assign fileName = imageJSON.getString("name")> 
641                                                        <img src="${getImageURL(imageJSON, '600')}" class="media-object" /> 
642                                                         
643                                                    <#else> 
644                                                        <div class="xaspect-ratio xaspect-ratio-top xaspect-ratio-3-to-2"> 
645                                                            <div class="placeholder placeholder-colored"></div>  
646                                                        </div> 
647                                                    </#if> 
648                                                </div> 
649                                            </div> 
650                                        </#if> 
651 
652                                         
653                                        <div class="col"> 
654                                            <#if link?is_first> 
655                                                <h3 class="blue-wrapper--first-title"><a href="/-/${link.urlTitle}" class="media-content">${link.title}</a></h3> 
656                                            <#else> 
657                                                <h3><a href="/-/${link.urlTitle}" class="media-content">${link.title}</a></h3> 
658                                            </#if> 
659                                             
660                                            <#list link.categories as cat> 
661                                                <span data-cat="${cat?lower_case}" class="category-item">${cat}</span> 
662                                            </#list> 
663                                            <span class="entry-meta">${link.date}</span> 
664 
665                                            <#if link?is_first> 
666                                                <p>${link.lead}</p> 
667                                            </#if> 
668 
669                                        </div> 
670                                    </div> 
671                                    <hr> 
672                                </div> 
673 
674 
675 
676                                    <#-- VANHAT --> 
677 
678                                    <#-- <div class="media"> 
679                                        <div class="media-left"> 
680                                            <a href="/-/${link.urlTitle}" class="sans"> 
681 
682                                                <#if link.urlImage?? && link.urlImage?has_content > 
683                                                    <#assign imageJSON = jsonFactoryUtil.createJSONObject(link.urlImage)> 
684                                                    <#assign fileEntryId = imageJSON.getString("fileEntryId")> 
685                                                    <#assign fileName = imageJSON.getString("name")> 
686                                                    <img src="${getImageURL(imageJSON, '600')}" class="media-object" /> 
687                                                     
688                                                <#else> 
689                                                    <div class="aspect-ratio aspect-ratio-top aspect-ratio-3-to-2"> 
690                                                        <div class="placeholder placeholder-colored"></div>  
691                                                    </div> 
692                                                </#if> 
693 
694                                            </a> 
695                                        </div> 
696                                        <div class="media-body"> 
697                                            <a href="/-/${link.urlTitle}" class="sans">${link.title}</a> 
698                                            <span class="date">${link.date}</span> 
699                                        </div> 
700                                    </div> --> 
701                                </#list> 
702                            </div> 
703                        </div> 
704                    </div> 
705 
706                </div> 
707 
708            </#if> 
709        </#if> 
710 
711        <script src="${javascript_folder}/audioplayer.min.js?v=2"></script> 
712 
713        <#--  NEWSLETTER SUBSCRIPTION BANNER  --> 
714 
715        <#-- <div class="article-subscription"> 
716            <div class="visible-md visible-lg"> 
717                <div class="banner-category-d"><h2 class="no-top-margin" style="margin-bottom: 30px;">Tilaa Kirkko ja kaupungin viikoittainen juttukooste</h2> 
718                    <form class="form-inline" action="https://kirkkojakaupunki.creamailer.fi/tilaa/59d75acf78807" id="subForm" method="post"> 
719                        <input id="redirect" name="redirect" type="hidden" value="https://kirkkojakaupunki-dev.ch5finland.com/"> 
720                        <input class="form-control" id="S&auml;hk&ouml;postiosoite" name="userEmail" placeholder="S&auml;hk&ouml;postiosoite"> 
721                        <input id="newsletter-submit-article" class="btn btn-inverse" type="submit" value="Tilaa uutiskirje"> 
722                    </form>  
723                </div> 
724            </div> 
725        </div> --> 
726 
727        <#-- FACEBOOK COMMENTS --> 
728        <#-- <#if articleComments?? && getterUtil.getBoolean(articleComments.getData()) == true> 
729            <div id="fb-root"></div> 
730            <script>if ($.gdprcookie.preference("analytics")) { document.write(` 
731                <scri`+`pt> 
732                    (function(d, s, id) { 
733                        var js, fjs = d.getElementsByTagName(s)[0]; 
734                        if (d.getElementById(id)) return; 
735                        js = d.createElement(s); js.id = id; 
736                        js.src = "//connect.facebook.net/fi_FI/sdk.js#xfbml=1&version=v2.8&appId=206864833121117"; 
737                        fjs.parentNode.insertBefore(js, fjs); 
738                    }(document, 'script', 'facebook-jssdk')); 
739                </`+`script> 
740                 
741                <h2 class="heading-decor-section">Kommentoi</h2> 
742                <p>Kommentoidaksesi sinun täytyy olla kirjautuneena Facebookiin.</p> 
743                <div class="fb-comments" data-href="${articleCompleteUrl}" data-width="725" data-numposts="5"></div> 
744                 
745            `); } 
746        </script> 
747 
748        </#if> --> 
749  </div> 
750</article> 
751 
752 
753<#-- Include script only if owl carousel among content has been built --> 
754 
755<script src="${javascript_folder}/owl.carousel.min.js"></script> 
756 
757<#if includeOwlScript == true> 
758    <script> 
759    	$('.owl-carousel').owlCarousel({ 
760            items: 1, 
761    		loop: true, 
762    		rewind: false, 
763    		margin: 0, 
764    		nav: true, 
765            navText : ['<span class="owl-carousel-nav glyphicon glyphicon-chevron-left"></span>','<span class="owl-carousel-nav glyphicon glyphicon-chevron-right"></span>'], 
766            autoplay:true, 
767            autoplayTimeout:3000, 
768            smartSpeed:1400, 
769            autoplayHoverPause:true 
770    	}); 
771 
772    </script> 
773</#if> 
774 
775<#-- 
776    Convert Youtube links to embedded videos 
777--> 
778<script type="text/javascript"> 
779 
780    $(document).ready(function () { 
781        $(".js-video-embed" ).each(function() { 
782            // Creates an iframe if it's youtube video. Otherwise just shows the original link. 
783            if (getYoutubeVideoId($(this).attr("href"))) { 
784                var div = $("<div>", {"class": "responsive-video"}); 
785                var wrapper = $("<div>", {"class": "responsive-wrapper"}); 
786                wrapper.append('<iframe src="https://www.youtube.com/embed/'+getYoutubeVideoId($(this).attr("href"))+'?rel=0" frameborder="0" allowfullscreen=""></iframe>'); 
787                div.append(wrapper); 
788                $(this).parent().append(div); 
789                $(this).hide(); //iframe is shown, hide the original link 
790
791        }); 
792    }); 
793    function getYoutubeVideoId(url) { 
794        var videoid = url.match(/(?:https?:\/{2})?(?:w{3}\.)?youtu(?:be)?\.(?:com|be)(?:\/watch\?v=|\/)([^\s&]+)/); 
795        if(videoid != null) { 
796           return videoid[1]; 
797        } else { 
798            return ""; 
799
800
801</script> 
802 
803<#--   
804    Create image comparison slider   
805--> 
806<script src="/o/kirkkojakaupunki-site-theme/js/cocoen.min.js"></script> 
807 
808<script type="text/javascript"> 
809    $(document).ready(function () { 
810        document.querySelectorAll('.cocoen').forEach(function(element){ 
811            var imageComparison = new Cocoen(element); 
812                var sliderOffset = $(element).attr("slider-offset"); 
813                if ($(element).attr("slider-offset") >= 100 || !($(element).attr("slider-offset"))){ 
814                    sliderOffset = 98; 
815                } else if ($(element).attr("slider-offset") == 0) { 
816                    sliderOffset = 2; 
817
818                imageComparison.element.children[0].style.width = sliderOffset+"%"; 
819                imageComparison.dragElement.style.left = sliderOffset+"%"; 
820        }); 
821 
822        // depending on slider offset show either the caption of the first or the second image 
823        $('.cocoen').mousemove(function(event){ 
824            addCaption(this); 
825        }); 
826 
827        // same functionality for touch screens 
828        document.querySelectorAll('.cocoen').forEach(function(element){ 
829            element.addEventListener("touchmove", function() { 
830                addCaption(this); 
831            }); 
832        }); 
833 
834        function addCaption(element) { 
835            var index = $('.cocoen').index(element); 
836            var sliderOffset = parseInt(element.firstElementChild.style.width); 
837            if(sliderOffset < 50){ 
838                $('.caption1').eq(index).hide(); 
839                $('.caption2').eq(index).show(); 
840            } else { 
841                $('.caption2').eq(index).hide(); 
842                $('.caption1').eq(index).show(); 
843
844
845    });     
846     
847</script> 
848 
849 
850<#----------------------------------------------------------------------------- 
851    Helper functions 
852------------------------------------------------------------------------------> 
853<#function getRelatedLinkObjectForAssetEntry relatedAssetEntryId> 
854                <#local relatedAssetEntry = assetEntryLocalService.getEntry(relatedAssetEntryId) /> 
855                <#local relatedAssetEntryPrimKey = relatedAssetEntry.getClassPK() /> 
856                <#local relatedArticle = JournalArticleLocalService.getLatestArticle(relatedAssetEntryPrimKey) /> 
857                <#local relatedArticleId = relatedArticle.getArticleId() /> 
858                <#local docXml = saxReaderUtil.read(relatedArticle.getContent()) />	 
859                <#local image = docXml.valueOf("//dynamic-element[@name='articleImages']/dynamic-content/text()") /> 
860 
861                <#-- Get full description & shorten it --> 
862                <#local lead = htmlUtil.stripHtml(htmlUtil.extractText(relatedArticle.getDescription())) /> 
863         
864                <#local categories = getCategoryNames(relatedArticleId) /> 
865 
866                <#local linkObject = {"categories": categories, "title": relatedArticle.getTitleCurrentValue(),"urlTitle": relatedArticle.getUrlTitle(), "date": relatedArticle.getDisplayDate()?date, "urlImage": image, "lead": lead } /> 
867                 
868                <#if image?? && image?has_content> 
869 
870                <#else> 
871                    <#local nostokuva = docXml.valueOf("//dynamic-element[@name='nostokuva']/dynamic-content/text()") /> 
872                    <#if nostokuva?? && nostokuva?has_content> 
873                        <#local image = nostokuva /> 
874                        <#local linkObject = {"title": relatedArticle.getTitleCurrentValue(),"urlTitle": relatedArticle.getUrlTitle(), "date": relatedArticle.getDisplayDate()?date, "urlImage": image, "lead": lead, "categories": categories  } /> 
875                    </#if> 
876                </#if> 
877    <#return linkObject /> 
878</#function> 
879 
880<#macro printRemainingTagContents container startAt wrapperCSSClass> 
881    <#local contentSlots = container.getSiblings() /> 
882    <#if contentSlots?has_content && contentSlots?size gt 0> 
883        <#list contentSlots as slot> 
884            <#if slot?index gte startAt> 
885            <#if slot.getData()?? && slot.getData()?has_content> 
886            <#assign slotData = slot.getData()> 
887               <#if articleImages?has_content> 
888                <#assign slotData = replaceImageTags(slotData, tagImage, articleImages)> 
889                <#assign slotData = replaceCarouselTags(slotData, tagCarousel, articleImages)> 
890            </#if> 
891        	    <#switch wrapperCSSClass> 
892        	        <#case 'template-quote'> 
893        	            <div class="article-box article-quote voice-no-read"> 
894        	                <p class="quote-body">${slotData}</p> 
895        	            </div> 
896                	    <#break> 
897            	    <#default> 
898            	        <div class="${wrapperCSSClass}">${slotData}</div> 
899        	    </#switch> 
900            </#if> 
901            </#if> 
902        </#list> 
903    </#if> 
904</#macro> 
905 
906 
907<#-- 
908    Print remainging videos, if any 
909--> 
910<#macro printRemainingVideoContents container startAt> 
911    <#local contentSlots = container.getSiblings() /> 
912    <#if contentSlots?has_content && contentSlots?size gt 0> 
913        <#list contentSlots as slot> 
914            <#if slot?index gte startAt> 
915                <#if slot.URL.getData()?? && slot.URL.getData()?has_content> 
916 
917                    <#assign URL = slot.URL.getData()!"" /> 
918                    <#assign videoFile = slot.videoFile.getData()!"" /> 
919                    <#assign caption = slot.caption.getData()!"" /> 
920                    <#assign embed = videoEmbed(URL, caption, videoFile)!"" /> 
921                    ${embed} 
922 
923                </#if> 
924            </#if> 
925        </#list> 
926    </#if> 
927</#macro> 
928 
929<#macro printNewsletterAd articleTags> 
930 
931   <#-- 
932      hengellisyys, henkisyys, hiljentyminen, rukoukset laukaisemaan bannerin joka mainostaa hiljentymiskirjettä 
933 
934      Apply Order :  
935      Jos samassa artikkelissa on useampi mainittu tägi, niin yliajojärjestys voisi olla tämä: 
936      vantaa, espoo, helsinki, mainitut hiljentymiskirjeen tägit 
937      Eli jos artikkelissa on vantaa ja helsinki, näytetään helsinkikirjebanneri.  
938      Jos artikkelissa on helsinki ja vaikkapa hengellisyys, näytetään hiljentymiskirjebanneri. 
939   --> 
940 
941    <#local showNewsletterAd = ""> 
942    <#local showNewsletterAdImg = ""> 
943    <#local newsletterAdImgAlt = ""> 
944    <#local modified = "1766063977434"> 
945 
946    <#if articleTags?contains("vantaa")> 
947        <#local showNewsletterAd = "Vantaa"> 
948        <#local showNewsletterAdImg = "https://www.kirkkojakaupunki.fi/documents/20147/49696306/web_Vantaa-kirje+tooni.jpg/6fb76d3e-c16a-6143-4af1-7a776474a34b?t=" + modified> 
949    </#if> 
950 
951    <#if articleTags?contains("espoo")> 
952        <#local showNewsletterAd = "Espoo"> 
953        <#local showNewsletterAdImg = "https://www.kirkkojakaupunki.fi/documents/20147/49696306/web_Espoo-kirje+tooni.jpg/50bedfbc-552a-8239-6e25-f376aa76795b?t=" + modified> 
954    </#if> 
955     
956    <#if articleTags?contains("helsinki")> 
957        <#local showNewsletterAd = "Helsinki"> 
958        <#local showNewsletterAdImg = "https://www.kirkkojakaupunki.fi/documents/20147/49696306/web_Helsinki-kirje+tooni.jpg/a3f37d3b-fb3f-2728-0d48-bcc897a9186e?t=" + modified> 
959    </#if>     
960   <#if showNewsletterAd?has_content> 
961    <#local newsletterAdImgAlt = "Tilaa ${showNewsletterAd}-kirje"> 
962   </#if> 
963   <#-- 
964      Hiljentymiskirje 
965   --> 
966   <#if articleTags?contains("hengellisyys") ||  
967        articleTags?contains("henkisyys") || 
968        articleTags?contains("hiljentyminen") || 
969        articleTags?contains("rukoukset")   
970
971        <#local showNewsletterAd = "hiljentymiskirje"> 
972        <#local showNewsletterAdImg = "https://www.kirkkojakaupunki.fi/documents/20147/49696306/web_Hiljentymiskirje+tooni.jpg/e2fee3b7-1912-ba85-c08e-58754870b1ba?t=" + modified>    
973        <#local newsletterAdImgAlt = "Tilaa hiljentymiskirje"> 
974   </#if> 
975   <#-- // End of Hiljentymiskirje --> 
976 
977    <#if showNewsletterAd?has_content> 
978        <div class="subscribe-newsletter "> 
979            <a href="/uutiskirje?tilaa=${showNewsletterAd}"> 
980                <img alt="${newsletterAdImgAlt}" src="${showNewsletterAdImg}" /> 
981            </a> 
982        </div> 
983    </#if> 
984</#macro> 
985 
986<#-- 
987    Print remainging audio embeds, if any 
988--> 
989<#macro printRemainingAudioContents container startAt> 
990    <#local contentSlots = container.getSiblings() /> 
991    <#if contentSlots?has_content && contentSlots?size gt 0> 
992        <#list contentSlots as slot> 
993            <#if slot?index gte startAt> 
994                <#if slot.audioFile.getData()?? && slot.audioFile.getData()?has_content> 
995                    <#assign description = slot.audioDescription.getData() /> 
996                    <#assign files = slot.audioFile /> 
997                    <#assign embed = audioEmbed(description, files) /> 
998                    ${embed} 
999                </#if> 
1000            </#if> 
1001        </#list> 
1002    </#if> 
1003</#macro> 
1004 
1005<#function replaceTags content tag replacementElement wrapperCSSClass> 
1006    <#global tagReplaceCounter = 0 /> 
1007    <#if replacementElement?has_content> 
1008        <#assign replacementList = replacementElement.getSiblings() > 
1009        <#if replacementList?has_content> 
1010 
1011        	<#list replacementList as cur_replacement> 
1012 
1013        	    <#switch wrapperCSSClass> 
1014        	        <#case 'template-quote'> 
1015                	    <#assign replacement> 
1016                	        <div class="article-box article-quote voice-no-read"> 
1017                	            <p class="quote-body">${cur_replacement.getData()}</p> 
1018            	            </div> 
1019                	    </#assign> 
1020                	    <#break> 
1021        	        <#case 'no-wrapper'> 
1022                	    <#assign replacement = cur_replacement.getData() > 
1023                	    <#break>                	     
1024            	    <#default> 
1025                	    <#assign replacement> 
1026                	        <div class="${wrapperCSSClass}">${cur_replacement.getData()}</div> 
1027                	    </#assign> 
1028        	    </#switch> 
1029 
1030        	    <#if content?index_of(tag) gt -1> 
1031            		<#local content = content?replace(tag, replacement, 'f') > 
1032            		<#global tagReplaceCounter++ /> 
1033        		</#if> 
1034        	</#list> 
1035        </#if> 
1036    </#if> 
1037 
1038  <#-- Remove "empty" tags--> 
1039  <#local content = content?replace(tag, '') > 
1040 
1041  <#return content > 
1042</#function> 
1043 
1044<#function replaceCarouselTags content tagBase replacementElement> 
1045    <#if replacementElement?has_content> 
1046        <#assign replacementList = replacementElement.getSiblings()> 
1047 
1048        <#if replacementList?has_content> 
1049            <#list 1..10 as i> 
1050                <#assign carouselArray = []> 
1051                <#list replacementList as cur_image> 
1052                    <#if cur_image.getData?? && cur_image.getData()?has_content> 
1053                        <#if cur_image.position.getData() == "article-image-carousel-${i}"> 
1054                            <#assign carouselArray = carouselArray + [createCarouselItem(cur_image)] /> 
1055                        </#if> 
1056                    </#if> 
1057                </#list> 
1058                 
1059                <#if carouselArray?has_content> 
1060                    <#assign replacement> 
1061                        <div class="owl-carousel owl-theme"> 
1062                            <#list carouselArray as carousel1> 
1063                            <div class="item"> 
1064                                ${carousel1} 
1065                            </div> 
1066                            </#list> 
1067                        </div> 
1068                    </#assign> 
1069                    <#local content = content?replace(tagBase?replace("#", i), replacement, 'f') > 
1070                </#if> 
1071            </#list> 
1072        </#if> 
1073    </#if> 
1074     
1075     
1076    <#-- clean image carousel tags --> 
1077    <#list 1..10 as i> 
1078        <#local content = content?replace(tagBase?replace("#", i), "") > 
1079    </#list> 
1080    <#return content /> 
1081</#function> 
1082 
1083<#function createCarouselItem cur_image> 
1084    <#assign result = "" /> 
1085    <#if cur_image.getAttribute("alt")?has_content> 
1086        <#assign result> 
1087            <div class="aspect-ratio aspect-ratio-middle aspect-ratio-xs"> 
1088                <img class="aspect-ratio-item-fluid" src="${getImageURLByTemplateModel(cur_image, '1200')}" alt="${cur_image.getAttribute("alt")}" /> 
1089            </div> 
1090            <p class="caption voice-no-read">${cur_image.getAttribute("alt")}</p> 
1091        </#assign> 
1092    <#else> 
1093        <#assign result> 
1094            <div class="aspect-ratio aspect-ratio-middle aspect-ratio-xs"> 
1095                <img class="aspect-ratio-item-fluid" src="${getImageURLByTemplateModel(cur_image, '1200')}" alt="" /> 
1096            </div> 
1097        </#assign> 
1098    </#if> 
1099    <#return result /> 
1100</#function> 
1101 
1102<#function replaceImageTags content tag replacementElement> 
1103    <#if replacementElement?has_content> 
1104        <#assign replacementList = replacementElement.getSiblings() > 
1105        <#if replacementList?has_content> 
1106        	<#list replacementList as cur_image> 
1107 
1108                <#if cur_image.getData?? && cur_image.getData()?has_content> 
1109 
1110                    <#-- Skip header images --> 
1111                    <#if cur_image.position.getData() != "article-image-header" && !cur_image.position.getData()?starts_with("article-image-carousel-")> 
1112                        <#assign thumbnailSize = 2 > 
1113                        <#if cur_image.position.getData() == "article-image-full"> 
1114                            <#assign thumbnailSize = 3 > 
1115                        </#if> 
1116                        <#assign replacement> 
1117 
1118                            <div class="article-box ${cur_image.position.getData()}"> 
1119                                <#if cur_image.getAttribute("alt")?has_content> 
1120                                    <img src="${getImageURLByTemplateModel(cur_image, '1200')}" alt="${cur_image.getAttribute("alt")}" /> 
1121                                    <p class="caption voice-no-read">${cur_image.getAttribute("alt")}</p> 
1122                                <#else> 
1123                                    <img src="${getImageURLByTemplateModel(cur_image, '1200')}" alt="" /> 
1124                                </#if> 
1125                            </div> 
1126                        </#assign> 
1127                        <#local content = content?replace(tag, replacement, 'f') > 
1128                    </#if> 
1129 
1130                </#if> 
1131 
1132        	</#list> 
1133        </#if> 
1134    </#if> 
1135 
1136  <#-- Remove "empty" tags--> 
1137  <#local content = content?replace(tag, '') > 
1138 
1139  <#return content > 
1140</#function> 
1141 
1142 
1143<#function replaceImageComparisonTags content tag replacementElement> 
1144    <#if replacementElement?has_content> 
1145        <#assign replacementList = replacementElement.getSiblings() > 
1146        <#if replacementList?has_content> 
1147            <#list replacementList as cur_imageComparison> 
1148                <#if cur_imageComparison.getData??> 
1149                    <#assign image1 = cur_imageComparison.image1 /> 
1150                    <#assign image2 = cur_imageComparison.image2 /> 
1151                    <#if cur_imageComparison.sliderOffset.getData() == "" > 
1152                        <#assign offset = 100 /> 
1153                    <#else> 
1154                        <#assign offset = cur_imageComparison.sliderOffset.getData() /> 
1155                    </#if> 
1156                    <#assign replacement> 
1157                        <#if image1.getData?? && image1.getData()?has_content && image2.getData?? && image2.getData()?has_content> 
1158                            <div class="cocoen-theme"> 
1159                                <div class="cocoen" slider-offset="${offset}"> 
1160                                    <#if image1.getAttribute("alt")?has_content> 
1161                                        <img src="${getThumbnailUrl(image1.getData(), 3) }" alt="${image1.getAttribute("alt")}" /> 
1162                                    <#else> 
1163                                        <img src="${getThumbnailUrl(image1.getData(), 3) }" alt="" /> 
1164                                    </#if> 
1165                                    <#if image2.getAttribute("alt")?has_content> 
1166                                        <img src="${getThumbnailUrl(image2.getData(), 3) }" alt="${image2.getAttribute("alt")}" /> 
1167                                    <#else> 
1168                                        <img src="${getThumbnailUrl(image2.getData(), 3) }" alt="" /> 
1169                                    </#if> 
1170                                </div> 
1171                                <#if image1.getAttribute("alt")?has_content && image2.getAttribute("alt")?has_content> 
1172                                    <#if offset?number lt 50> <!-- pienempi kuin 50, n&auml;yt&auml; kuvateksti 2 --> 
1173                                        <div class="caption2"> 
1174                                            <p class="caption voice-no-read"> 
1175                                                ${image2.getAttribute("alt")} 
1176                                            </p> 
1177                                        </div> 
1178                                        <div class="caption1" style="display:none"> 
1179                                            <p class="caption voice-no-read"> 
1180                                                ${image1.getAttribute("alt")} 
1181                                            </p> 
1182                                        </div> 
1183                                    <#else> 
1184                                        <div class="caption2" style="display:none"> 
1185                                            <p class="caption voice-no-read"> 
1186                                                ${image2.getAttribute("alt")} 
1187                                            </p> 
1188                                        </div> 
1189                                        <div class="caption1"> 
1190                                            <p class="caption voice-no-read"> 
1191                                                ${image1.getAttribute("alt")} 
1192                                            </p> 
1193                                        </div> 
1194                                    </#if> 
1195                                </#if> 
1196                            </div> 
1197                        </#if> 
1198                    </#assign> 
1199                    <#local content = content?replace(tag, replacement, 'f') > 
1200                </#if> 
1201            </#list> 
1202        </#if> 
1203    </#if> 
1204    <#-- Remove "empty" tags--> 
1205    <#local content = content?replace(tag, '') > 
1206 
1207    <#return content > 
1208</#function> 
1209 
1210 
1211<#function replaceVideoTags content tag replacementElement> 
1212    <#global tagReplaceCounter = 0 /> 
1213    <#if replacementElement?has_content> 
1214        <#assign replacementList = replacementElement.getSiblings() > 
1215        <#if replacementList?has_content> 
1216 
1217            <#global videoListSize = replacementList?size /> 
1218 
1219        	<#list replacementList as cur_video> 
1220                <#assign videoFile = "" /> 
1221                <#assign URL = cur_video.URL.getData()!"" /> 
1222                <#if (cur_video.videoFile)??> 
1223                    <#assign videoFile = cur_video.videoFile.getData()!"" /> 
1224                </#if> 
1225                <#assign caption = cur_video.caption.getData()!"" /> 
1226                 
1227                <#if (cur_video.videoFile)?? || URL?has_content> 
1228                    <#assign replacement = videoEmbed(URL, caption, videoFile)!"" /> 
1229                </#if> 
1230                
1231                <#if content?index_of(tag) gt -1> 
1232                    <#local content = content?replace(tag, replacement, 'f') > 
1233                    <#global tagReplaceCounter++ /> 
1234                </#if> 
1235 
1236                <#-- <#local content = content?replace(tag, replacement, 'f') > --> 
1237        	</#list> 
1238        </#if> 
1239    </#if> 
1240 
1241  <#-- Remove "empty" tags--> 
1242  <#local content = content?replace(tag, '') > 
1243 
1244  <#return content > 
1245</#function> 
1246 
1247 
1248<#function replaceAudioTags content tag replacementElement> 
1249    <#global tagReplaceCounter = 0 /> 
1250    <#if replacementElement?has_content> 
1251        <#assign replacementList = replacementElement.getSiblings() > 
1252        <#if replacementList?has_content> 
1253 
1254            <#global audioListSize = replacementList?size /> 
1255 
1256        	<#list replacementList as cur_audioEmbed> 
1257                <#assign description = cur_audioEmbed.audioDescription.getData() /> 
1258                <#assign files = cur_audioEmbed.audioFile /> 
1259                <#assign replacement = audioEmbed(description, files) /> 
1260 
1261                <#if content?index_of(tag) gt -1> 
1262                    <#local content = content?replace(tag, replacement, 'f') > 
1263                    <#global tagReplaceCounter++ /> 
1264                </#if> 
1265 
1266        	</#list> 
1267        </#if> 
1268    </#if> 
1269    <#local content = content?replace(tag, '') > 
1270    <#return content > 
1271</#function> 
1272 
1273<#function replaceAdTag content> 
1274    <#local adScript> 
1275    	<div class="ad-container"> 
1276            <div> 
1277                <script type="text/javascript"> 
1278                if (!$.gdprcookie || $.gdprcookie.preference("marketing")) { 
1279                    if((window.innerWidth > 1019) || (typeof inPreviewMode !== 'undefined' && inPreviewMode)) 
1280
1281                    // NM 468x400 
1282                    document.write('<scri'+'pt data-adfscript="adx.adform.net/adx/?mid=937873&mkv=" id="ar"></'+'script>'); 
1283                    document.write('<scri'+'pt src="//s1.adform.net/banners/scripts/adx.js" async defer ></'+'script>'); 
1284
1285                    else 
1286
1287                    // NM 300x300 3 
1288                    document.write('<scri'+'pt data-adfscript="adx.adform.net/adx/?mid=937882&mkv="></'+'script>'); 
1289                    document.write('<scri'+'pt src="//s1.adform.net/banners/scripts/adx.js" async defer></'+'script>'); 
1290
1291
1292                </script> 
1293            </div> 
1294        </div> 
1295    </#local> 
1296     
1297    <#return content?replace("[[mainos]]", adScript) /> 
1298</#function> 
1299 
1300<#function videoEmbed URL, caption, videoFile> 
1301    <#local embed = "" /> 
1302 
1303    <#if URL?contains("vimeo")> 
1304        <#local iframeSrc = "https://player.vimeo.com/video/" /> 
1305        <#local videoID = URL?split("/")?last /> 
1306		<#local embed> 
1307		    <div class="responsive-video"> 
1308    			<div class="responsive-wrapper vimeo" id="vimeo-${videoID}" data-embed="${videoID}"> 
1309    				<img class="decor-video" alt="Toista video" src="/o/kirkkojakaupunki-site-theme/images/icons/video-decor.svg"> 
1310    			</div> 
1311				<noscript><a href="${URL}" target="_blank" rel="noopener"Videota</a> ei voida n&auml;ytt&auml;&auml; koska javascript on kytketty pois p&auml;&auml;lt&auml; selaimesta.</noscript> 
1312    		</div> 
1313		</#local> 
1314    <#elseif URL?contains("youtube")> 
1315        <#local isVerticalVideo = URL?starts_with("https://www.youtube.com/shorts/")> 
1316         
1317        <#local iframeSrc = "https://www.youtube.com/embed/" /> 
1318        <#local videoID = URL?replace("^.*\\?v=([\\w-_]*).*", "$1", "r") /> 
1319        <#if URL?starts_with("https://www.youtube.com/shorts/")> 
1320            <#local videoID = URL?replace("https://www.youtube.com/shorts/","")> 
1321        </#if> 
1322         
1323		<#local embed> 
1324             
1325            <div class="responsive-video <#if isVerticalVideo>vertical-video</#if>">   
1326    			<div class="responsive-wrapper youtube" data-embed="${videoID}"> 
1327    				<img class="decor-video" alt="Toista video" src="/o/kirkkojakaupunki-site-theme/images/icons/video-decor.svg"> 
1328    			</div> 
1329                <noscript><a href="https://www.youtube.com/watch?v=${videoID}" target="_blank" rel="noopener">Videota</a> ei voida n&auml;ytt&auml;&auml; koska javascript on kytketty pois p&auml;&auml;lt&auml; selaimesta.</noscript> 
1330			</div> 
1331		</#local> 
1332    <#elseif videoFile?has_content> 
1333        <#local embed> 
1334            <div class="responsive-video"> 
1335                <video controls controlsList="nodownload" style="max-width:100%"> 
1336                <#-- #t=0.001 Safari hack - See ticket 25143 --> 
1337                <source src="${videoFile}#t=0.001" type="video/mp4"> 
1338                    Your browser does not support the video tag. 
1339                </video> 
1340            </div>  
1341        </#local> 
1342    <#else> 
1343        <#return embed> 
1344    </#if> 
1345 
1346    <#return embed> 
1347</#function> 
1348 
1349 
1350<#function audioEmbed description, files> 
1351    <#local embed = ""> 
1352    <#local audioFiles = [] /> 
1353     
1354    <#list files.getSiblings() as file>        
1355        <#local fileURL = file.getData()!""> 
1356        <#if fileURL?has_content> 
1357            <#local fileFormat = file.audioFormat.getData()> 
1358            <#local fileObject = {"format": fileFormat, "URL": fileURL}> 
1359            <#local audioFiles += [fileObject]> 
1360        </#if> 
1361    </#list> 
1362 
1363    <#if audioFiles?has_content> 
1364        <#local embed> 
1365            <div class="audio-player sans voice-no-read"> 
1366                <button class="btn btn-link flex-item-center"> 
1367                    <i class="glyphicon glyphicon-play" aria-hidden="true"></i> 
1368                </button> 
1369                <div class="audio-player-details flex-item-center"> 
1370                    <#if description?has_content> 
1371                        <p>${description}</p> 
1372                    </#if> 
1373                    <div class="audio-player-progress"> 
1374                        <span class="audio-player-time-display">-:- / -:-</span> 
1375                        <div class="audio-player-seekbar"> 
1376                            <div class="audio-player-bufferbar"></div> 
1377                            <div class="audio-player-progressbar"></div> 
1378                        </div> 
1379                    </div>                 
1380                </div> 
1381                <audio preload="metadata" loop> 
1382                    <#list audioFiles as file> 
1383                        <source src="${file.URL}" type="${file.format}" /> 
1384                    </#list> 
1385                </audio> 
1386            </div> 
1387        </#local> 
1388    </#if> 
1389 
1390    <#return embed> 
1391</#function> 
1392 
1393 
1394<#function getHeaderImages articleImages> 
1395    <#local headerImages = [] /> 
1396 
1397    <#if articleImages?has_content && articleImages.getSiblings()?has_content> 
1398        <#list articleImages.getSiblings() as cur_image> 
1399            <#if cur_image.position.getData() == 'article-image-header'> 
1400                <#local headerImages = headerImages + [cur_image] /> 
1401            </#if> 
1402        </#list> 
1403    </#if> 
1404 
1405    <#if !headerImages?has_content && articleImages?has_content && articleImages.getSiblings()?has_content > 
1406        <#local headerImages = headerImages + [articleImages.getSiblings()?first] /> 
1407    </#if> 
1408 
1409    <#return headerImages> 
1410</#function> 
1411 
1412<#function getContentCarouselImages articleImages> 
1413 
1414    <#local contentCarouselImages = [] /> 
1415 
1416    <#if articleImages?has_content && articleImages.getSiblings()?has_content> 
1417        <#list articleImages.getSiblings() as cur_image> 
1418            <#if cur_image.position.getData()?starts_with('article-image-carousel-')> 
1419                <#local contentCarouselImages = contentCarouselImages + [cur_image] /> 
1420            </#if> 
1421        </#list> 
1422    </#if> 
1423 
1424    <#if !contentCarouselImages?has_content && articleImages?has_content && articleImages.getSiblings()?has_content > 
1425        <#local contentCarouselImages = contentCarouselImages + [articleImages.getSiblings()?first] /> 
1426    </#if> 
1427 
1428    <#return contentCarouselImages> 
1429</#function> 
1430 
1431<#-- 
1432    Attempts to get mime type for a file in document library. 
1433 
1434    Parameters: 
1435        fileUrl: A string containig a url to the file. 
1436 
1437    Returns mime type as a string or an empty string. 
1438--> 
1439<#function getMimeType fileUrl> 
1440    <#if fileUrl?? && fileUrl?has_content> 
1441 
1442        <#-- Attempt to parse uuid & groupId from provided Url --> 
1443        <#assign splitUrl = fileUrl?split("/", "r") /> 
1444 
1445        <#if splitUrl?seq_contains("documents") && splitUrl?size gte 6> 
1446            <#attempt> 
1447 
1448                <#assign groupId = splitUrl[2] /> 
1449                <#assign uuid = splitUrl[5] /> 
1450                <#assign uuid = uuid?split("?")[0] /> 
1451 
1452                <#-- Get DLFileEntry --> 
1453                <#assign DLFileEntryLocalService = serviceLocator.findService("com.liferay.document.library.kernel.service.DLFileEntryLocalService") /> 
1454                <#assign fileEntry = DLFileEntryLocalService.fetchDLFileEntryByUuidAndGroupId(uuid, getterUtil.getLong(groupId)) /> 
1455                <#return fileEntry.getMimeType()> 
1456            <#recover> 
1457                <#-- Parsing mime type failed, return empty --> 
1458                <#return ""> 
1459            </#attempt> 
1460 
1461        <#elseif splitUrl?seq_contains("journal") && splitUrl?size gte 4> 
1462            <#attempt> 
1463                <#assign imageId = splitUrl[3]?split("?")[1]?split("=")[1]?split("&")[0] /> 
1464                <#assign ImageLocalService = serviceLocator.findService("com.liferay.portal.kernel.service.ImageLocalService") /> 
1465                <#assign imageType = ImageLocalService.getImage(getterUtil.getLong(imageId)).getType() /> 
1466                <#switch imageType> 
1467                    <#case "gif"> 
1468                        <#return "image/gif"> 
1469                    <#case "svg"> 
1470                        <#return "image/svg"> 
1471                    <#default> 
1472                        <#return imageType> 
1473                </#switch> 
1474            <#recover> 
1475                <#return ""> 
1476            </#attempt> 
1477 
1478        <#else> 
1479            <#-- Parsing image url failed, return empty --> 
1480            <#return ""> 
1481        </#if> 
1482 
1483    <#else> 
1484        <#-- parameter empty or missing, return empty --> 
1485        <#return ""> 
1486    </#if> 
1487</#function> 
1488 
1489<#-- 
1490    Returns thumbnail image url for given image. 
1491    Handles SVG & bitmap formats. 
1492 
1493    Parameters: 
1494        imageUrl: string containing relative url to an image in document library 
1495        thumbnailSize: value for Liferay's imageThumbnail parameter (0-3) 
1496 
1497    Returns image url with appended thumbnail info or an empty string. 
1498 --> 
1499<#function getThumbnailUrl imageUrl thumbnailSize> 
1500    <#if imageUrl?? && imageUrl?has_content> 
1501 
1502        <#-- Attempt to get mime type --> 
1503        <#assign mimeType = getMimeType(imageUrl) /> 
1504 
1505        <#if mimeType?has_content> 
1506 
1507            <#-- Check image mime type --> 
1508            <#switch mimeType> 
1509                <#case "image/svg+xml"> 
1510                    <#-- SVG image -> do not append thumbnail parameter --> 
1511                    <#return imageUrl> 
1512                <#case "image/gif"> 
1513                    <#return imageUrl> 
1514                <#default> 
1515                    <#-- Predume bitmap image -> append thumbnail parameter --> 
1516                    <#if imageUrl?contains("?")> 
1517                        <#assign paramChar = "&" /> 
1518                    <#else> 
1519                        <#assign paramChar = "?" /> 
1520                    </#if> 
1521<#-- 
1522    Liferay 7.3 thumbSize 3 on pienempi kuin aiemmin. Woodwingist tulevat kuvat nykyisin 1200 joten voidaan palauttaa suoraan kuvan url. Vaihtoehto hyodyntaa adaptive mediaa 
1523--> 
1524                    <#if thumbnailSize == 3> 
1525                        <#return imageUrl /> 
1526                    <#else> 
1527                        <#return imageUrl + paramChar + "imageThumbnail=" + thumbnailSize /> 
1528                    </#if> 
1529            </#switch> 
1530        <#else> 
1531            <#-- Embbedded journal article image (type: journal) mime recognizion fails for ie  
1532            /-/sini-mikkola-tutkii-lutherin-kasityksia 
1533            /-/kristinuskon-alkeita-ja-syventavia-keskusteluja 
1534            /-/mika-keisarin-on 
1535            --> 
1536            <#return imageUrl > 
1537        </#if> 
1538 
1539    </#if> 
1540</#function> 
1541 
1542<#-- 
1543    Return list of web content titles from given folder 
1544    parameter: 
1545        - authorCardFolderId 
1546--> 
1547<#function getAvailableAuthorNames authorCardFolderIds > 
1548 
1549  <#local authorNames = []>     
1550  <#local seenArticles = [] > 
1551  <#-- Multiple version exists so keep track which articles we have already checked --> 
1552 
1553  <#list authorCardFolderIds as authorCardFolderId> 
1554    <#assign authorCards = JournalArticleLocalService.getArticles(groupId, authorCardFolderId) /> 
1555 
1556    <#if authorCards?has_content> 
1557        <#list authorCards as authorCard> 
1558	    <#if !seenArticles?seq_contains(authorCard.articleId)> 
1559	      <#assign latest = JournalArticleLocalService.getLatestArticle(authorCard.resourcePrimKey) /> 
1560	      <#if latest.getStatus() == 0> 
1561		  <#local authorName = latest.getTitle(locale) /> 
1562		  <#if !authorNames?seq_contains(authorName) > 
1563		      <#local authorNames = authorNames + [authorName] /> 
1564		  </#if> 
1565	      </#if> 
1566	      <#local seenArticles = seenArticles + [authorCard.articleId] /> 
1567	    </#if> 
1568        </#list> 
1569         
1570    </#if> 
1571  </#list> 
1572  <#return authorNames /> 
1573</#function> 
1574 
1575<#-- 
1576    Replaces from given string author names with links to author page 
1577    parameters:  
1578    - authorNameStr : String where replacements is targeted 
1579    - authorNames : seq : list of author names 
1580    - baseUrl : url where author name is appended (as url escaped string) 
1581--> 
1582 
1583<#function makeAuthorLinks authorNameStr authorNames baseUrl > 
1584    <#list authorNames as authorName> 
1585        <#local authorNameInUrl = authorName?url("utf-8") /> 
1586        <#local authorNameStr = authorNameStr?replace(authorName, "<a class=\"author-name\" href=\""+baseUrl +authorNameInUrl + "\">"+authorName+"</a>") /> 
1587    </#list> 
1588    <#return authorNameStr /> 
1589</#function> 
1590 
1591<#function getImageURL imageJSON thumbId> 
1592    <#if imageJSON?? && imageJSON?has_content> 
1593        <#assign fileEntryId = imageJSON.getLong("fileEntryId")/> 
1594        <#assign fileName = imageJSON.getString("name")/> 
1595         
1596        <#if fileName?ends_with(".svg") || fileName?ends_with(".gif")> 
1597            <#assign imageGroupId = imageJSON.getLong("groupId")/> 
1598            <#assign imageUuid = imageJSON.getString("uuid")/> 
1599         
1600            <#return getFullImageUrL(imageGroupId, imageUuid) > 
1601        <#else> 
1602            <#return getAdaptiveImageURLByFileEntryId(fileEntryId, fileName, thumbId) > 
1603        </#if> 
1604    </#if> 
1605</#function> 
1606 
1607<#function getImageURLByTemplateModel imageTemplateModel thumbId> 
1608    <#local uuid = imageTemplateModel.getAttribute("uuid")/> 
1609    <#return getFullImageUrL(groupId, uuid)> 
1610</#function> 
1611 
1612<#function getAdaptiveImageURLByFileEntryId fileEntryId fileName thumbId> 
1613 
1614		<#local adaptiveMediaUrl = "/o/adaptive-media/image/${fileEntryId}/${thumbId}/${fileName}" > 
1615		 
1616        <#return adaptiveMediaUrl> 
1617</#function> 
1618 
1619<#function getFullImageUrL(groupId, uuid)> 
1620            <#assign imageURL = "/documents/" /> 
1621            <#assign imageURL += groupId /> 
1622            <#assign imageURL += "/" + uuid /> 
1623         
1624            <#return imageURL> 
1625</#function> 
1626 
1627<#function getCategoryNames( articleId, vocabularyId="" )> 
1628 
1629    <#local categoryNames = [] /> 
1630 
1631    <#-- Get all categories from journalArticle --> 
1632    <#local journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") /> 
1633    <#local primKey = journalArticleLocalService.getArticle(getterUtil.getLong(groupId), articleId).getResourcePrimKey() /> 
1634    <#local assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService") /> 
1635    <#local categories = assetCategoryLocalService.getCategories('com.liferay.journal.model.JournalArticle', getterUtil.getLong(primKey)) /> 
1636 
1637    <#if categories?has_content> 
1638        <#list categories as cur_category> 
1639            <#if vocabularyId?has_content && vocabularyId == cur_category.getVocabularyId() > 
1640                <#-- get category names from given category --> 
1641                <#local categoryNames += [cur_category.getName()] /> 
1642            <#elseif !vocabularyId?has_content> 
1643                <#-- get all category names --> 
1644                <#local categoryNames += [cur_category.getName()] /> 
1645            </#if> 
1646 
1647        </#list> 
1648    </#if> 
1649 
1650    <#return categoryNames> 
1651</#function> 
1652 
1653<#function cleanSpecialChars content> 
1654  <#local content = content?replace("\xAD", "") > 
1655 
1656  <#return content > 
1657</#function> 
1658 
1659<#if mobileAppView> 
1660    <script> 
1661        <#-- Replace article urls (contains /-/) with this asset publisher content url --> 
1662        let contentUrlIndex = window.location.pathname.indexOf('/content/'); 
1663         
1664        if (contentUrlIndex > 0) { 
1665            let assetPublisherContentURL = window.location.pathname.substring(0,contentUrlIndex) + "/content/"; 
1666         
1667            $('article a[href*="/-/"]').each(function(){ 
1668                let localAssetPublisherContentUrl  = $(this).attr("href").replace("/-/", assetPublisherContentURL); 
1669                $(this).attr("href", localAssetPublisherContentUrl); 
1670            }); 
1671
1672    </script> 
1673</#if> 

Löydä lisää näkökulmia


Keskustele Facebookissa
Keskustele ja kommentoi Facebookissa
Lähetä juttuvinkki
Lähetä juttuvinkki
Kirkko ja kaupunki -mediaan.

Tilaa Kirkko ja kaupungin ilmaisia uutiskirjeitä.