The following has evaluated to null or missing: ==> FrontendService.media.getDMTJsonObject( coverBild.groupId?number, coverBild.uuid, locale ) [in template "252001#252047#252845" at line 128, column 37] ---- 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: dMTJsonObject = FrontendService.media... [in template "252001#252047#252845" at line 128, column 21] ----
1<#-- used @ Veranstaltung-Detailseite Intro
2 used @ Publikation-Detailseite Intro
3-->
4
5<#--
6Web content templates to display teaser on thema detail page
7
8Generic template for detail pages Intro / Teaser element
9-->
10<#--
11Display the current page title
12-->
13<#include "${fullTemplatesPath}/functions/relatedContentUtil.ftl" />
14<#include "${fullTemplatesPath}/macros/debugging.ftl" />
15
16<#include "${fullTemplatesPath}/macros/page-modules/PMIntro.ftl" />
17<#include "${fullTemplatesPath}/macros/atomic-modules/AMPublicationCarousel.ftl" />
18<#include "${fullTemplatesPath}/macros/atomic-modules/AMMetadata.ftl" />
19<#include "${fullTemplatesPath}/macros/atomic-modules/AMDatetime.ftl" />
20
21
22<#--
23 renders the Intro for nearly all Pages
24 TODO: remove Share? (was in the designs, but not anymore?)
25 TODO: check if languageSelect/filter are working (js)
26
27 - portletId
28 - data = {
29 "media": string (src from image),
30 "category": string,
31 "title": string,
32 "author": string,
33 "subheadline": string,
34 "copy": string,
35 "filter": {
36 "id": string,
37 "name": string,
38 "entries": Array<Object> ({key:value}),
39 },
40 "languageSelect": {
41 "id": string,
42 "name": string,
43 "entries": Array<Object> ({key:value}),
44 },
45 "meta": {
46 "pos"; string (top/bottom)
47 "date": string,
48 "hash": string,
49 "info": string, (url)
50 },
51 "share" : {
52 "login": string,
53 "print": string,
54 "mail": string,
55 "multishare": string?? (tbd)
56 }
57 - AMMetadata: macro
58 - position: String ("top") -> defines wether the meta-data should be rendered above or below the intro-content
59 }
60-->
61
62<#assign
63 JournalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")
64
65 ServiceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext()
66 DLAPP = serviceLocator.findService("com.liferay.document.library.kernel.service.DLAppLocalService")
67
68 themeDisplay = ServiceContext.getThemeDisplay()
69 editmode = FrontendService.user.isPrivilegedUser(themeDisplay)
70
71 languageId = themeDisplay.getLocale()
72 groupId = themeDisplay.getScopeGroupId()
73 currentUrl = themeDisplay.getURLCurrent()
74
75 layout = themeDisplay.getLayout()
76 layouttpl = layout.getTypeSettingsProperties().getProperty("layout-template-id")
77/>
78
79<#setting locale="${languageId}">
80
81<#-- get article from url -->
82
83<#assign entry = FrontendService.article.getArticleToUrl(currentUrl, groupId?number)! >
84
85
86<#if entry?has_content>
87
88 <#if entry.resourcePrimKey??>
89 <#assign primaryKey = entry.resourcePrimKey?number >
90 <#elseif entry.classPK??>
91 <#assign primaryKey = entry.classPK?number >
92 </#if>
93
94 <#assign
95 jsonString = FrontendService.article.getWebcontent(primaryKey)
96 json = FrontendService.json.parseAsJson(jsonString)
97 availablelanguages = FrontendService.article.getAssetEntryToUrl(primaryKey).getAvailableLanguageIds()
98
99 title = entry.getTitle(languageId)
100 data = {
101 "title": title
102 }
103 />
104 <@debugJsonString jsonString "ADT_KASDE_DYNAMIC_INTRO" />
105
106 <#if hasContent('untertitel', languageId, json)>
107 <#assign data = data + { "subheadline": getValueForLanguage('untertitel', languageId, json, "first") } >
108 </#if>
109
110 <#if hasContent('beschreibung', languageId, json)>
111 <#assign data = data + { "copy": getValueForLanguage('beschreibung', languageId, json, "first") } >
112 </#if>
113
114 <#-- fill meta data -->
115 <#assign meta = {} />
116
117 <#-- PUBLIKATIONEN DETAIL -->
118 <#if layouttpl?contains("LAYOUT_KASDE_PUBLIKATIONEN_DETAIL")>
119
120 <#if hasContent('coverDMTKASDEMEDIUM', languageId, json)>
121 <#assign
122 coverBildString = getValueForLanguage('coverDMTKASDEMEDIUM', languageId, json, "first")
123 />
124
125 <#if coverBildString?has_content>
126 <#assign
127 coverBild = FrontendService.json.parseAsJson(coverBildString)
128 dMTJsonObject = FrontendService.media.getDMTJsonObject( coverBild.groupId?number, coverBild.uuid, locale )
129 linkToDMT = FrontendService.media.getImageURLForAMConfiguration('hd-resolution',coverBild.groupId?number, coverBild.uuid )
130 data = data + { "media": linkToDMT, "meta" : dMTJsonObject }
131 />
132 <#if dMTJsonObject.altText?? >
133 <#assign data = data + {"alt" : dMTJsonObject.altText} />
134 </#if>
135 <#if dMTJsonObject.quelle??>
136 <#assign meta = meta + { "quelle": dMTJsonObject.quelle } />
137 </#if>
138 </#if>
139 <#-- uncomment to display pdf cover as Intro Image
140 <#elseif hasContent('document_pdfDMTBASICDOCUMENT', languageId, json)>
141 <#assign
142 pdfDocument = getValueForLanguage('document_pdfDMTBASICDOCUMENT', languageId, json, "first")
143 fileEntry = FrontendService.media.getFileEntry(pdfDocument.uuid, groupId?number)!/>
144 <#if fileEntry?has_content>
145 <#assign
146 linkToThumbnail = FrontendService.link.getThumbnailSrc(fileEntry , themeDisplay)
147 data = data + { "media": linkToThumbnail }
148 />
149 </#if>
150 -->
151 </#if>
152
153 <#assign
154 meta = meta + { "orderInfo": "true" }
155 verbundJournalArticle = FrontendService.publication.getVerbundToPublikation( entry )!""
156 />
157
158
159
160 <#if hasContent('erscheinungsdatum', languageId, json)>
161 <#assign
162 erscheinungsdatum = getValueForLanguage('erscheinungsdatum', languageId, json, "first")
163 />
164 <#if erscheinungsdatum?has_content >
165 <#assign
166 erscheinungsdatumFormatted = FrontendService.date.getDateFormatLong( erscheinungsdatum, languageId )
167 meta = meta + { "date": erscheinungsdatumFormatted }
168 />
169 </#if>
170 </#if>
171
172 <#if verbundJournalArticle?has_content>
173 <#assign
174 verbundJsonString = FrontendService.article.getWebcontent(verbundJournalArticle.resourcePrimKey)
175 verbundJson = FrontendService.json.parseAsJson(verbundJsonString)
176 laufendenummer = getValueForLanguage('laufendenummer', languageId, verbundJson, "first")
177 coverImg = getValueForLanguage('mediumDMTKASDEMEDIUM', languageId, verbundJson, "first")
178 />
179 <@debugJsonString verbundJsonString "ADT_KASDE_DYNAMIC_INTRO-verbundJournalArticle" />
180 <#assign meta = meta + { "laufendenummer": laufendenummer } >
181
182 <#if coverImg?has_content && coverImg.url?has_content >
183 <#assign meta = meta + { "coverImg": coverImg.url } >
184 </#if>
185 </#if>
186
187
188 <#if meta?has_content>
189 <#assign data = data + {"meta": meta } >
190 </#if>
191
192 </#if>
193 <#-- PUBLIKATIONEN DETAIL END -->
194
195
196 <#-- VERANSTALTUNGEN DETAIL -->
197 <#if layouttpl?contains("LAYOUT_KASDE_VERANSTALTUNGEN_DETAIL")>
198 <#assign
199 friendlyUrl = FrontendService.article.getFriendlyUrl(primaryKey, languageId, groupId)!""
200 links = []
201 />
202 <#if availablelanguages?has_content && friendlyUrl?has_content>
203 <#if (availablelanguages?size > 1) >
204 <#list availablelanguages as language>
205 <#assign
206 defaultLanguage = "de_DE"
207 defaultLocale = FrontendService.language.getLocaleByKey(defaultLanguage)
208 linkLocale = (FrontendService.language.getLocaleByKey(language))!defaultLocale
209 langFriendlyUrl = FrontendService.article.getFriendlyUrl(primaryKey, linkLocale, groupId)
210
211 link = {
212 "key": language!defaultLanguage,
213 "value": linkLocale.getDisplayLanguage(languageId),
214 "url": "/c/portal/update_language?p_l_id=" +
215 layout.plid + "&redirect=" + langFriendlyUrl +
216 "&languageId=" + language
217 }
218 />
219 <#if language == languageId>
220 <#assign link = link + { "selected": "true" } >
221 </#if>
222 <#assign links = links + [link]>
223 </#list>
224 <#assign
225 data = data + {
226 "languageSelect": {
227 "id": "languageSelectRedirect",
228 "name": "languageselectRedirect",
229 "entries": links,
230 "label": languageUtil.get(languageId, "diese.veranstaltung.ist.in.weiteren.sprachen.verfuegbar")
231 }
232 }
233 />
234 </#if>
235 </#if>
236 </#if>
237
238 <#if hasContent('erscheinungsdatum', languageId, json)>
239 <#assign
240 startdate = getValueForLanguage('erscheinungsdatum', languageId, json, "first")
241 meta = meta + { "start": startdate?date.iso, "end": "" }
242 />
243 </#if>
244
245 <#if hasContent('startdatum', languageId, json)>
246 <#assign
247 startdate = getValueForLanguage('startdatum', languageId, json, "first")
248 meta = meta + { "start": startdate?date.iso, "end": "" }
249 />
250 </#if>
251
252 <#if hasValue('einfuehrungText', locale, json)>
253 <#assign data = data + { "einfuehrungText" : getValueForLanguage('einfuehrungText', locale, json, "first") } >
254 <#elseif hasValue(FrontendService.article.getFieldNameByReferenceName(primaryKey, 'einfuehrungText'), locale, json, "first")>
255 <#assign data = data + { "einfuehrungText" : getValueForLanguage(FrontendService.article.getFieldNameByReferenceName(primaryKey, 'einfuehrungText'), locale, json, "first") } >
256 </#if>
257
258 <#if hasContent('endedatum', languageId, json)>
259 <#assign
260 enddate = getValueForLanguage('endedatum', languageId, json, "first")
261 meta = meta + { "end": enddate?date.iso }
262 />
263 </#if>
264
265 <#if hasContent('startzeit', languageId, json)>
266 <#assign
267 startzeit = getValueForLanguage('startzeit', languageId, json, "first")
268 />
269 <#if startzeit?has_content >
270 <#assign meta = meta + { "startzeit": startzeit } />
271 </#if>
272 </#if>
273
274 <#if hasContent('endezeit', languageId, json)>
275 <#assign
276 endezeit = getValueForLanguage('endezeit', languageId, json, "first")
277 meta = meta + { "endezeit": endezeit }
278 />
279 </#if>
280
281 <#if hasContent('ortWCSKASDEORT', languageId, json)>
282 <#assign
283 ortWCSKASDEORT = FrontendService.json.parseAsJson(getValueForLanguage('ortWCSKASDEORT', languageId, json, "first"))
284 ortWCSKASDEORTPrimaryKey = ortWCSKASDEORT.classPK?number
285 ortWCSKASDEORTWebContent = FrontendService.article.getWebcontentByPk(ortWCSKASDEORTPrimaryKey)!""
286 />
287 <#if ortWCSKASDEORTWebContent?has_content >
288 <#assign
289 ortWCSKASDEORTTitle = ortWCSKASDEORTWebContent.getTitle(languageId)!""
290 />
291 <#if ortWCSKASDEORTTitle?has_content >
292 <#assign
293 meta = meta + { "ortWCSKASDEORT": ortWCSKASDEORTTitle }
294 />
295 </#if>
296 </#if>
297 </#if>
298
299
300 <#if hasContent('veranstaltungsnummer', languageId, json)>
301 <#assign
302 verauuid = getValueForLanguage('veranstaltungsnummer', languageId, json, "first")
303 meta = meta + { "verauuid": verauuid }
304 />
305 </#if>
306
307
308 <#if (data.meta)?has_content >
309 <#assign meta = data.meta />
310 </#if>
311
312 <#if !(data.media)?has_content && hasContent('mediumDMTKASDEMEDIUM', languageId, json)>
313 <#assign
314 medium = getValueForLanguage('mediumDMTKASDEMEDIUM', languageId, json, "first")
315 mediaData = getRelatedMediaObject(medium, themeDisplay, languageId, FrontendService, "hd-resolution")
316 />
317 <#assign data = data + { "media": mediaData.url , "meta" : mediaData.meta} >
318
319
320 <#if mediaData.meta?? && mediaData.meta.quelle??>
321 <#assign meta = meta + data.meta + { "quelle": mediaData.meta.quelle } />
322 </#if>
323 </#if>
324
325
326 <#if meta?has_content>
327 <#assign data = data + {"meta": meta } >
328 </#if>
329
330 <#-- END fill meta data -->
331
332 <#if hasContentForSequence('autorenWCSKASDEPERSON', languageId, json)>
333 <#assign
334 journalArticles = getValueForLanguageAnsprechpartner('autorenWCSKASDEPERSON', languageId, json)
335 authors = []
336 />
337 <#list journalArticles as articleString>
338 <#assign article = FrontendService.json.parseAsJson(articleString) />
339 <#if article?has_content && article?is_hash && article.classPK??>
340 <#assign articleDereferenced = FrontendService.person.resolveContactInstanceToPerson(article, languageId)!"" />
341 <#if articleDereferenced?has_content >
342 <#assign
343 author = ""
344 articlePrimaryKey = articleDereferenced.classPK?number
345 articleJsonString = FrontendService.article.getWebcontent(articlePrimaryKey)
346 articleJson = FrontendService.json.parseAsJson(articleJsonString)
347 />
348 <@debugJsonString articleJsonString "ADT_KASDE_DYNAMIC_INTRO-autorenWCSKASDEPERSON" />
349 <#if hasValue('anredetitel', languageId, articleJson)>
350 <#assign author = author + getValueForLanguage('anredetitel', languageId, articleJson, " ") + " ">
351 </#if>
352 <#if hasValue('vorname', languageId, articleJson)>
353 <#assign author = author + getValueForLanguage('vorname', languageId, articleJson, " ") + " ">
354 </#if>
355 <#if hasValue('nachname', languageId, articleJson)>
356 <#assign author = author + getValueForLanguage('nachname', languageId, articleJson, " ") + " ">
357 </#if>
358
359 <#attempt>
360 <#assign href = FrontendService.article.getFriendlyUrl(articlePrimaryKey, languageId, groupId)!"#" >
361 <#recover>
362 <#assign href = "#" >
363 </#attempt>
364 <#if href?has_content && href != "#" && href != "/_404">
365 <#assign author = '<a href="' + href + '">' + author?trim + '</a>'>
366 </#if>
367
368 <#assign authors = authors + [author?trim]>
369 </#if>
370 </#if>
371 </#list>
372 <#if authors?has_content>
373 <#assign data = data + { "author": authors?join(", ") } >
374 </#if>
375 </#if>
376
377 <#if layouttpl?contains("LAYOUT_KASDE_VERANSTALTUNGEN_DETAIL") >
378 <#assign categories = FrontendService.category.getCategoriesToArticle(primaryKey, "VERANSTALTUNGSTYP")! >
379 <#if categories?has_content && categories[0]?has_content >
380 <#assign data = data + { "category": categories[0].getTitle(languageId,true)! } >
381 </#if>
382
383 <#if hasContent('ausgebucht', languageId, json)>
384 <#assign data = data + { "ausgebucht" : getValueForLanguage('ausgebucht', languageId, json, "first") }>
385 </#if>
386
387 <#if hasContent('storniert', languageId, json)>
388 <#assign data = data + { "storniert" : getValueForLanguage('storniert', languageId, json, "first") }>
389 </#if>
390
391 <#elseif layouttpl?contains("LAYOUT_KASDE_PUBLIKATIONEN_DETAIL") >
392 <#assign categories = FrontendService.category.getCategoriesToArticle(primaryKey, "PUBLIKATIONSREIHE")! >
393 <#if categories?has_content && categories[0]?has_content >
394 <#assign data = data + { "category": categories[0].getTitle(languageId,true)! } >
395 </#if>
396 <#else>
397 <#assign categories = FrontendService.category.getCategoriesToArticle(primaryKey, "THEMA")! >
398 <#if categories?has_content && categories[0]?has_content >
399 <#assign data = data + { "category": categories[0].getTitle(languageId,true)! } >
400 </#if>
401 </#if>
402
403
404 <#assign
405 languages = []
406 />
407
408 <#attempt>
409 <#if json["document_pdfDMTBASICDOCUMENT"]?? >
410 <#if availablelanguages?has_content>
411 <#list availablelanguages as pdf_language>
412 <#assign
413 docRefJson = getValueForLanguage('document_pdfDMTBASICDOCUMENT', pdf_language, json, "first")
414 docRef = FrontendService.json.parseAsJson(docRefJson)
415 />
416 <#if docRef?is_hash && pdf_language != languageId >
417 <#assign
418 lang = FrontendService.language.getLocaleByKey(pdf_language)!""
419 docGroupId = docRef["groupId"]?number
420 docUuid = docRef["uuid"]
421 dMTJsonObject = FrontendService.media.getDMTJsonObject( docGroupId, docUuid, locale )
422 dMTLink = FrontendService.media.getLinkToDMT( dMTJsonObject )
423 />
424 <#if lang?has_content>
425 <#assign
426 languages = languages + [
427 {
428 "key": pdf_language,
429 "value": FrontendService.language.getLocaleByKey(pdf_language).getDisplayLanguage(),
430 "url": dMTLink
431 }]
432 />
433 </#if>
434 </#if>
435 </#list>
436 </#if>
437 </#if>
438 <#recover>
439 </#attempt>
440
441 <#if (languages?size > 0)>
442 <#attempt>
443 <#assign
444 data = data + { "languageSelect": {
445 "id": "languageSelect",
446 "name": "languageselect",
447 "entries": languages,
448 "documents": "",
449 "button": "true"
450 }}
451 />
452 <#recover>
453 </#attempt>
454 </#if>
455
456 <@PMIntro "ADT_KASDE_DYNAMIC_INTRO" data AMMetadata AMDatetime "bottom" />
457 ${FrontendService.article.getEditArticleHtml(primaryKey, themeDisplay)}
458
459 <#if data.meta?has_content>
460 <#if data.meta.laufendenummer?has_content !isACColorScheme() && !isVLCColorScheme() && !isDPMColorScheme()>
461 <div>
462 <div id="publicationVerbundPagination">
463 <@AMPublicationCarousel data.meta.laufendenummer data.meta.date data.meta.coverImg />
464 </div>
465 </div>
466 </#if>
467 </#if>
468
469<#elseif (editmode?? && editmode)>
470 <@errorMessage languageUtil.get(locale, "kein.journalArticle.gefunden") "ADT_KASDE_DYNAMIC_INTRO" layouttpl currentUrl />
471</#if>
Die Neuwahl der moldauischen Legislative stellt eine Zäsur für die ehemalige Sowjetrepublik dar – und zwar in mehrfacher Hinsicht. Zum einen hat PAS das beste prozentuale Ergebnis nach Stimmen aller Zeiten für eine politische Partei in der Republik Moldau erzielen können. Zum anderen ist dieser Erfolg u.a. darauf zurückzuführen, dass – wie schon im letzten Präsidentschaftswahlkampf – nicht mehr die bis dato klassischen geopolitischen Differenzen zwischen einer Ausrichtung in Richtung Europa oder Russland die Agenda bestimmt hatten. Vielmehr setze sich PAS glaubwürdig für Reformen zu Demokratie, Rechtsstaat und Marktwirtschaft ein – während die Sozialisten vor allem gegen Sandu und eine angeblich mit ihr verbundene Einmischung westlicher Mächte in die inneren Angelegenheiten der Republik Moldau Stellung bezogen.
Die Präsidentin deutete am Wahlabend das Ergebnis als „Ende der Regierung der Diebe“ – mit Verweis auf das im Februar 2019 gewählte Parlament, das unter demokratisch fragwürdigen Umständen noch unter dem Regime des Oligarchen Plahotniuc gewählt worden war. Dessen Demokratische Partei (PDM) war mit abhängigen „Unabhängigen“ und Proxy-Parteien auf de facto 40 Mandate gekommen – und hat nun unter demokratischeren Bedingungen nicht einmal mehr zwei Prozent der Stimmen auf sich vereinen können. Auch in dieser Hinsicht stellt der Wahlsieg von PAS eine Zäsur dar: erstmals hat mit PAS eine Partei eine Wahl gewonnen, die nicht unter dem Einfluss oligarchischer Strukturen steht.
Als Präsidentin ist Maia Sandu mittlerweile parteilos. Den Vorsitz von PAS hat der langjährige Generalsekretär Igor Grosu übernommen. In entscheidenden Wählerschichten war die Wahl aber eine Art Referendum über Sandus Kurs. Mit PAS verbindet ein erheblicher Teil der Bevölkerung das positive Image von Maia Sandu, die bereits als Premierministerin (Juni – November 2019) und früher als Bildungsministerin konsequent und glaubwürdig für Integrität und Korruptionsbekämpfung eingetreten ist.
Nun steht PAS vor der Herausforderung, das bereits vor der Pandemie wirtschaftlich und sozial angeschlagene Land auf einen gründlichen Reformkurs zu bringen. Dabei dürfte vor allem eine Reform des in erheblichen Teilen mit Korruption verbundenen Justizwesens eine zentrale Rolle spielen. Aber auch in ökonomischer Hinsicht braucht die Republik Moldau dringend Strukturreformen. Bereits der hohe Anteil der Diaspora-Stimmen weist darauf hin, dass vor allem junge, gut ausgebildete Menschen für sich keine Zukunft mehr im Inland sehen. Zwar ist mit einer Annäherung an die EU und entsprechender Unterstützung zu rechnen, jedoch sind die wirtschaftlichen Rückstände kaum in einer Legislaturperiode aufzuholen. Darüber hinaus wird es für PAS auch schwierig sein, in größerem Umfang hinreichend qualifiziertes und verlässliches Personal für Regierung und Verwaltung zu finden, weil große Teile der Eliten ausgewandert sind. Charakteristisch für den Zustand der moldauischen Demokratie ist zudem nach wie vor, dass immerhin noch mehr als fünf Prozent der Wähler für die Shor-Partei gestimmt haben – die sich mittels eines Netzwerks aus sog. „Sozialgeschäften“ durch materielle Zuwendung die Loyalität armer Wähler gesichert hat.
Mit nur drei Parteien im Parlament erfolgt auch eine Konsolidierung des seit Jahren fragmentierten politischen Spektrums der Republik Moldau. U.a. scheiterte an der gesetzlich festgelegten Hürde das Bündnis des Bürgermeisters der zweitgrößten Stadt Balti, Renato Usatii, der in der ersten Wahlrunde der Präsidentschaftswahl immerhin auf 17 Prozent der Stimmen gekommen war und sich als Alternative v.a. für die russischsprachige Wählerschaft präsentiert hatte. Auch die Plattform Würde und Wahrheit (PDA), die ebenso wie PAS der EVP angehört und 2019 mit PAS einen gemeinsamen Wahlblock gebildet hatte, verpasste den Einzug ins Parlament mit weniger als drei Prozent der Stimmen.