null Rakas lähiö: Kirjailija Virpi Hämeen-Anttila nauttii siitä, että Mikkolassa ei tapahdu liikaa

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