Fel uppstod under bearbetning av mallen.
The following has evaluated to null or missing:
==> recordId  [in template "617264#617298#284013" at line 381, column 84]

----
Tip: If the failing expression is known to be 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: ${recordId.getData()}  [in template "617264#617298#284013" at line 381, column 82]
	- Reached through: @debugthis title="Record Id - Query" ...  [in template "617264#617298#284013" at line 381, column 13]
----
1<#-- STAFF PICKS TEMPLATE --> 
2<#--Settings needed for local REST API call --> 
3<#assign portalSiteID = "" /><#-- Portal side id needed to query records --> 
4<#assign agencyID = "" /><#-- Agency ID needed for cover fetching. Can be obtained e.g. from SOLR --> 
5<#assign agencyMemberID = "" /> 
6<#assign agencyName = "" /><#-- Needed for cover fetching --> 
7<#assign portNumber = "16520" /><#-- Needed for all API calls --> 
8<#assign queryLimit = 8 /><#-- Limits how many records are shown at maximum in list view --> 
9<#assign portalUrl = "" /> 
10<#assign portalUrlSecure = "" /><#-- Used for fetching covers and get rid of mixed content warning --> 
11<#assign csAddress = "http://arena-central" /> <#-- used to be arena-central:16517 --> 
12<#assign lsAddress = "http://arena-local:16520" /> 
13<#assign friendlyUrl = "" /> 
14<#assign sitePrefix = "/web/arena" /> 
15 
16<#-- If friendlyUrl is not set, get it from the organization --> 
17<#if friendlyUrl == "" > 
18    <#assign groupLocalService = serviceLocator.findService("com.liferay.portal.kernel.service.GroupLocalService")/> 
19    <#assign group = groupLocalService.getGroup(groupId)/> 
20    <#assign friendlyUrl = group.getFriendlyURL() /> 
21    <#assign sitePrefix = "/web${friendlyUrl}" /> 
22</#if> 
23 
24<#-- Get server and page URLs --> 
25<#assign serviceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext() /> 
26<#assign themeDisplay = serviceContext.getThemeDisplay() /> 
27<#assign portalUrl = themeDisplay.getPortalURL() /> 
28<#assign portalUrlSecure = portalUrl /> 
29<#if portalUrlSecure?index_of("https") == -1> 
30    <#assign portalUrlSecure = portalUrl?replace("http", "https") /> 
31</#if> 
32<#if portalUrl?index_of("https") != -1> 
33    <#assign portalUrl = portalUrl?replace("https", "http") /> 
34</#if> 
35 
36<#assign virtualURL = portalUrlSecure?replace("https://","") /> 
37 
38<#assign crdPageUrl = portalUrlSecure + "/results"/> 
39<#assign searchPageUrl = portalUrlSecure + "/search"/> 
40<#assign fullPageUrl = portalUrl + themeDisplay.getURLCurrent() /> 
41<#assign urlMatcher = themeDisplay.getURLCurrent()?matches("^(/[a-z]{2}(_[A-Z]{2})?)?/web/[^/]+")> 
42<#list urlMatcher as algFriendlyUrl> 
43    <#assign crdPageUrl = portalUrlSecure + algFriendlyUrl + "/results"/> 
44    <#assign searchPageUrl = portalUrlSecure + algFriendlyUrl + "/search"/> 
45</#list> 
46 
47 
48<#-- General variables needed in multiple macros --> 
49<#assign journalArticleResourceService = serviceLocator.findService("com.liferay.journal.service.JournalArticleResourceLocalService") /> 
50<#assign articleResourcePK = journalArticleResourceService.getArticleResourcePrimKey(groupId, .vars['reserved-article-id'].data)?number /> 
51<#assign journalArticleService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") /> 
52<#assign journalArticle = journalArticleService.getArticle(groupId, .vars['reserved-article-id'].data) /> 
53 
54<#--Makes a query to the REST API and requests records. This function should be used to call the API within this template. 
55Returns the result as a simpleHash object --> 
56<#function queryAPI query limit> 
57    <#assign fullRequestUrl = "${lsAddress}/local-rest/api/v1/portalsites/${portalSiteID}/records?query=${httpUtilUnsafe.encodeURL(query)}&count=${limit}&isShowExtended=false&sortDirection=Descending&sortField=Relevance&agencyMemberId=${agencyMemberID}&decorationNames=Ratings"/> 
58    <#assign response = httpUtilUnsafe.URLtoString(fullRequestUrl) /> 
59    <#assign result = jsonFactoryUtil.looseDeserialize(response) /> 
60    <#return result /> 
61</#function> 
62 
63<#-- Makes a query to Central REST API to get portal site settings --> 
64<#function getPortalSiteSettingsFromCentralService> 
65    <#assign requestUrlPortalSites = "${csAddress}/central-rest/api/v1/configs/portalsites?vhost=${httpUtilUnsafe.encodeURL(virtualURL)}&friendlyUrl=${httpUtilUnsafe.encodeURL(friendlyUrl)}" /> 
66    <#assign response = httpUtilUnsafe.URLtoString(requestUrlPortalSites) /> 
67    <#assign result = jsonFactoryUtil.looseDeserialize(response) /> 
68    <#return result /> 
69</#function> 
70 
71<#-- Makes a query to Central REST API to get Member settings to extract Agency ID from --> 
72<#function getAgencySettingsFromCentralService> 
73    <#assign requestUrlMemberAgencies = "${csAddress}/central-rest/api/v1/configs/agencymembers/${agencyMemberID}" /> 
74    <#assign response = httpUtilUnsafe.URLtoString(requestUrlMemberAgencies) /> 
75    <#assign result = jsonFactoryUtil.looseDeserialize(response) /> 
76    <#return result /> 
77</#function> 
78 
79<#function getServerSettingsFromCentralService> 
80    <#assign portalSites = "" /> 
81    <#assign returnValue = "OK" /> 
82    <#assign portalSites = "" /> 
83    <#assign memberData = "" /> 
84    <#assign favoriteAgencyName = "" /> 
85    <#attempt> 
86        <#assign portalSites = getPortalSiteSettingsFromCentralService() /> 
87        <#if portalSites.id??> 
88            <#assign portalSiteID = portalSites.id?string /> 
89            <#assign favoriteAgencyName = portalSites.mainGroup.properties["Favourite Agency Member"] /> 
90        <#else> 
91            <#assign requestUrlPortalSites = "${csAddress}/central-rest/api/v1/configs/portalsites?vhost=${httpUtilUnsafe.encodeURL(virtualURL)}&friendlyUrl=${httpUtilUnsafe.encodeURL(friendlyUrl)}" /> 
92            <#assign response = httpUtilUnsafe.URLtoString(requestUrlPortalSites) /> 
93        </#if> 
94        <#if favoriteAgencyName != ""> 
95        <#-- Go through portalSites.agencyMemberSummaries to find the one with matching favoriteAgencyName --> 
96            <#list portalSites.agencyMemberSummaries as summary> 
97                <#if summary.name == favoriteAgencyName> 
98                    <#assign agencyMemberID = summary.id?string /> 
99                </#if> 
100            </#list> 
101        </#if> 
102        <#recover> 
103            <#assign returnValue =  "Portal Sites failed" /> 
104    </#attempt> 
105    <#if agencyMemberID != "" && returnValue == "OK"> 
106        <#attempt> 
107            <#assign memberData = getAgencySettingsFromCentralService() /> 
108            <#if memberData.agency??> 
109                <#assign agencyID = memberData.agency.id /> 
110                <#assign agencyName = memberData.agency.name /> 
111            </#if> 
112            <#recover> 
113                <#assign returnValue =  "Agency member data failed" /> 
114        </#attempt> 
115    </#if> 
116 
117    <#return returnValue /> 
118</#function> 
119 
120<#macro debugServerInfo> 
121    <div class="serverInfo hidden debug informative"> 
122        <p class="idsForRestAPI"> 
123            <strong>Portal Site ID:</strong> ${portalSiteID}<br /> 
124            <strong>Agency ID:</strong> ${agencyID}<br /> 
125            <strong>Agency name:</strong> ${agencyName}<br /> 
126            <strong>Member ID:</strong> ${agencyMemberID} 
127 
128        </p> 
129        <p class="serverURL"> 
130            <strong>Portal site URL:</strong> ${portalUrl}<br /> 
131            <strong>Portal site URL Secure:</strong> ${portalUrlSecure}<br /> 
132            <strong>Virtual URL:</strong> ${virtualURL}<br /> 
133            <strong>Friendly URL:</strong> ${friendlyUrl} 
134        </p> 
135    </div> 
136</#macro> 
137 
138<#-- Outputs a hidden debug tag with information. --> 
139<#macro debugthis title message link isinformative> 
140    <#assign cssClass = "hidden debug" /> 
141    <#if isinformative> 
142        <#assign cssClass = "hidden debug informative" /> 
143    </#if> 
144    <div class="${cssClass}"> 
145        <h4>Debug - ${title}</h4> 
146        <#if link == ""> 
147            <p>${message}</p> 
148        <#else> 
149            <p><a href="${link}">${message}</a></p> 
150        </#if> 
151    </div> 
152</#macro> 
153 
154<#macro showTags> 
155    <#assign tagsService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetTagLocalService") /> 
156    <#assign tagsAsset = tagsService.getTags("com.liferay.journal.model.JournalArticle", articleResourcePK) /> 
157 
158<#-- Services for tag links --> 
159    <#assign layoutUid = journalArticle.getLayoutUuid() /> 
160 
161    <h3><@liferay.language key="staffpicks.detail.header.tags" /></h3> 
162    <@debugthis title="tags" message="Tag links don't work yet." isinformative=true link="" /> 
163    <@debugthis title="tags" message=layoutUid isinformative=true link="" /> 
164    <ul class="staffpick-article-tags"> 
165        <#list tagsAsset as tag> 
166            <#assign tagNameLink = tag.getName() /> 
167            <li class="staffpick-article-tagentry"><a class="staffpicks-article-tag-link" href="${sitePrefix}/-/tag/${tagNameLink}">${tagNameLink}</a></li> 
168        </#list> 
169    </ul> 
170</#macro> 
171 
172<#macro showArticleAuthor> 
173    <#if articleAuthor?? && articleAuthor.getData() != ""> 
174        <p class="staffpick-article-author-name"> 
175            <@liferay.language_format key="staffpicks.detail.articleauthor" arguments=[articleAuthor.getData()] /> 
176            <#--${languageUtil.format(locale, "staffpicks.detail.articleauthor", [articleAuthor.getData()])}--> 
177        </p> 
178    </#if> 
179</#macro> 
180 
181<#macro showDate dateString> 
182    <#assign localization = languageUtil.get(locale,"staffpicks.detail.dateformat") /> 
183    <#assign timeString = "MMM d yyyy" /> 
184    <#if localization != "staffpicks.detail.dateformat"> 
185        <#assign timeString = localization /> 
186    </#if> 
187    <#assign originalLocale = locale /> 
188    <#setting locale = localeUtil.getDefault() /> 
189    <#assign time = dateString?datetime("EEE, dd MMM yyyy hh:mm:ss ZZZZ") /> 
190    <#setting locale = originalLocale /> 
191    ${time?string[timeString]} 
192</#macro> 
193 
194<#macro showRecord recordInfo> 
195<#-- Arena 4 CRD link --> 
196    <#assign crdPageFullUrl = "${crdPageUrl}?p_p_id=crDetailWicket_WAR_arenaportlet&p_p_lifecycle=1&p_p_state=normal&p_r_p_arena_urn%3Aarena_search_item_id=${recordInfo.id}&p_r_p_arena_urn%3Aarena_agency_name=${agencyName}" /> 
197 
198    <li class="similar-record record-${recordInfo.id}"> 
199        <@debugthis title="Record" message="ID: ${recordInfo.id}" link="" isinformative=true /> 
200        <a class="similar-record-link" href="${crdPageFullUrl}"> 
201            <img class="similar-record-cover" src="${portalUrlSecure}/local-rest/api/v1/portalsites/${portalSiteID}/agencies/${agencyID}/records/${httpUtilUnsafe.encodeURL(recordInfo.id)}/cover" alt="" /> 
202            <span class="similar-record-title">${recordInfo.fields.title}</span> 
203            <#if recordInfo.fields.authors?? && recordInfo.fields.authors?size gt 0 && recordInfo.fields.authors[0]??> 
204            <span class="similar-record-author">${recordInfo.fields.authors[0].name} 
205                </#if> 
206        </a> 
207        <#if recordInfo.rating??> 
208            <@showRatings rating=recordInfo.rating recordtitle=recordInfo.fields.title /> 
209        </#if> 
210    </li> 
211</#macro> 
212 
213<#macro showRatings rating recordtitle> 
214    <#assign ratingFive = (rating/2) /> 
215    <#assign ratingLimit = 5 /> 
216    <div class="staffpicks-rating"> 
217        <#assign ratingFiveString = ratingFive?string.number /> 
218        <span class="sr-only"><@liferay.language_format key="staffpicks.detail.rating" arguments=[recordtitle, ratingFiveString, ratingLimit]/></span> 
219        <#list 1..ratingLimit as x> 
220            <#if (x-0.5) == ratingFive> 
221                <span class="arena-rating rating-half-full"><i class="icon-star-half-full"></i></span> 
222            <#elseif x <= ratingFive> 
223                <span class="arena-rating rating-full"><i class="icon-star"></i></span> 
224            <#else> 
225                <span class="arena-rating rating-empty"><i class="icon-star-empty"></i></span> 
226            </#if> 
227        </#list> 
228    </div> 
229</#macro> 
230 
231<#macro showSimilarRecords result> 
232    <h3><@liferay.language key="staffpicks.detail.header.similartitles" /></h3> 
233    <#assign searchString = "" /> 
234    <#attempt> 
235        <#if result.fields.subjects?size gt 0> 
236            <#assign searchString = searchString + "(" /> 
237            <#list result.fields.subjects as subject> 
238                <#assign searchString = searchString + "subject:\"${subject}\"" /> 
239                <#if subject_index < result.fields.subjects?size-1> 
240                    <#assign searchString = searchString + " OR " /> 
241                </#if> 
242            </#list> 
243            <#assign searchString = searchString +") AND (" /> 
244        <#else> 
245            <#assign searchString = searchString +"(" /> 
246        </#if> 
247        <#recover> 
248    </#attempt> 
249    <#attempt> 
250        <#if result.fields.languages?size gt 0> 
251            <#list result.fields.languages as language> 
252                <#assign searchString = searchString + "language:\"${language}\"" /> 
253                <#if language_index < result.fields.languages?size-1> 
254                    <#assign searchString = searchString + " OR " /> 
255                </#if> 
256            </#list> 
257        </#if> 
258        <#recover> 
259    </#attempt> 
260    <#attempt> 
261        <#assign searchString = searchString +") AND " /> 
262        <#assign searchString = searchString+"mediaclass:\"${result.fields.mediaClass}\" AND " /> 
263        <#assign searchString = searchString +"NOT uberkey:\"${result.uberkey}\"" /> 
264        <#recover> 
265    </#attempt> 
266 
267    <#assign similarBooks = ""> 
268 
269    <#attempt> 
270        <#assign similarBooks = queryAPI(searchString, queryLimit) /> 
271        <ul class="staffpick-similar-records"> 
272            <#list similarBooks.records as record> 
273                <@showRecord recordInfo = record /> 
274            </#list> 
275        </ul> 
276        <#recover> 
277            <@debugthis title="Similar records" message="Similar records not looked for because an error happened in API call or processing it." isinformative=false link="" /> 
278    </#attempt> 
279    <@debugthis title="Similar records search string" message=searchString isinformative=true link="" /> 
280    <#assign fullRequestUrl = '${lsAddress}/local-rest/api/v1/portalsites/${portalSiteID}/records?query=${searchString}&count=${queryLimit}&isShowExtended=false&sortDirection=Descending&sortField=Relevance&agencyMemberId=${agencyMemberID}'/> 
281    <@debugthis title="Similar records search URL" message="Similar records query" isinformative=true link=fullRequestUrl /> 
282</#macro> 
283 
284<#-- Prints a debug button that toggles the visibility of elements with debug CSS class --> 
285<#macro toggleDebug> 
286    <script type="text/javascript"> 
287        function toggleDebugMessages() { 
288            YUI().use("node",function(Y) { 
289                Y.all(".debug").each(function() { 
290                    this.toggleClass("hidden"); 
291                }); 
292            }); 
293        }; 
294    </script> 
295    <a href="javascript:void(0);" onclick="toggleDebugMessages()" class="btn btn-info toggle-debug-button"><i class="icon-eye-open"></i> Debug</a> 
296</#macro> 
297 
298<link rel="stylesheet" type="text/css" href="//cdn.axiell.com/arena/staffpicks/staffpicks.css"> 
299<div class="staffpick-article"> 
300    <#assign status = "OK" /> 
301    <#assign status = getServerSettingsFromCentralService() /> 
302 
303    <@debugServerInfo /> 
304 
305    <#if status != "OK"> 
306        <@debugthis isinformative=false title="Central Service Settings failed" message="Failed with ${status}" link=""/> 
307    </#if> 
308 
309    <div class="back-button-container"> 
310        <a class="staffpick-back-link arena-link-button" href="javascript:void(0);" onclick="window.history.back();"><@liferay.language key="back" /></a> 
311    </div> 
312    <style>.portlet-asset-categories-navigation, .staff-picks-introduction { display: none; }</style> 
313    <#assign searchQuery = "" /> 
314    <#assign result = "" /> 
315    <#assign recordInfo = "" /> 
316    <#if recordId?? && recordId.getData() != ""> 
317        <#if recordId.getData()?index_of("id:") == -1> 
318            <#assign searchQuery = 'id:"${recordId.getData()}"' /> 
319        <#else> 
320            <#assign searchQuery = recordId.getData() /> 
321        </#if> 
322        <#attempt> 
323            <#assign result = queryAPI(searchQuery, 1) /> 
324            <#assign recordInfo = result.records[0] /> 
325 
326            <#recover> 
327                <#assign recordInfo = { 
328                "fields" : { 
329                "title" :  "${.vars['reserved-article-title'].data}" 
330
331                } /> 
332                <#assign fullRequestUrl = "${lsAddress}/local-rest/api/v1/portalsites/${portalSiteID}/records?query=${httpUtilUnsafe.encodeURL(searchQuery,true)}&count=1&isShowExtended=false&sortDirection=Descending&sortField=Relevance&agencyMemberId=${agencyMemberID}"/> 
333                <@debugthis isinformative=false title="API call failed with this url" message=fullRequestUrl link=fullRequestUrl /> 
334 
335        </#attempt> 
336    <#else> 
337        <#assign recordInfo = { 
338        "fields" : { 
339        "title" :  "${.vars['reserved-article-title'].data}" 
340
341        } /> 
342    </#if> 
343 
344 
345 
346 
347    <div class="row"> 
348        <div class="col-xs-12 col-sm-4 col-lg-3 cover-column"> 
349 
350            <#if recordInfo.id??> 
351            <#--Arena 4 CRD link --> 
352                <#assign crdPageFullUrl = "${crdPageUrl}?p_p_id=crDetailWicket_WAR_arenaportlet&p_p_lifecycle=1&p_p_state=normal&p_r_p_arena_urn%3Aarena_search_item_id=${recordInfo.id}&p_r_p_arena_urn%3Aarena_agency_name=${agencyName}" /> 
353 
354                <a class="record-link" href="${crdPageFullUrl}"> 
355                    <#assign assetService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService") /> 
356                    <#assign thumbnailPath = "" /> 
357                    <#attempt> 
358                        <#assign serviceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext()> 
359                        <#assign themeDisplay = serviceContext.getThemeDisplay() /> 
360                        <#assign thumbnailPath = journalArticle.getArticleImageURL(themeDisplay) /> 
361                        <#recover> 
362                    </#attempt> 
363                    <#if journalArticle.getSmallImage() && thumbnailPath != ""> 
364                        <img class="cover-image cover-overwrite" alt="" src="${thumbnailPath}" /> 
365                    <#else> 
366                        <img class="cover-image" alt="" src="${portalUrlSecure}/local-rest/api/v1/portalsites/${portalSiteID}/agencies/${agencyID}/records/${httpUtilUnsafe.encodeURL(recordInfo.id)}/cover" /> 
367                    </#if> 
368                    <span class="alg-button alg-button--inverted gotoCRDButton"><@liferay.language key="staffpicks.detail.viewbook" /></span> 
369                </a> 
370            </#if> 
371            <@toggleDebug /> 
372        </div> 
373        <div class="col-xs-12 col-sm-8 col-lg-9 staffpick-detail"> 
374            <div class="staffpick-article-title"> 
375                <h2>${recordInfo.fields.title}</h2> 
376            </div> 
377            <#-- Special debug which cannot be in a regular macro --> 
378            <#if recordInfo.id??> 
379                <@debugthis title="Record Id - API" message="Record ID from API: ${recordInfo.id}" isinformative=true link="" /> 
380            </#if> 
381            <@debugthis title="Record Id - Query" message="Record ID from Query: ${recordId.getData()}" isinformative=true link="" /> 
382            <#if recordInfo.id?? && (recordInfo.id != recordId.getData() )> 
383                <@debugthis title="Record id missmatch" message="Query ID and API ID do not match!" isinformative=false link="" /> 
384            </#if> 
385 
386            <#if recordInfo.fields?? && recordInfo.fields.authors?? && recordInfo.fields.authors?size gt 0 && recordInfo.fields.authors[0]??> 
387                <div class="staffpick-article-author"> 
388                    <a class="staffpick-article-author-link" href="${searchPageUrl}?p_p_id=searchResult_WAR_arenaportlet&p_p_lifecycle=1&p_p_state=normal&p_r_p_arena_urn%3Aarena_facet_queries=&p_r_p_arena_urn%3Aarena_search_query=${recordInfo.fields.authors[0].name}&p_r_p_arena_urn%3Aarena_search_type=solr&p_r_p_arena_urn%3Aarena_sort_advice=field%3DRelevance%26direction%3DDescending"> 
389                        <@liferay.language_format key="staffpicks.detail.author" arguments=[recordInfo.fields.authors[0].name] /> 
390                    </a> 
391                </div> 
392            </#if> 
393            <div class="staffpick-article-text"> 
394                ${articleText.getData()} 
395            </div> 
396            <div class="staffpick-article-recommendedby-date row"> 
397                <div class="staffpick-article-recommeded-by col-xs-12 col-sm-7"> 
398                    <@showArticleAuthor /> 
399                </div> 
400                <div class="staffpick-article-date col-xs-12 col-sm-5"> 
401                    <@showDate dateString=.vars['reserved-article-create-date'].data /> 
402                </div> 
403            </div> 
404        </div> 
405    </div> 
406    <#--<div class="row tags-container"> 
407        <div class="col-xs-12"> 
408            <@showTags /> 
409        </div> 
410    </div>--> 
411    <div class="row similar-records-container"> 
412        <div class="col-xs-12"> 
413            <@showSimilarRecords result=recordInfo /> 
414        </div> 
415    </div> 
416</div> 

Sök

Språk

Kategorimeny