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