Changes for page Home

Last modified by Jesse Veentjer on 06-5-2024 05:01

From version 221.1
edited by Jesse Veentjer
on 06-5-2024 05:01
Change comment: Nieuwe afbeelding Preloader_oranje.gif toegevoegd
To version 219.32
edited by Jesse Veentjer
on 19-2-2024 11:41
Change comment: There is no comment for this version

Summary

Details

Page properties
Content
... ... @@ -1,16 +1,129 @@
1 +(% class="floatinginfobox wbrechts" %)
2 +(((
3 +(% class="wbrb" %)
4 +(% aria-label="aanhetwerk.gif image widget" contenteditable="false" data-xwiki-image-style-alignment="center" role="region" tabindex="-1" data-widget="image" %)[[image:attach:aanhetwerk.gif||data-xwiki-image-style-alignment="center"]](% title="Click and drag to resize" %)​(% aria-label="aanhetwerk.gif image widget" contenteditable="false" data-xwiki-image-style-alignment="center" role="region" tabindex="-1" style="background-color:rgba(220,220,220,0.5)" %)[[image:data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==||draggable="true" height="15" role="presentation" title="Click and drag to move" width="15"]]
5 +
6 +(% class="wbtoc" %)
7 +(((
8 + (% class="wbtocheader" %)Inhoud
9 +
10 +(% aria-label="macro:toc widget" contenteditable="false" role="region" tabindex="-1" %)
11 +(((
12 +(% class="macro" data-macro="startmacro:toc|-|" data-widget="xwiki-macro" data-xwiki-dom-updated="true" %)
13 +(((
14 +(% class="macro-placeholder hidden" %)
15 +(((
16 +macro:toc
17 +)))
18 +
19 +(% class="wikitoc" %)
20 +* [[Welkom op de WB Kennisbank>>doc:null||anchor="HWelkomopdeWBKennisbank"]]
21 +* [[Nieuws>>doc:null||anchor="HNieuws"]]
22 +)))
23 +
24 +(% style="background-color:rgba(220,220,220,0.5)" %)[[image:data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==||height="15" role="presentation" title="Click and drag to move" width="15"]]
25 +)))
26 +)))
27 +)))
28 +
1 1  (% class="wblinks" %)
2 2  (((
3 -{{velocity}}
4 -#if($isGuest)
5 -#set($loginscherm = 'https://kennis.wardenburg.nl/login/XWiki/XWikiLogin')
6 -=Welkom op onze Kennisbank=
7 -Toegang tot (kwalitatief) goede informatie is een uitdaging waar iedereen mee worstelt, met het lanceren van dit digitale archief waarin we kennis, de laatste ontwikkelingen (nieuws), bestanden en ideeën kunnen plaatsen en delen gaan we het vinden van informatie eenvoudiger maken. In de kern maakt kennisbank het mogelijk om informatie te genereren organiseren en delen
31 += **Welkom op de WB Kennisbank** =
8 8  
9 -{{showhide showmessage="We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:" hidemessage="Verstop voorbeelden" effectduration="1"}}
33 +(% aria-label="macro:velocity widget" contenteditable="false" role="region" tabindex="-1" %)
34 +(((
35 +(% class="macro" data-macro="startmacro:velocity|-||-|#if(!$isGuest)
36 +##gebruiker is ingelogd
37 +(% style=~"font-size:18px;font-style: italic;~" ~%)**[[Zorg dat je op de hoogte bent van de kennisbank huisregels!>>doc:.Werkwijze.Kennisbank.Huisregels kennisbank.WebHome||target=_blank]]**
38 +#end" data-widget="xwiki-macro" data-xwiki-dom-updated="true" %)
39 +(((
40 +(% class="macro-placeholder hidden" %)
41 +(((
42 +macro:velocity
43 +)))
44 +
45 +(% style="font-size:18px; font-style:italic" %)**//[[Zorg dat je op de hoogte bent van de kennisbank huisregels!>>doc:.Werkwijze.Kennisbank.Huisregels kennisbank.WebHome||target="_blank"]]//**
46 +)))
47 +
48 +(% style="background:url(~"https://kennis.wardenburg.nl/webjars/wiki%3Axwiki/xwiki-platform-ckeditor-webjar/15.8/plugins/widget/images/handle.png~") rgba(220, 220, 220, 0.5); left:0px; top:-15px" %)[[image:data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==||height="15" role="presentation" title="Click and drag to move" width="15"]]
49 +)))
50 +
51 +Toegang tot (kwalitatief) goede informatie is een uitdaging waar iedereen mee worsteld, met het lanceren van dit digitale archief waarin we kennis, de laatste ontwikkelingen (nieuws), bestanden en ideeën kunnen plaatsen en delen gaan we het vinden van informatie eenvoudiger maken. In de kern maakt kennisbank het mogelijk om informatie te genereren organiseren en delen
52 +
53 +(% aria-label="macro:showhide widget" contenteditable="false" role="region" tabindex="-1" %)
54 +(((
55 +(% class="macro" data-macro="startmacro:showhide|-|showmessage=~"We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:~" hidemessage=~"Verstop voorbeelden~" effectduration=~"1~"|-|✅ Toegang tot informatie , verbreed je kennis naar nieuwe onderwerpen.
56 +* Gedeelde kennis is makkelijk doorzoekbaar, je kan naar specifieke delen van pagina’s linken met een weblink!
57 +* Kennis van collega's wordt met elkaar gedeeld. Het voorkomt dat je zelf het wiel moet uitvinden terwijl er al informatie van een collega over een bepaald onderwerp is.
58 +* //Help collega's en klanten door hen in staat te stellen zichzelf te helpen//[[(Nb. zonder in te loggen zien bezoekers ook de 'Openbaar' folder)>>doc:.Openbaar.WebHome]]
59 +
60 +✅ Dankzij de nieuwssectie kunnen ook de laatste ontwikkelingen per 'nieuwsonderwerp' op de kennisbank geplaatst worden.
61 +
62 +✅ Deel je kennis door het vast te leggen in de kennisbank
63 +* Of het nou gaat om een bekende fout in een apparaat/softwareversie of een handige manier om een installatie te configureren, als je tijd hebt geïnvesteerd om een probleem oplossen is het jammer wanneer bijvoorbeeld een collega moet zwoegen om tot dezelfde oplossing te komen.
64 +
65 +✅ Zorgt voor transparantie en duidelijkheid op kennisgebied
66 +* Uitleg en handleidingen van installaties maar ook onze werkprocessen kunnen vastgelegd en gedeeld worden met de kennisbank.
67 +* Ervaringen en discussies kunnen per onderwerp geplaatst en besproken worden." data-widget="xwiki-macro" data-xwiki-dom-updated="true" %)
68 +(((
69 +(% class="macro-placeholder hidden" %)
70 +(((
71 +macro:showhide
72 +)))
73 +
74 +(% class="macro" data-macro="startmacro:velocity|-||-|#set($discard = $xwiki.jsx.use(~"Macros.ShowHideMacro~"))
75 +#set($mparams = $wikimacro.parameters)
76 +#if(!$mparams)
77 + #set($mparams = $xcontext.macro.params)
78 +#end
79 +#if($mparams.id)
80 + #set($id = $util.convertToAlphaNumeric($mparams.id))
81 +#end
82 +#set($showmessage = $escapetool.xml($mparams.showmessage))
83 +#set($hidemessage = $escapetool.xml($mparams.hidemessage))
84 +#set($divstyle = $escapetool.xml($mparams.style))
85 +#set($effect = $escapetool.xml($mparams.effect))
86 +#if($effect == ~"appear~" || $effect == ~"fade~")
87 + #set($effect = ~"fadeToggle~")
88 +#elseif ($effect == ~"blind~" || $effect == ~"slide~")
89 + #set($effect = ~"slideToggle~")
90 +#end
91 +#set($effectduration = $mathtool.mul(1000,$mparams.effectduration))
92 +(% #if($divstyle && $divstyle!=~"~") style=~"$\{divstyle}~" #end ~%)
93 +(((
94 +(% class=~"showhidebutton~" ~%)
95 +(((
96 +\{\{html clean=false}}
97 +<a href=~"javascript:void(0)~" #if($id && $id!=~"~")id=~"showhidebuttontext$\{id}~" #end data-show-duration=~"$effectduration~" data-show-effect=~"$effect~" data-show-message=~"$showmessage~" data-hide-message=~"$hidemessage~">$mparams.showmessage</a>
98 +\{\{/html}}
99 +)))
100 +(% class=~"showhidecontent~" #if($id && $id!=~"~")id=~"showhidecontent$\{id}~" #end style=~"display: none;~" ~%)
101 +(((
102 +(((
103 +$xcontext.macro.content
104 +)))
105 +)))
106 +)))" %)
107 +(((
108 +(% class="macro-placeholder hidden" %)
109 +(((
110 +macro:velocity
111 +)))
112 +
113 +(((
114 +(% class="showhidebutton" %)
115 +(((
116 +(% data-macro="startmacro:html|-|clean=~"false~"|-|<a href=~"javascript:void(0)~" data-show-duration=~"1000~" data-show-effect=~"toggle~" data-show-message=~"We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:~" data-hide-message=~"Verstop voorbeelden~">We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:</a>" class="macro hidden macro-placeholder" %)macro:html(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<a href=~"javascript:void(0)~" data-show-duration=~"1000~" data-show-effect=~"toggle~" data-show-message=~"We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:~" data-hide-message=~"Verstop voorbeelden~">We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:</a>" %)[[We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:>>path:javascript:void(0)||data-hide-message="Verstop voorbeelden" data-show-duration="1000" data-show-effect="toggle" data-show-message="We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:"]]
117 +)))
118 +
119 +(% class="showhidecontent" style="display: none;" %)
120 +(((
121 +(((
10 10  ✅ Toegang tot informatie , verbreed je kennis naar nieuwe onderwerpen.
123 +
11 11  * Gedeelde kennis is makkelijk doorzoekbaar, je kan naar specifieke delen van pagina’s linken met een weblink!
12 12  * Kennis van collega's wordt met elkaar gedeeld. Het voorkomt dat je zelf het wiel moet uitvinden terwijl er al informatie van een collega over een bepaald onderwerp is.
13 -* //Help collega's en klanten door hen in staat te stellen zichzelf te helpen//[[(Nb. zonder in te loggen zien bezoekers ook de 'Openbaar' folder)>>path:/Main/Openbaar/]]
126 +* //Help collega's en klanten door hen in staat te stellen zichzelf te helpen//[[(Nb. zonder in te loggen zien bezoekers ook de 'Openbaar' folder)>>doc:.Openbaar.WebHome]]
14 14  
15 15  ✅ Dankzij de nieuwssectie kunnen ook de laatste ontwikkelingen per 'nieuwsonderwerp' op de kennisbank geplaatst worden.
16 16  
... ... @@ -22,33 +22,16854 @@
22 22  
23 23  * Uitleg en handleidingen van installaties maar ook onze werkprocessen kunnen vastgelegd en gedeeld worden met de kennisbank.
24 24  * Ervaringen en discussies kunnen per onderwerp geplaatst en besproken worden.
25 -{{/showhide}}
26 -{{html}}
27 -<a href=$loginscherm>
28 -<button class="login-btn" onclick="this.classList.add('clicked')"><span>Login</span></button>
29 -</a>
30 -{{/html}}
31 -Door in te loggen krijg je meer functies op de kennisbank, log in met je voornaam.achternaam (hetzelfde als je e-mail zonder het @wardenburg.nl gedeelte).
32 -#else
33 -=Zoeken=
34 -[[Klik hier om de zoekopdracht te wissen>>path:/Main ||target="_self"]]
35 -{{include reference="Main.Search" /}}
138 +)))
139 +)))
140 +)))
141 +)))
142 +)))
143 +
144 +(% style="background:url(~"https://kennis.wardenburg.nl/webjars/wiki%3Axwiki/xwiki-platform-ckeditor-webjar/15.8/plugins/widget/images/handle.png~") rgba(220, 220, 220, 0.5); left:0px; top:-15px" %)[[image:data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==||height="15" role="presentation" title="Click and drag to move" width="15"]]
145 +)))
146 +
36 36  ----
37 -* [[Klik hier voor uitleg hoe de kennisbank werkt>>path:/Main/Werkwijze/Kennisbank/]]. //Als je verdwaald raakt kan je altijd linksbovenin op het logo klikken, dan ga je terug naar deze homepagina. //
38 -* [[Voor discussies,vragen en/of opmerkingen over de kennisbank kan je aan dit teamkanaal meedoen>>url:https://teams.microsoft.com/l/team/19%3aAxo-k8j1CVRGXTb0t3Dc6tjNDNudeTZjcP_KZVFR5381%40thread.tacv2/conversations?groupId=4da292cd-ff72-4d4c-adc5-8aa3dfc4ae3f&tenantId=42b413cc-67db-4507-a4a6-ce30ce798022||rel="noopener noreferrer" target="_blank"]].
148 +
149 +* [[Klik hier voor uitleg hoe de kennisbank werkt>>doc:Main.Werkwijze.Kennisbank.WebHome]]. //Als je verdwaald raakt kan je altijd linksbovenin op het logo klikken, dan ga je terug naar deze homepagina.  //
150 +* [[Voor discussies,vragen en/of opmerkingen over de kennisbank kan je aan dit teamkanaal meedoen>>https://teams.microsoft.com/l/team/19%3aAxo-k8j1CVRGXTb0t3Dc6tjNDNudeTZjcP_KZVFR5381%40thread.tacv2/conversations?groupId=4da292cd-ff72-4d4c-adc5-8aa3dfc4ae3f&tenantId=42b413cc-67db-4507-a4a6-ce30ce798022||rel="noopener noreferrer" target="_blank"]].
151 +
152 +(% aria-label="macro:velocity widget" contenteditable="false" role="region" tabindex="-1" %)
153 +(((
154 +(% class="macro" data-macro="startmacro:velocity|-||-|
155 +#if($isGuest)
156 +#set($loginscherm = 'https://kennis.wardenburg.nl/login/XWiki/XWikiLogin')
157 +==**Inloggen**==
158 +Door in te loggen krijg je meer functies op de kennisbank. [[Log hier in op de wiki >>$loginscherm ||target=~"_blank~"]] met je voornaam.achternaam (hetzelfde als je e-mail zonder het @wardenburg.nl gedeelte).
159 +
160 +Ondervind je problemen met het inloggen? [[Neem dan contact op met Automatisering.>>https://teams.microsoft.com/l/chat/0/0?users=jesse.veentjer@wardenburg.nl&topicname=Xwiki|target=_blank]]
39 39  #end
40 40  #if(!$isGuest)
41 -= Nieuws =
42 -{{blogpostlist blog="Nieuws.WebHome" limit="6" layout="cards" layoutParams="displayTitle=true|useSummary=true"/}}
163 +##gebruiker is ingelogd
164 +(% class=~"nieuws~" ~%)
165 += **Nieuws** =
166 +Hieronder vind je de laatste (10) nieuwsberichten, [[een overzicht van alle nieuwsberichten en een onderverdeling van de categorieën vindt je op de nieuws homepagina>>doc:Nieuws.WebHome]].
167 +
168 +(% class=~"nieuwstabel~" ~%)
169 +(((
170 +\{\{blogpostlist blog=~"Nieuws.WebHome~" limit=~"10~" layout=~"cards~" layoutParams=~"displayTitle=true|useSummary=true~"/}}
171 +)))
172 +#end" data-widget="xwiki-macro" data-xwiki-dom-updated="true" %)
173 +(((
174 +(% class="macro-placeholder hidden" %)
175 +(((
176 +macro:velocity
177 +)))
178 +
179 +(% id="HNieuws" class="nieuws" %)
180 += **Nieuws** =
181 +
182 +Hieronder vind je de laatste (10) nieuwsberichten, [[een overzicht van alle nieuwsberichten en een onderverdeling van de categorieën vindt je op de nieuws homepagina>>doc:Nieuws.WebHome]].
183 +
184 +(% class="nieuwstabel" %)
185 +(((
186 +(% class="macro" data-macro="startmacro:blogpostlist|-|blog=~"Nieuws.WebHome~" limit=~"10~" layout=~"cards~" layoutParams=~"displayTitle=true|useSummary=true~"" %)
187 +(((
188 +(% class="macro-placeholder hidden" %)
189 +(((
190 +macro:blogpostlist
191 +)))
192 +
193 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Nieuwsbrief januari 2024~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=~"" %)
194 +(((
195 +(% class="macro-placeholder hidden" %)
196 +(((
197 +macro:blogPostLayoutCards
198 +)))
199 +
200 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
201 +(((
202 +(% class="macro-placeholder hidden" %)
203 +(((
204 +macro:include
205 +)))
206 +
207 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
208 +(((
209 +(% class="macro-placeholder hidden" %)
210 +(((
211 +macro:include
212 +)))
213 +
214 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
215 +#set($blogClassname = 'Blog.BlogClass')
216 +#set($blogTemplate = 'Blog.BlogTemplate')
217 +#set($blogSheet = 'Blog.BlogSheet')
218 +## Blog entries
219 +#set($blogPostClassname = 'Blog.BlogPostClass')
220 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
221 +#set($blogPostSheet = 'Blog.BlogPostSheet')
222 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
223 +#set($oldArticleClassname = 'XWiki.ArticleClass')
224 +## Categories
225 +#set($blogCategoryClassname = 'Blog.CategoryClass')
226 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
227 +#set($blogCategorySheet = 'Blog.CategorySheet')
228 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
229 +#set($oldBlogCategoryClassname = 'Blog.Categories')
230 +#set($defaultCategoryParent = 'Blog.Categories')
231 +## Style
232 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
233 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
234 +## Clientside scripts
235 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
236 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
237 +## Misc
238 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
239 +#set($isBlogPost = $doc.getObject($blogPostClassname))
240 +#set($defaultBlogSpace = 'Blog')
241 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
242 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
243 +##
244 +##
245 +##
246 +#**
247 + * Displays an image, taken from the blog style document.
248 + *
249 + * @param $imgName The name of the icon from icons set to use.
250 + *#
251 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
252 +(((
253 +(% class="macro-placeholder hidden" %)
254 +(((
255 +macro:velocity
256 +)))
257 +)))
258 +)))
259 +
260 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
261 +##
262 +##
263 +## Import the blog skin and javascripts.
264 +$!xwiki.ssx.use($blogStyleDocumentName)##
265 +$!xwiki.jsx.use($blogScriptsDocumentName)##
266 +##
267 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
268 +#template('hierarchy_macros.vm')##
269 +##
270 +##
271 +#**
272 + * Prints a blog. This is the main macro used in the BlogSheet.
273 + *
274 + * @param blogDoc the XDocument holding the blog definition object.
275 + *###
276 +#macro(printBlog $blogDoc)
277 + \{\{include reference='Blog.CreatePost'/}}
278 +
279 + ## Use the blogPostList macro to display the blogposts
280 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
281 + ## do not support FTM the monthly and weekly blog display types
282 + #getBlogDisplayType($blogDoc $displayType)
283 + #if ($displayType == 'weekly' || $displayType == 'monthly')
284 + #getBlogEntries($blogDoc $entries)
285 + #displayBlog($entries 'index' true true)
286 + #displayNavigationLinks($blogDoc)
287 + #else
288 + #getBlogDisplayType($blogDoc $displayType)
289 + #set ($paginated = 'no')
290 + #if ($displayType == 'paginated')
291 + #set ($paginated = 'yes')
292 + #end
293 + #getBlogPostsLayout($blogDoc $postsLayout)
294 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
295 + #end
43 43  #end
44 -{{/velocity}}
297 +##
298 +##
299 +##
300 +#**
301 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
302 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
303 + * all entries).
304 + *
305 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
306 + *###
307 +#macro(showBlogInfo $blogDoc)
308 + #if($blogDoc.getObject($blogClassname))
309 + ## Keep testing for inline action for backward compatibility with older blogs.
310 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
311 + #macro(displayProperty $blogDoc $propname)
312 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
313 + : $blogDoc.display($propname)
314 + #end
315 + #displayProperty($blogDoc 'title')
316 + #displayProperty($blogDoc 'description')
317 + #displayProperty($blogDoc 'displayType')
318 + #displayProperty($blogDoc 'itemsPerPage')
319 + #displayProperty($blogDoc 'postsLayout')
320 + #displayProperty($blogDoc 'postsLayoutParameters')
321 + #else
322 + $blogDoc.display('description')
323 + #end
324 + #elseif($doc.fullName == $blogSheet)
325 += $services.localization.render('blog.code.blogsheet') =
326 + \{\{translation key='blog.code.sheetexplanation'/}}
327 + #else
328 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
329 + #end
330 +#end
331 +##
332 +##
333 +##
334 +#**
335 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
336 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
337 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
338 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
339 + *
340 + * @param space A <tt>String</tt>, the name of the space where to search.
341 + * @param blogDoc The resulting XDocument.
342 + *###
343 +#macro(getBlogDocument $space $blogDoc)
344 + #set ($result = $NULL)
345 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
346 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
347 + ## identify the right blog based on a configuration object in a WebPreferences page.
348 + #set ($spaceReference = $services.model.resolveSpace($space))
349 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
350 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
351 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
352 + #if ($preferencesObj)
353 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
354 + #end
355 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
356 + #if (~"$!result~" == '')
357 + ## First, try the Space.WebHome, for a whole-space blog
358 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
359 + #if(!$result.getObject($blogClassname))
360 + ## Second, try the Space.Blog document
361 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
362 + #if(!$result.getObject($blogClassname))
363 + ## Third, try searching for a blog document in the current space
364 + ## Prevent the query fail when the space contains dots '.'
365 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
366 + #if($blogDocs.size() > 0)
367 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
368 + #else
369 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
370 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
371 + #if($blogDocs.size() > 0)
372 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
373 + #else
374 + ## Last, fallback to Blog.WebHome, the default blog
375 + #set($result = $xwiki.getDocument('Blog.WebHome'))
376 + #end
377 + #end
378 + #end
379 + #end
380 + #end
381 + #set ($blogDoc = $NULL)
382 + #setVariable (~"$blogDoc~" $result)
383 +#end
384 +##
385 +##
386 +##
387 +#**
388 + * Retrieve the blog title.
389 + *
390 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
391 + * @param title The resulting title.
392 + *###
393 +#macro(getBlogTitle $blogDoc $title)
394 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
395 + #set ($title = $NULL)
396 + #setVariable (~"$title~" $!blogDoc.displayTitle)
397 +#end
398 +##
399 +##
400 +##
401 +#**
402 + * Retrieve the blog description.
403 + *
404 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
405 + * property set.
406 + * @param description The resulting description.
407 + *###
408 +#macro(getBlogDescription $blogDoc $description)
409 + #getBlogProperty($blogDoc 'description' '' $result)
410 + #set ($description = $NULL)
411 + #setVariable (~"$description~" $result)
412 +#end
413 +##
414 +##
415 +##
416 +#**
417 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
418 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
419 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
420 + * month), or all.
421 + *
422 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
423 + * @param entries The resulting list of entries to display, a list of XDocument names.
424 + *###
425 +#macro(getBlogEntries $blogDoc $entries)
426 + #if (!$entries)
427 + #setVariable (~"$entries~" [])
428 + #end
429 + #getAllBlogPostsQuery($query)
430 + #isDefaultBlog($blogDoc $isDefault)
431 + #set($queryParams = \{})
432 + #if ($isDefault)
433 + #getCategoryAllBlogPostsQuery($query)
434 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
435 + #set($discard = $queryParams.put('creator', $xcontext.user))
436 + #set($discard = $queryParams.put('space', $blogDoc.space))
437 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
438 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
439 + #else
440 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
441 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
442 + #set($discard = $queryParams.put('space', $blogPostsLocation))
443 + #set($discard = $queryParams.put('parent', $blogDoc.space))
444 + #end
445 + #getBlogDisplayType($blogDoc $displayType)
446 + #if($displayType == 'weekly')
447 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
448 + #elseif($displayType == 'monthly')
449 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
450 + #elseif($displayType == 'all')
451 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
452 + #else
453 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
454 + #end
455 +#end
456 +##
457 +##
458 +##
459 +#**
460 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
461 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
462 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
463 + * (10 if not defined).
464 + *
465 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
466 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
467 + * refined to restrict to a given space, or to a given search criteria, etc.
468 + * @param entries The resulting list of entries to display, a list of XDocument names.
469 + * @param queryParams The parameters to bind with the query.
470 + *###
471 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
472 + #if (!$entries)
473 + #setVariable (~"$entries~" [])
474 + #end
475 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
476 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
477 + #bindQueryParameters($countQueryObj $queryParams)
478 + #bindQueryParameters($queryObj $queryParams)
479 + #set($totalEntries = $countQueryObj.count())
480 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
481 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
482 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
483 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
484 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
485 +#end
486 +##
487 +##
488 +##
489 +#**
490 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
491 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
492 + * digit year). Initially the current week is displayed.
493 + *
494 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
495 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
496 + * refined to restrict to a given space, or to a given search criteria, etc.
497 + * @param entries The resulting list of entries to display, a list of XDocument names.
498 + * @param queryParams The parameters to bind with the query.
499 + *###
500 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
501 + #if (!$entries)
502 + #setVariable (~"$entries~" [])
503 + #end
504 + #getRequestedWeek($weekDate)
505 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
506 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
507 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
508 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
509 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
510 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
511 + #bindQueryParameters($countQueryObj $queryParams)
512 + #bindQueryParameters($queryObj $queryParams)
513 + #set($totalEntries = $countQueryObj.count())
514 + #set($discard = $entries.addAll($queryObj.execute()))
515 +#end
516 +##
517 +##
518 +##
519 +#**
520 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
521 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
522 + * digit year). Initially the current month is displayed.
523 + *
524 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
525 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
526 + * refined to restrict to a given space, or to a given search criteria, etc.
527 + * @param entries The resulting list of entries to display, a list of XDocument names.
528 + * @param queryParams The parameters to bind with the query.
529 + *###
530 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
531 + #if (!$entries)
532 + #setVariable (~"$entries~" [])
533 + #end
534 + #getRequestedMonth($monthDate)
535 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
536 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
537 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
538 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
539 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
540 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
541 + #bindQueryParameters($countQueryObj $queryParams)
542 + #bindQueryParameters($queryObj $queryParams)
543 + #set($totalEntries = $countQueryObj.count())
544 + #set($discard = $entries.addAll($queryObj.execute()))
545 +#end
546 +##
547 +##
548 +##
549 +#**
550 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
551 + *
552 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
553 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
554 + * refined to restrict to a given space, or to a given search criteria, etc.
555 + * @param entries The resulting list of entries to display, a list of XDocument names.
556 + * @param queryParams The parameters to bind with the query.
557 + *###
558 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
559 + #if (!$entries)
560 + #setVariable (~"$entries~" [])
561 + #end
562 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
563 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
564 + #bindQueryParameters($countQueryObj $queryParams)
565 + #bindQueryParameters($queryObj $queryParams)
566 + #set($totalEntries = $countQueryObj.count())
567 + #set($discard = $entries.addAll($queryObj.execute()))
568 +#end
569 +##
570 +##
571 +##
572 +#**
573 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
574 + *
575 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
576 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
577 + * refined to restrict to a given space, or to a given search criteria, etc.
578 + * @param queryParams The parameters to bind with the query.
579 + * @param entries The resulting list of entries to display, a list of XDocument names.
580 + *###
581 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
582 + #if (!$entries)
583 + #setVariable (~"$entries~" [])
584 + #end
585 + #set($query = ~"$\{query} and isPublished.value = 0~")
586 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
587 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
588 + #bindQueryParameters($countQueryObj $queryParams)
589 + #bindQueryParameters($queryObj $queryParams)
590 + #set($totalEntries = $countQueryObj.count())
591 + #set($discard = $entries.addAll($queryObj.execute()))
592 +#end
593 +##
594 +##
595 +##
596 +#**
597 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
598 + *
599 + * @param entries The resulting list of entries to display, a list of XDocument names.
600 + *###
601 +#macro(getGlobalBlogEntries $entries)
602 + #if (!$entries)
603 + #setVariable (~"$entries~" [])
604 + #end
605 + #getAllBlogPostsQuery($query)
606 + #set($totalEntries = $services.query.hql($query).count())
607 + #set($defaultItemsPerPage = 20)
608 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
609 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
610 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
611 +#end
612 +#**
613 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
614 + * blog, nor specify a range or an ordering criteria.
615 + *
616 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
617 + *
618 + * @param query The basic query for selecting blog entries.
619 + *#
620 +#macro(getBlogEntriesBaseQuery $query)
621 + #getAllBlogPostsQuery($query)
622 +#end
623 +#**
624 + * Return the Query for selecting the all wiki blog posts without filtering
625 + *
626 + * @param query The basic query for selecting blog entries.
627 + *#
628 +#macro(getAllBlogPostsQuery $query)
629 + #set ($query = $NULL)
630 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
631 + IntegerProperty hidden, DateProperty publishDate
632 + where doc.fullName <> '$blogPostTemplate' and
633 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
634 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
635 + hidden.id.id = obj.id and hidden.id.name='hidden' and
636 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
637 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
638 +#end
639 +##
640 +##
641 +##
642 +###**
643 + * Return the Query for selecting the all wiki blog posts with categories filtering
644 + *
645 + * @param query The basic query for selecting blog entries.
646 + *###
647 +#macro(getCategoryAllBlogPostsQuery $query)
648 + #set ($query = $NULL)
649 + #getAllBlogPostsQuery($baseQuery)
650 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
651 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
652 +#end
653 +##
654 +##
655 +##
656 +#**
657 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
658 + * week), monthly (all entries in a month), or all.
659 + *
660 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
661 + * property set.
662 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
663 + *###
664 +#macro(getBlogDisplayType $blogDoc $displayType)
665 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
666 + #set ($displayType = $NULL)
667 + #setVariable (~"$displayType~" $result)
668 +#end
669 +##
670 +##
671 +##
672 +#**
673 + * Displays a list of entries.
674 + *
675 + * @param entries The entries to display, a list of XDocument names.
676 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
677 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
678 + * used values: index, single, category, search, unpublished, hidden.
679 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
680 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
681 + * displayed alone on their page since it's the page title which is used in this case)
682 + *###
683 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
684 + #set($blogDay = '')
685 + (% class=~"hfeed $!\{displaying}~" ~%)(((
686 + (% class=~"blogDay~" ~%)(((
687 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
688 + #getEntryObject($entryDoc $entryObj)
689 + ## Although all entries should have one of the two objects, better check to be sure.
690 + #if(~"$!\{entryObj}~" != '')
691 + #getEntryDate($entryDoc $entryObj $entryDate)
692 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
693 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
694 + #if($blogDay != $entryDateStr)
695 + #if($blogDay != '')
696 + )))
697 + (% class=~"blogDay~" ~%)(((
698 + #end
699 + #displayBlogDate($entryDate)
700 + #set ($blogDay = $entryDateStr)
701 + #end
702 + ## Finally, display the entry.
703 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
704 + #end
705 + #end
706 + )))## blogDay
707 + )))## hfeed
708 +#end
709 +##
710 +##
711 +##
712 +#**
713 + * Get the entry object, either a new BlogPost or an old Article.
714 + *
715 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
716 + * @param entryObj The resulting xobject of the blog post.
717 + *###
718 +#macro(getEntryObject $entryDoc $__entryObj)
719 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
720 + #if(!$result)
721 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
722 + #end
723 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
724 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
725 + ## overwritten in this case but it's less likely to have such a variable defined before.
726 + #set ($__entryObj = $NULL)
727 + #setVariable (~"$__entryObj~" $result)
728 +#end
729 +##
730 +##
731 +##
732 +#**
733 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
734 + * the document creation date, but can be edited by the user.
735 + *
736 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
737 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
738 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
739 + *###
740 +#macro(getEntryDate $entryDoc $entryObj $result)
741 + #set ($result = $NULL)
742 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
743 +#end
744 +##
745 +##
746 +##
747 +#**
748 + * Displays a date, nicely formatted as a calendar page.
749 + *
750 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
751 + *###
752 +#macro(displayBlogDate $date)
753 + #set($year = $xwiki.formatDate($date, 'yyyy'))
754 + ## 3 letter month name, like Jan, Dec.
755 + #set($month = $xwiki.formatDate($date, 'MMM'))
756 + ## Uncomment to get a full length month name, like January, December.
757 + ## TODO: this could be defined somewhere in the blog style.
758 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
759 + #set($day = $xwiki.formatDate($date, 'dd'))
760 + (% class=~"blogdate~" ~%)
761 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
762 +#end
763 +##
764 +##
765 +##
766 +#**
767 + * Displays a blog article: management tools, header, content, footer.
768 + *
769 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
770 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
771 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
772 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
773 + * when they're displayed alone on their page since it's the page title which is used in this case)
774 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
775 + *###
776 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
777 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
778 + #isPublished($entryObj $isPublished)
779 + #isHidden($entryObj $isHidden)
780 + #if($doc.fullName == $entryDoc.fullName)
781 + (% class=~"hentry single-article~" ~%)(((
782 + #else
783 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
784 + #end
785 + #if ($shouldDisplayActions)
786 + #displayEntryTools($entryDoc $entryObj)
787 + #end
788 + #if($shouldDisplayTitle)
789 + #displayEntryTitle($entryDoc $entryObj)
790 + #end
791 + #if($doc.fullName == $entryDoc.fullName)
792 + #if(!$isPublished)
793 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
794 + #elseif($isHidden)
795 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
796 + #end
797 + #end
798 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
799 + #displayEntryFooter($entryDoc $entryObj)
800 + )))## hentry
801 +#end
802 +##
803 +##
804 +##
805 +#**
806 + * Checks if the provided blog is published or not.
807 + *
808 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
809 + * @param isPublished The resulting boolean, true if the entry is considered published.
810 + *###
811 +#macro(isPublished $entryObj $isPublished)
812 + #set ($isPublished = $NULL)
813 + ## This should work for both old articles, which don't have the 'published' property at all, and
814 + ## are considered published by default, and new entries, that should have 1 if published.
815 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
816 + #setVariable (~"$isPublished~" true)
817 + #else
818 + #setVariable (~"$isPublished~" false)
819 + #end
820 +#end
821 +##
822 +##
823 +##
824 +#**
825 + * Checks if the provided blog is hidden or not.
826 + *
827 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
828 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
829 + *###
830 +#macro(isHidden $entryObj $isHidden)
831 + #set ($isHidden = $NULL)
832 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
833 + ## are considered visible by default, and new entries, that should have 1 if hidden.
834 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
835 + #setVariable (~"$isHidden~" true)
836 + #else
837 + #setVariable (~"$isHidden~" false)
838 + #end
839 +#end
840 +##
841 +##
842 +##
843 +#**
844 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
845 + *
846 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
847 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
848 + *###
849 +#macro(displayEntryTools $entryDoc $entryObj)
850 + #if($xcontext.action == 'view')
851 + (% class=~"blog-entry-toolbox~" ~%)(((
852 + #displayPublishButton($entryDoc $entryObj)
853 + #displayHideShowButton($entryDoc $entryObj)
854 + #displayEditButton($entryDoc $entryObj)
855 + #displayDeleteButton($entryDoc $entryObj)
856 + )))
857 + #end
858 +#end
859 +##
860 +##
861 +##
862 +#**
863 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
864 + *
865 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
866 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
867 + * @todo AJAX calls.
868 + *###
869 +#macro(displayPublishButton $entryDoc $entryObj)
870 + #isPublished($entryObj $isPublished)
871 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
872 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
873 + #end
874 +#end
875 +##
876 +##
877 +##
878 +#**
879 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
880 + *
881 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
882 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
883 + *###
884 +#macro(displayHideShowButton $entryDoc $entryObj)
885 + #isPublished($entryObj $isPublished)
886 + #isHidden($entryObj $isHidden)
887 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
888 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
889 + #set ($queryString = \{
890 + 'xredirect' : $thisURL,
891 + 'form_token' : $services.csrf.getToken()
892 + })
893 + #if ($isHidden)
894 + #set ($discard = $queryString.putAll(\{
895 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
896 + 'comment' : $services.localization.render('blog.code.madevisible')
897 + }))
898 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
899 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
900 + #else
901 + #set ($discard = $queryString.putAll(\{
902 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
903 + 'comment' : $services.localization.render('blog.code.hid')
904 + }))
905 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
906 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
907 + #end
908 + #end
909 +#end
910 +##
911 +##
912 +##
913 +#**
914 + * Displays the edit button to those that can edit the article.
915 + *
916 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
917 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
918 + *###
919 +#macro(displayEditButton $entryDoc $entryObj)
920 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
921 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
922 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
923 + #end
924 +#end
925 +##
926 +##
927 +##
928 +#**
929 + * Displays the delete button to those that can edit the article.
930 + *
931 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
932 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
933 + * @todo AJAX calls.
934 + *###
935 +#macro(displayDeleteButton $entryDoc $entryObj)
936 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
937 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
938 + #end
939 +#end
940 +##
941 +##
942 +##
943 +#**
944 + * Displays the title of the entry.
945 + *
946 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
947 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
948 + *###
949 +#macro(displayEntryTitle $entryDoc $entryObj)
950 + #if($doc.fullName == $entryDoc.fullName)
951 + (% class=~"entry-title~" ~%)
952 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
953 + #else
954 + (% class=~"entry-title~" ~%)
955 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
956 + #end
957 +#end
958 +##
959 +##
960 +##
961 +#**
962 + * Displays the body of the entry.
963 + *
964 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
965 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
966 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
967 + *###
968 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
969 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
970 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
971 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
972 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
973 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
974 + ))) ## entry-content
975 + (% class=~"clearfloats~" ~%)((()))
976 +#end
977 +##
978 +##
979 +##
980 +#**
981 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
982 + * of the <tt>extract</tt> field (if not empty).
983 + *
984 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
985 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
986 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
987 + * @param entryContent The resulting content.
988 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
989 + * <tt>onlyExtract</tt> is <tt>true</tt>)
990 + *###
991 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
992 + #if ($onlyExtract)
993 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
994 + ## of the content.
995 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
996 + #end
997 + #if(~"$!macro.result~" == '')
998 + #set($macro.result = $entryObj.getProperty('content').value)
999 +#* Disabled until the content can be cleanly cut.
1000 +* #if($onlyExtract && $result.length()>$maxchars)
1001 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
1002 +* #set($i = $i + 1)
1003 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
1004 +* #end
1005 +## *###
1006 + #elseif (!$removeEllipsis)
1007 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
1008 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
1009 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
1010 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
1011 + #end
1012 + #end
1013 + #set ($entryContent = $NULL)
1014 + #setVariable (~"$entryContent~" $macro.result)
1015 +#end
1016 +##
1017 +##
1018 +##
1019 +#**
1020 + * Displays the footer of the entry.
1021 + *
1022 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
1023 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
1024 + *###
1025 +#macro(displayEntryFooter $entryDoc $entryObj)
1026 + (% class=~"entry-footer~" ~%)(((
1027 + #isPublished($entryObj $isPublished)
1028 + (% class='entry-author-label' ~%)
1029 + #if($isPublished)
1030 + \{\{translation key='blog.code.postedby'/}} ##
1031 + #else
1032 + \{\{translation key='blog.code.createdby'/}} ##
1033 + #end
1034 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
1035 + #getEntryDate($entryDoc $entryObj $entryDate)
1036 + #listCategories($entryObj) #*
1037 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
1038 + ## we assume cannot be more than 3 seconds.
1039 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
1040 + #if ($showcomments)
1041 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
1042 + #end ##
1043 + #if($entryDoc != $doc) ##
1044 + #displayEntryBlogLocation($entryDoc $entryObj) ##
1045 + #end
1046 + )))## entry-footer
1047 +#end
1048 +##
1049 +##
1050 +#**
1051 + * Display the blog for the entry (if it is not the currently displayed blog)
1052 + *
1053 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
1054 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
1055 + *###
1056 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
1057 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
1058 + #if(~"$!blogPostsLocation~" != ~"~") ##
1059 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
1060 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
1061 + #if($doc.documentReference != $blogDocRef) ##
1062 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
1063 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
1064 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
1065 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
1066 + )))(%~%)##
1067 + #end
1068 + #end
1069 + #end
1070 +#end
1071 +##
1072 +##
1073 +##
1074 +##
1075 +#**
1076 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
1077 + *
1078 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
1079 + *###
1080 +#macro(listCategories $entryObj)
1081 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
1082 + #set($categories = $entryObj.getProperty('category').value)
1083 + #set($first = true)
1084 + #if($categories.size() > 0)
1085 + #foreach($category in $categories)
1086 + #set($categoryDoc = $!xwiki.getDocument($category))
1087 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
1088 + #if($foreach.count == 1)
1089 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
1090 + #else
1091 + , ##
1092 + #end##
1093 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
1094 + #end##
1095 + #end##
1096 + #end
1097 + #end
1098 +#end
1099 +##
1100 +##
1101 +##
1102 +#**
1103 + * Displays blog pagination links (older and newer entries).
1104 + *
1105 + * @param blogDoc the XDocument holding the blog definition object.
1106 + *###
1107 +#macro(displayNavigationLinks $blogDoc)
1108 + (% class=~"clearfloats~" ~%)((()))
1109 + #getBlogDisplayType($blogDoc $displayType)
1110 + #if($displayType == 'weekly')
1111 + (% class=~"pagingLinks~" ~%)(((
1112 + #getRequestedWeek($weekDate)
1113 + $weekDate.addWeeks(-1)##
1114 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
1115 + #sep()
1116 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
1117 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
1118 + )))
1119 + #elseif($displayType == 'monthly')
1120 + (% class=~"pagingLinks~" ~%)(((
1121 + #getRequestedMonth($monthDate)
1122 + $monthDate.addMonths(-1)##
1123 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
1124 + #sep()
1125 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
1126 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
1127 + )))
1128 + #elseif($displayType == 'all')
1129 + #else
1130 + ## Paginated
1131 + #if(($totalPages > 1))
1132 + #set($queryString = '')
1133 + #foreach($p in $request.getParameterNames())
1134 + #if($p != 'page' && $p != 'ipp')
1135 + #foreach($v in $request.getParameterValues($p))
1136 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
1137 + #end
1138 + #end
1139 + #end
1140 + (% class=~"pagingLinks~" ~%)(((
1141 + #if ($currentPageNumber < $totalPages)
1142 + #set($currentPageNumber = $currentPageNumber + 1)
1143 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
1144 + #set($currentPageNumber = $currentPageNumber - 1)
1145 + #end
1146 + #if ($currentPageNumber > 1)
1147 + #if ($currentPageNumber < $totalPages)
1148 + #sep()
1149 + #end
1150 + #set($currentPageNumber = $currentPageNumber - 1)
1151 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
1152 + #set($currentPageNumber = $currentPageNumber + 1)
1153 + #end
1154 + (% class=~"clear~" ~%)(%~%)
1155 + )))## pagingLinks
1156 + #end
1157 + #end
1158 +#end
1159 +##
1160 +##
1161 +##
1162 +#**
1163 + * Displays a message box with ~"publish~" icon.
1164 + *
1165 + * @param message A text message concerning blog article publishing
1166 + *###
1167 +#macro(publishMessageBox $message)
1168 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
1169 +#end
1170 +#**
1171 + * Displays a message box with ~"show/hide~" icon.
1172 + *
1173 + * @param message A text message concerning blog article hiding
1174 + *###
1175 +#macro(hideMessageBox $message)
1176 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
1177 +#end
1178 +##
1179 +##
1180 +##
1181 +#**
1182 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
1183 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
1184 + *
1185 + * @param monthDate The resulting week, a JODATime MutableDateTime.
1186 + *###
1187 +#macro(getRequestedWeek $weekDate)
1188 + #set ($weekDate = $NULL)
1189 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
1190 + #if(~"$!\{request.year}~" != '')
1191 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
1192 + #end
1193 + #if(~"$!\{request.week}~" != '')
1194 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
1195 + #end
1196 +#end
1197 +##
1198 +##
1199 +##
1200 +#**
1201 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
1202 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
1203 + *
1204 + * @param monthDate The resulting month, a JODATime MutableDateTime.
1205 + *###
1206 +#macro(getRequestedMonth $monthDate)
1207 + #set ($monthDate = $NULL)
1208 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
1209 + #if(~"$!\{request.year}~" != '')
1210 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
1211 + #end
1212 + #if(~"$!\{request.month}~" != '')
1213 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
1214 + #end
1215 +#end
1216 +##
1217 +##
1218 +##
1219 +#**
1220 + * Retrieve a blog property (title, display type, etc).
1221 + *
1222 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
1223 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
1224 + * @param defaultValue The default value to use in case the blog object does not define one.
1225 + * @param propertyValue The resulting value.
1226 + *###
1227 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
1228 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
1229 + #if($result == '')
1230 + #set($result = $defaultValue)
1231 + #end
1232 + #set ($propertyValue = $NULL)
1233 + #setVariable (~"$propertyValue~" $result)
1234 +#end
45 45  
1236 +#**
1237 + * If an error occurs when executing an action, set a specific response status and display an error message.
1238 + *
1239 + * @param status The response status.
1240 + * @param text The user readable error to be displayed. Can be a translation key.
1241 + * @param parameters The parameters to use when decoding the translation key.
1242 + *###
1243 +#macro(blog__actionResponseError $status $text $parameters)
1244 + $response.setStatus($status)
1245 + #if($request.ajax)
1246 + $services.localization.render($text, $!parameters)
1247 + #else
1248 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
1249 + #end
1250 +#end
1251 +##
1252 +##
1253 +##
1254 +#**
1255 + * Check if a blog is the Default blog (The one in the 'Blog' space).
1256 + *
1257 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
1258 + * @param isDefault The resulting boolean.
1259 + *###
1260 +#macro(isDefaultBlog $blogDoc $isDefault)
1261 + #set ($result = false)
1262 + #if ($blogDoc.space == 'Blog')
1263 + #set ($result = true)
1264 + #end
1265 + #setVariable(~"$isDefault~" $result)
1266 +#end
1267 +##
1268 +##
1269 +##
1270 +#**
1271 + * Retrieve the blog posts location (space).
1272 + *
1273 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
1274 + * @param postsLocation The resulting location.
1275 + *###
1276 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
1277 + #getBlogDocument($blogSpace $blogDoc)
1278 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
1279 + #set ($postsLocation = $NULL)
1280 + #setVariable (~"$postsLocation~" $result)
1281 +#end
1282 +##
1283 +##
1284 +##
1285 +#**
1286 + * Retrieve the blog categories location (space).
1287 + *
1288 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
1289 + * @param categoriesLocation The resulting location.
1290 + *###
1291 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
1292 + #getBlogDocument($blogSpace $blogDoc)
1293 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
1294 + #set ($postsLocation = $NULL)
1295 + #setVariable (~"$categoriesLocation~" $result)
1296 +#end
1297 +###**
1298 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
1299 + * for example there is 4 different panel contexts:
1300 + * aBlog.aPost or aBlog.WebHome
1301 + * aCategorySpace.aCategory
1302 + * aCategorySpace.WebHome
1303 + * Blog.aPost or Blog.WebHome
1304 + *
1305 + * @param query The query for selecting blog entries.
1306 + * @param queryParams The parameters to bind with the generated query.
1307 + * @param targetDoc The document in which the articles will be displayed.
1308 + *###
1309 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
1310 + #set ($query = $NULL)
1311 + #set ($queryParams = $NULL)
1312 + #getCategoryAllBlogPostsQuery($resultQuery)
1313 + #set ($resultQueryParams = \{})
1314 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
1315 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
1316 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
1317 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
1318 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
1319 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
1320 + #elseif($targetDoc.getObject($blogCategoryClassname))
1321 + ## Get all posts that are in a category aCategorySpace.aCategory
1322 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
1323 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
1324 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
1325 + ## Get all posts that are in a category aCategorySpace.%
1326 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
1327 + ## Exclude incategorized posts
1328 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
1329 + #if ($targetDoc.space == $defaultBlogSpace)
1330 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
1331 + #end
1332 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
1333 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
1334 + #else
1335 + ## Get all posts in blog space aBlog
1336 + #getAllBlogPostsQuery($resultQuery)
1337 + #getBlogPostsLocation($targetDoc.space $postsLocation)
1338 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
1339 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
1340 + #end
1341 + #setVariable(~"$query~" $resultQuery)
1342 + #setVariable(~"$queryParams~" $resultQueryParams)
1343 +#end
1344 +##
1345 +##
1346 +##
1347 +###**
1348 + * Display blog posts based on the context where the posts are displayed.
1349 + * for example there is 4 different panel contexts:
1350 + * aBlog.aPost or aBlog.WebHome
1351 + * aCategorySpace.aCategory
1352 + * aCategorySpace.WebHome
1353 + * Blog.aPost or Blog.WebHome
1354 + *
1355 + * @param targetDoc The document in which the articles will be displayed.
1356 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
1357 + * @param layout Layout of the the posts to display
1358 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
1359 + * @param limit the number of posts to display
1360 + *###
1361 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
1362 + #if ($postLayout == 'full')
1363 + #set ($macro.paginated = 'yes')
1364 + #end
1365 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
1366 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
1367 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
1368 + #if (~"$!layout~" == '')
1369 + #set ($layout = $postsLayout)
1370 + #end
1371 + #if ($postsVisiblity == 'recent')
1372 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
1373 + #elseif($postsVisiblity == 'unpublished')
1374 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
1375 + #end
1376 + #elseif($targetDoc.getObject($blogCategoryClassname))
1377 + ## Display all posts that are in a category aCategorySpace.aCategory
1378 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
1379 + #getBlogPostsLayout($blogDoc $postsLayout)
1380 + #if (~"$!layout~" == '')
1381 + #set ($layout = $postsLayout)
1382 + #end
1383 + #if ($postsVisiblity == 'recent')
1384 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
1385 + #elseif($postsVisiblity == 'unpublished')
1386 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
1387 + #end
1388 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
1389 + ## Display all posts that are in a category aCategorySpace.%
1390 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
1391 + #getBlogPostsLayout($blogDoc $postsLayout)
1392 + #if (~"$!layout~" == '')
1393 + #set ($layout = $postsLayout)
1394 + #end
1395 + #if ($postsVisiblity == 'recent')
1396 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
1397 + #elseif($postsVisiblity == 'unpublished')
1398 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
1399 + #end
1400 + #else
1401 + ## Display all posts in blog space aBlog
1402 + #getBlogDocument($targetDoc.space $blogDoc)
1403 + #getBlogPostsLayout($blogDoc $postsLayout)
1404 + #if (~"$!layout~" == '')
1405 + #set ($layout = $postsLayout)
1406 + #end
1407 + #if ($postsVisiblity == 'recent')
1408 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
1409 + #elseif($postsVisiblity == 'unpublished')
1410 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
1411 + #end
1412 + #end
1413 +#end
1414 +##
1415 +##
1416 +##
1417 +#**
1418 + * Bind parameters to a query object.
1419 + *
1420 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
1421 + * @param queryParams the query parameters.
1422 + *###
1423 +#macro(bindQueryParameters $queryObj $queryParams)
1424 + #set ($output = $queryObj)
1425 + #foreach( $key in $queryParams.keySet() )
1426 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
1427 + #end
1428 + #setVariable(~"$queryObj~" $output)
1429 +#end
1430 +##
1431 +##
1432 +##
1433 +#**
1434 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
1435 + *
1436 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
1437 + * property set.
1438 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
1439 + *###
1440 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
1441 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
1442 + #set ($postsLayout = $NULL)
1443 + #setVariable (~"$postsLayout~" $res)
1444 +#end
1445 +##
1446 +##
1447 +##
1448 +#**
1449 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
1450 + *
1451 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
1452 + * @param blogDoc The resulting XDocument.
1453 + *###
1454 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
1455 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
1456 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
1457 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
1458 + #else
1459 + ## Fallback to Blog.WebHome, the default blog
1460 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
1461 + #end
1462 + #set ($blogDoc = $NULL)
1463 + #setVariable (~"$blogDoc~" $macro.result)
1464 +#end" %)
1465 +(((
1466 +(% class="macro-placeholder hidden" %)
1467 +(((
1468 +macro:velocity
46 46  )))
47 -{{velocity}}
48 -#if (!$hasEdit)
1470 +)))
1471 +)))
1472 +
1473 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
1474 +(((
1475 +(% class="macro-placeholder hidden" %)
1476 +(((
1477 +macro:include
1478 +)))
1479 +
1480 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
1481 + * Extract the layout parameters from a string.
1482 + *
1483 + * @param layoutParamsString The string representation of the layout parameters.
1484 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
1485 + * @param layoutsParameters The resulting layout parameters Map.
1486 + *###
1487 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
1488 + #set ($layoutsParameters = $NULL)
1489 + #set ($macro.layoutParams = \{})
1490 + #if (~"$!layoutParamsString~" != '')
1491 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
1492 + #foreach ($item in $macro.paramsArr)
1493 + #set ($itemSplit = $item.split('='))
1494 + #if ($itemSplit.size() == 2)
1495 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
1496 + #end
1497 + #end
1498 + #end
1499 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
1500 +#end" %)
1501 +(((
1502 +(% class="macro-placeholder hidden" %)
1503 +(((
1504 +macro:velocity
1505 +)))
1506 +)))
1507 +)))
1508 +
1509 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
1510 + #initLayoutVars($pDoc $pObj)
1511 + <div class=~"col-xs-12 col-sm-6 next_blog~">
1512 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
1513 + <div class=~"row~">
1514 + <div class=~"col-xs-4~">
1515 + #if ($imageAtt)
1516 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
1517 + #end
1518 + </div>
1519 + <div class=~"col-xs-8 art_det~">
1520 + <p class=~"text-left~">
1521 + #if($displayTitle)$!postTitle #end
1522 + <br/><span class=~"date_info~"> $!dateStr </span>
1523 + </p>
1524 + #displayPostDetails($pDoc)
1525 + </div>
1526 + </div>
1527 + </a>
1528 + </div>
1529 + #end
1530 + ##
1531 + ##
1532 + ##
1533 + #macro(displayPinnedPost $pDoc $pObj)
1534 + #initLayoutVars($pDoc $pObj)
1535 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
1536 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
1537 + <div class=~"thumbnail~">
1538 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
1539 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
1540 + #end
1541 + #if ($imageAtt)
1542 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
1543 + #end
1544 + <div class=~"caption~">
1545 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
1546 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
1547 + #end
1548 + #if ($displaySummaryOnPinnedPosts)
1549 + <div class=~"text-left post-summary~">
1550 + #set ($postContent = $pObj.getProperty('extract').value)
1551 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
1552 + </div>
1553 + #end
1554 + #displayPostDetails($pDoc)
1555 + </div>
1556 + </div>
1557 + </a>
1558 + </div>
1559 + #end
1560 + ##
1561 + ##
1562 + ##
1563 + #macro(formatPostDate $pDoc $pObj)
1564 + #set ($formattedDate = $NULL)
1565 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
1566 + #if (~"$!dateStr~" != '')
1567 + #set ($dateArr = $dateStr.split(' '))
1568 + #if ($dateArr.size() > 3)
1569 + #set ($dateStr = ~"~")
1570 + #foreach($s in $dateArr.subList(0, 3))
1571 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
1572 + #end
1573 + #end
1574 + #end
1575 + #setVariable(~"$formattedDate~" $dateStr)
1576 + #end
1577 + ##
1578 + ##
1579 + ##
1580 + #macro(displayPostDetails $pDoc)
1581 + <div class=~"row post-details~">
1582 + <div class=~"col-xs-8 detail~">
1583 + #if ($services.like.displayButton($pDoc.documentReference))
1584 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
1585 + ## Retrieve the likes number in XWiki 12.9+
1586 + #set ($likeNumber = $optLikeRecord.get())
1587 + #if (!$stringtool.isNumeric($likeNumber.toString()))
1588 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
1589 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
1590 + #end
1591 + #if ($stringtool.isNumeric($likeNumber.toString()))
1592 + <div class=~"post-likes btn btn-default disabled badge~"
1593 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
1594 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
1595 + </div>
1596 + #end
1597 + #elseif ($services.ratings)
1598 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
1599 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
1600 + <ul class=~"pull-left note list-inline~">
1601 + #foreach ($x in [1..5])
1602 + #set ($cls = ~"~")
1603 + #if ($x > $averageVote)
1604 + #set ($cls = ~"-o~")
1605 + #end
1606 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
1607 + #end
1608 + </ul>
1609 + #end
1610 + #end
1611 + </div>
1612 + #if ($showPostComments)
1613 + <div class=~"col-xs-4 com_det~">
1614 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
1615 + </div>
1616 + #end
1617 + </div>
1618 + #end
1619 + ##
1620 + ##
1621 + ##
1622 + #macro(initLayoutVars $pDoc $pObj)
1623 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
1624 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
1625 + #isPublished($pObj $isPublished)
1626 + #isHidden($pObj $isHidden)
1627 + #getEntryDate($pDoc $pObj $postDate)
1628 + #formatPostDate($postDate $dateStr)
1629 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
1630 + #set ($nbComments = $pDoc.getComments().size())
1631 + #set ($showPostComments = true)
1632 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
1633 + #set ($showPostComments = false)
1634 + #end
1635 + #end
1636 + ##
1637 + ##
1638 + ##
1639 + #macro(displayEditPinnedPostsButton)
1640 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
1641 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
1642 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
1643 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
1644 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
1645 + <div class=~"edit-pinned-posts-container~">
1646 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
1647 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
1648 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
1649 + </a>
1650 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
1651 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
1652 + </div>
1653 + </div>
1654 + #if (~"$!pinnedPostsObj~" == '')
1655 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
1656 + #end
1657 + #end
1658 + #end" %)
1659 +(((
1660 +(% class="macro-placeholder hidden" %)
1661 +(((
1662 +macro:velocity
1663 +)))
1664 +)))
1665 +
1666 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
1667 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
1668 + #getEntryObject($postDoc $postObj)
1669 + #if (~"$!postObj~" != '')
1670 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
1671 + ##
1672 + #set ($displayTitle = true)
1673 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
1674 + #set ($displayTitle = false)
1675 + #end
1676 + ##
1677 + #set ($displayTitleFirstOnPinnedPosts = false)
1678 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
1679 + #set ($displayTitleFirstOnPinnedPosts = true)
1680 + #end
1681 + ##
1682 + #set ($displaySummaryOnPinnedPosts = true)
1683 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
1684 + #set ($displaySummaryOnPinnedPosts = false)
1685 + #end
1686 + ##
1687 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
1688 + #if ($postIndex == 0)
1689 + #set ($stopBlogPostsDisplay = false)
1690 + #end
1691 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
1692 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
1693 + #set($scaleWidth = 600)
1694 + #set($imgQs=~"width=$scaleWidth~")
1695 + ## Display pinned posts
1696 + ## Get the list of pinned posts
1697 + #set ($pinnedPosts = [])
1698 + #set ($pinnedPostsSourceDoc = $NULL)
1699 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
1700 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
1701 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
1702 + #end
1703 + #if (~"$!pinnedPostsSourceDoc~" != '')
1704 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
1705 + #if (~"$!pinnedPostsObj~" != '')
1706 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
1707 + #if (~"$!orderedPinnedPostsJSON~" != '')
1708 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
1709 + #else
1710 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
1711 + #end
1712 + #end
1713 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
1714 + \{\{html clean=~"false~"}}
1715 + #set ($x = 0)
1716 + #set ($showPinnedPostsButton = true)
1717 + #foreach ($pinnedPost in $pinnedPosts)
1718 + #if ($x == 0)
1719 + <div class=~"row flex-container~">
1720 + #if ($showPinnedPostsButton)
1721 + #displayEditPinnedPostsButton()
1722 + #set($showPinnedPostsButton = false)
1723 + #end
1724 + #end
1725 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
1726 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
1727 + #if (~"$!pinnedPostObj~" != '')
1728 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
1729 + #end
1730 + #set ($x = $mathtool.add($x, 1))
1731 + #if ($x == 3)
1732 + #set ($x = 0)
1733 + </div>
1734 + #end
1735 + #end
1736 + #if ($mathtool.mod($x, 3) != 0)
1737 + </div>
1738 + #end
1739 + \{\{/html}}
1740 +
1741 + ## If the first post is a pinned post : this means that all the posts are pinned
1742 + ## In this case, avoid displaying the posts again after the pinned posts section.
1743 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
1744 + #set ($stopBlogPostsDisplay = true)
1745 + #end
1746 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
1747 +
1748 + \{\{html}}
1749 + <div class=~"row no-pinnded-posts~">
1750 + #displayEditPinnedPostsButton()
1751 + </div>
1752 + \{\{/html}}
1753 +
1754 + #end
1755 + #end
1756 + #if (!$stopBlogPostsDisplay)
1757 + \{\{html clean=~"false~"}}
1758 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
1759 + #set ($nbDisplayedPosts = 0)
1760 + #end
1761 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
1762 + #if ($nbDisplayedPosts != 0)
1763 + </div>
1764 + #set ($lastHtmlTag = 'c')
1765 + #end
1766 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
1767 + <div class=~"row~">
1768 + #set ($lastHtmlTag = 'o')
1769 + #set ($lastRowClass = ~"~")
1770 + #else
1771 + <div class=~"row flex-container~">
1772 + #set ($lastHtmlTag = 'o')
1773 + #set ($lastRowClass = ~"flex~")
1774 + #end
1775 + #end
1776 + #displaySmallPost($postDoc $postObj)
1777 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
1778 + </div>
1779 + #set ($lastHtmlTag = 'c')
1780 + #end
1781 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
1782 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
1783 + #if (~"$!lastHtmlTag~" == 'o')
1784 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
1785 + <div class=~"col-xs-12 col-sm-6~"></div>
1786 + #end
1787 + </div>
1788 + #end
1789 + #end
1790 + \{\{/html}}
1791 + #end
1792 + #else
1793 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
1794 + #end
1795 + #else
1796 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
1797 + #end" %)
1798 +(((
1799 +(% class="macro-placeholder hidden" %)
1800 +(((
1801 +macro:velocity
1802 +)))
1803 +
1804 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"row flex-container~">
1805 +<div class=~"col-xs-12 col-sm-6 next_blog~">
1806 +<a href=~"/Nieuws/Nieuwsbrief%20januari%202024~" class=~"thumbnail~">
1807 +<div class=~"row~">
1808 +<div class=~"col-xs-4~">
1809 +<img src=~"/download/Nieuws/Nieuwsbrief%20januari%202024/man-outdoor-light-architecture-people-street-1194699-pxhere.com.jpg?width=600&rev=1.1~" />
1810 +</div>
1811 +<div class=~"col-xs-8 art_det~">
1812 +<p class=~"text-left~">
1813 +Nieuwsbrief januari 2024 <br/><span class=~"date_info~"> Feb 5, 2024, </span>
1814 +</p>
1815 +<div class=~"row post-details~">
1816 +<div class=~"col-xs-8 detail~">
1817 +<div class=~"post-likes btn btn-default disabled badge~"
1818 +title=~"Number of likes on this page: 3~">
1819 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">3</span>
1820 +</div>
1821 +</div>
1822 +<div class=~"col-xs-4 com_det~">
1823 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
1824 +</div>
1825 +</div>
1826 +</div>
1827 +</div>
1828 +</a>
1829 +</div>" %)
1830 +(((
1831 +(% class="macro-placeholder hidden" %)
1832 +(((
1833 +macro:html
1834 +)))
1835 +
1836 +(% class="row flex-container" %)
1837 +(((
1838 +(% class="col-xs-12 col-sm-6 next_blog" %)
1839 +(((
1840 +(% class="row" %)
1841 +(((
1842 +(% class="col-xs-4" %)
1843 +(((
1844 +[[~[~[image:/download/Nieuws/Nieuwsbrief%20januari%202024/man-outdoor-light-architecture-people-street-1194699-pxhere.com.jpg?width=600&rev=1.1~]~]>>path:/Nieuws/Nieuwsbrief%20januari%202024||class="thumbnail"]]
1845 +)))
1846 +
1847 +(% class="col-xs-8 art_det" %)
1848 +(((
1849 +(% class="text-left" %)
1850 +[[Nieuwsbrief januari 2024
1851 +(% class="date_info" %) Feb 5, 2024,>>path:/Nieuws/Nieuwsbrief%20januari%202024||class="thumbnail"]]
1852 +
1853 +(% class="row post-details" %)
1854 +(((
1855 +(% class="col-xs-8 detail" %)
1856 +(((
1857 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 3" %)
1858 +(((
1859 +[[(% class="like-number" %)3>>path:/Nieuws/Nieuwsbrief%20januari%202024||class="thumbnail"]]
1860 +)))
1861 +)))
1862 +
1863 +(% class="col-xs-4 com_det" %)
1864 +(((
1865 +(% class="text-right" %)
1866 +[[(0)>>path:/Nieuws/Nieuwsbrief%20januari%202024||class="thumbnail"]]
1867 +)))
1868 +)))
1869 +)))
1870 +)))
1871 +)))
1872 +
1873 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Audit BMI en BORG~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024~"" %)
1874 +(((
1875 +(% class="macro-placeholder hidden" %)
1876 +(((
1877 +macro:blogPostLayoutCards
1878 +)))
1879 +
1880 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
1881 +(((
1882 +(% class="macro-placeholder hidden" %)
1883 +(((
1884 +macro:include
1885 +)))
1886 +
1887 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
1888 +(((
1889 +(% class="macro-placeholder hidden" %)
1890 +(((
1891 +macro:include
1892 +)))
1893 +
1894 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
1895 +#set($blogClassname = 'Blog.BlogClass')
1896 +#set($blogTemplate = 'Blog.BlogTemplate')
1897 +#set($blogSheet = 'Blog.BlogSheet')
1898 +## Blog entries
1899 +#set($blogPostClassname = 'Blog.BlogPostClass')
1900 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
1901 +#set($blogPostSheet = 'Blog.BlogPostSheet')
1902 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
1903 +#set($oldArticleClassname = 'XWiki.ArticleClass')
1904 +## Categories
1905 +#set($blogCategoryClassname = 'Blog.CategoryClass')
1906 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
1907 +#set($blogCategorySheet = 'Blog.CategorySheet')
1908 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
1909 +#set($oldBlogCategoryClassname = 'Blog.Categories')
1910 +#set($defaultCategoryParent = 'Blog.Categories')
1911 +## Style
1912 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
1913 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
1914 +## Clientside scripts
1915 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
1916 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
1917 +## Misc
1918 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
1919 +#set($isBlogPost = $doc.getObject($blogPostClassname))
1920 +#set($defaultBlogSpace = 'Blog')
1921 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
1922 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
1923 +##
1924 +##
1925 +##
1926 +#**
1927 + * Displays an image, taken from the blog style document.
1928 + *
1929 + * @param $imgName The name of the icon from icons set to use.
1930 + *#
1931 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
1932 +(((
1933 +(% class="macro-placeholder hidden" %)
1934 +(((
1935 +macro:velocity
1936 +)))
1937 +)))
1938 +)))
1939 +
1940 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
1941 +##
1942 +##
1943 +## Import the blog skin and javascripts.
1944 +$!xwiki.ssx.use($blogStyleDocumentName)##
1945 +$!xwiki.jsx.use($blogScriptsDocumentName)##
1946 +##
1947 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
1948 +#template('hierarchy_macros.vm')##
1949 +##
1950 +##
1951 +#**
1952 + * Prints a blog. This is the main macro used in the BlogSheet.
1953 + *
1954 + * @param blogDoc the XDocument holding the blog definition object.
1955 + *###
1956 +#macro(printBlog $blogDoc)
1957 + \{\{include reference='Blog.CreatePost'/}}
1958 +
1959 + ## Use the blogPostList macro to display the blogposts
1960 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
1961 + ## do not support FTM the monthly and weekly blog display types
1962 + #getBlogDisplayType($blogDoc $displayType)
1963 + #if ($displayType == 'weekly' || $displayType == 'monthly')
1964 + #getBlogEntries($blogDoc $entries)
1965 + #displayBlog($entries 'index' true true)
1966 + #displayNavigationLinks($blogDoc)
1967 + #else
1968 + #getBlogDisplayType($blogDoc $displayType)
1969 + #set ($paginated = 'no')
1970 + #if ($displayType == 'paginated')
1971 + #set ($paginated = 'yes')
1972 + #end
1973 + #getBlogPostsLayout($blogDoc $postsLayout)
1974 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
1975 + #end
1976 +#end
1977 +##
1978 +##
1979 +##
1980 +#**
1981 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
1982 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
1983 + * all entries).
1984 + *
1985 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
1986 + *###
1987 +#macro(showBlogInfo $blogDoc)
1988 + #if($blogDoc.getObject($blogClassname))
1989 + ## Keep testing for inline action for backward compatibility with older blogs.
1990 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
1991 + #macro(displayProperty $blogDoc $propname)
1992 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
1993 + : $blogDoc.display($propname)
1994 + #end
1995 + #displayProperty($blogDoc 'title')
1996 + #displayProperty($blogDoc 'description')
1997 + #displayProperty($blogDoc 'displayType')
1998 + #displayProperty($blogDoc 'itemsPerPage')
1999 + #displayProperty($blogDoc 'postsLayout')
2000 + #displayProperty($blogDoc 'postsLayoutParameters')
2001 + #else
2002 + $blogDoc.display('description')
2003 + #end
2004 + #elseif($doc.fullName == $blogSheet)
2005 += $services.localization.render('blog.code.blogsheet') =
2006 + \{\{translation key='blog.code.sheetexplanation'/}}
2007 + #else
2008 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
2009 + #end
2010 +#end
2011 +##
2012 +##
2013 +##
2014 +#**
2015 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
2016 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
2017 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
2018 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
2019 + *
2020 + * @param space A <tt>String</tt>, the name of the space where to search.
2021 + * @param blogDoc The resulting XDocument.
2022 + *###
2023 +#macro(getBlogDocument $space $blogDoc)
2024 + #set ($result = $NULL)
2025 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
2026 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
2027 + ## identify the right blog based on a configuration object in a WebPreferences page.
2028 + #set ($spaceReference = $services.model.resolveSpace($space))
2029 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
2030 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
2031 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
2032 + #if ($preferencesObj)
2033 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
2034 + #end
2035 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
2036 + #if (~"$!result~" == '')
2037 + ## First, try the Space.WebHome, for a whole-space blog
2038 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
2039 + #if(!$result.getObject($blogClassname))
2040 + ## Second, try the Space.Blog document
2041 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
2042 + #if(!$result.getObject($blogClassname))
2043 + ## Third, try searching for a blog document in the current space
2044 + ## Prevent the query fail when the space contains dots '.'
2045 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
2046 + #if($blogDocs.size() > 0)
2047 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
2048 + #else
2049 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
2050 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
2051 + #if($blogDocs.size() > 0)
2052 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
2053 + #else
2054 + ## Last, fallback to Blog.WebHome, the default blog
2055 + #set($result = $xwiki.getDocument('Blog.WebHome'))
2056 + #end
2057 + #end
2058 + #end
2059 + #end
2060 + #end
2061 + #set ($blogDoc = $NULL)
2062 + #setVariable (~"$blogDoc~" $result)
2063 +#end
2064 +##
2065 +##
2066 +##
2067 +#**
2068 + * Retrieve the blog title.
2069 + *
2070 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
2071 + * @param title The resulting title.
2072 + *###
2073 +#macro(getBlogTitle $blogDoc $title)
2074 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
2075 + #set ($title = $NULL)
2076 + #setVariable (~"$title~" $!blogDoc.displayTitle)
2077 +#end
2078 +##
2079 +##
2080 +##
2081 +#**
2082 + * Retrieve the blog description.
2083 + *
2084 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
2085 + * property set.
2086 + * @param description The resulting description.
2087 + *###
2088 +#macro(getBlogDescription $blogDoc $description)
2089 + #getBlogProperty($blogDoc 'description' '' $result)
2090 + #set ($description = $NULL)
2091 + #setVariable (~"$description~" $result)
2092 +#end
2093 +##
2094 +##
2095 +##
2096 +#**
2097 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
2098 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
2099 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
2100 + * month), or all.
2101 + *
2102 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
2103 + * @param entries The resulting list of entries to display, a list of XDocument names.
2104 + *###
2105 +#macro(getBlogEntries $blogDoc $entries)
2106 + #if (!$entries)
2107 + #setVariable (~"$entries~" [])
2108 + #end
2109 + #getAllBlogPostsQuery($query)
2110 + #isDefaultBlog($blogDoc $isDefault)
2111 + #set($queryParams = \{})
2112 + #if ($isDefault)
2113 + #getCategoryAllBlogPostsQuery($query)
2114 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
2115 + #set($discard = $queryParams.put('creator', $xcontext.user))
2116 + #set($discard = $queryParams.put('space', $blogDoc.space))
2117 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
2118 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
2119 + #else
2120 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
2121 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
2122 + #set($discard = $queryParams.put('space', $blogPostsLocation))
2123 + #set($discard = $queryParams.put('parent', $blogDoc.space))
2124 + #end
2125 + #getBlogDisplayType($blogDoc $displayType)
2126 + #if($displayType == 'weekly')
2127 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
2128 + #elseif($displayType == 'monthly')
2129 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
2130 + #elseif($displayType == 'all')
2131 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
2132 + #else
2133 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
2134 + #end
2135 +#end
2136 +##
2137 +##
2138 +##
2139 +#**
2140 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
2141 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
2142 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
2143 + * (10 if not defined).
2144 + *
2145 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
2146 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
2147 + * refined to restrict to a given space, or to a given search criteria, etc.
2148 + * @param entries The resulting list of entries to display, a list of XDocument names.
2149 + * @param queryParams The parameters to bind with the query.
2150 + *###
2151 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
2152 + #if (!$entries)
2153 + #setVariable (~"$entries~" [])
2154 + #end
2155 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
2156 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
2157 + #bindQueryParameters($countQueryObj $queryParams)
2158 + #bindQueryParameters($queryObj $queryParams)
2159 + #set($totalEntries = $countQueryObj.count())
2160 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
2161 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
2162 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
2163 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
2164 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
2165 +#end
2166 +##
2167 +##
2168 +##
2169 +#**
2170 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
2171 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
2172 + * digit year). Initially the current week is displayed.
2173 + *
2174 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
2175 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
2176 + * refined to restrict to a given space, or to a given search criteria, etc.
2177 + * @param entries The resulting list of entries to display, a list of XDocument names.
2178 + * @param queryParams The parameters to bind with the query.
2179 + *###
2180 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
2181 + #if (!$entries)
2182 + #setVariable (~"$entries~" [])
2183 + #end
2184 + #getRequestedWeek($weekDate)
2185 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
2186 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
2187 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
2188 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
2189 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
2190 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
2191 + #bindQueryParameters($countQueryObj $queryParams)
2192 + #bindQueryParameters($queryObj $queryParams)
2193 + #set($totalEntries = $countQueryObj.count())
2194 + #set($discard = $entries.addAll($queryObj.execute()))
2195 +#end
2196 +##
2197 +##
2198 +##
2199 +#**
2200 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
2201 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
2202 + * digit year). Initially the current month is displayed.
2203 + *
2204 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
2205 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
2206 + * refined to restrict to a given space, or to a given search criteria, etc.
2207 + * @param entries The resulting list of entries to display, a list of XDocument names.
2208 + * @param queryParams The parameters to bind with the query.
2209 + *###
2210 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
2211 + #if (!$entries)
2212 + #setVariable (~"$entries~" [])
2213 + #end
2214 + #getRequestedMonth($monthDate)
2215 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
2216 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
2217 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
2218 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
2219 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
2220 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
2221 + #bindQueryParameters($countQueryObj $queryParams)
2222 + #bindQueryParameters($queryObj $queryParams)
2223 + #set($totalEntries = $countQueryObj.count())
2224 + #set($discard = $entries.addAll($queryObj.execute()))
2225 +#end
2226 +##
2227 +##
2228 +##
2229 +#**
2230 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
2231 + *
2232 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
2233 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
2234 + * refined to restrict to a given space, or to a given search criteria, etc.
2235 + * @param entries The resulting list of entries to display, a list of XDocument names.
2236 + * @param queryParams The parameters to bind with the query.
2237 + *###
2238 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
2239 + #if (!$entries)
2240 + #setVariable (~"$entries~" [])
2241 + #end
2242 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
2243 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
2244 + #bindQueryParameters($countQueryObj $queryParams)
2245 + #bindQueryParameters($queryObj $queryParams)
2246 + #set($totalEntries = $countQueryObj.count())
2247 + #set($discard = $entries.addAll($queryObj.execute()))
2248 +#end
2249 +##
2250 +##
2251 +##
2252 +#**
2253 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
2254 + *
2255 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
2256 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
2257 + * refined to restrict to a given space, or to a given search criteria, etc.
2258 + * @param queryParams The parameters to bind with the query.
2259 + * @param entries The resulting list of entries to display, a list of XDocument names.
2260 + *###
2261 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
2262 + #if (!$entries)
2263 + #setVariable (~"$entries~" [])
2264 + #end
2265 + #set($query = ~"$\{query} and isPublished.value = 0~")
2266 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
2267 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
2268 + #bindQueryParameters($countQueryObj $queryParams)
2269 + #bindQueryParameters($queryObj $queryParams)
2270 + #set($totalEntries = $countQueryObj.count())
2271 + #set($discard = $entries.addAll($queryObj.execute()))
2272 +#end
2273 +##
2274 +##
2275 +##
2276 +#**
2277 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
2278 + *
2279 + * @param entries The resulting list of entries to display, a list of XDocument names.
2280 + *###
2281 +#macro(getGlobalBlogEntries $entries)
2282 + #if (!$entries)
2283 + #setVariable (~"$entries~" [])
2284 + #end
2285 + #getAllBlogPostsQuery($query)
2286 + #set($totalEntries = $services.query.hql($query).count())
2287 + #set($defaultItemsPerPage = 20)
2288 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
2289 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
2290 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
2291 +#end
2292 +#**
2293 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
2294 + * blog, nor specify a range or an ordering criteria.
2295 + *
2296 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
2297 + *
2298 + * @param query The basic query for selecting blog entries.
2299 + *#
2300 +#macro(getBlogEntriesBaseQuery $query)
2301 + #getAllBlogPostsQuery($query)
2302 +#end
2303 +#**
2304 + * Return the Query for selecting the all wiki blog posts without filtering
2305 + *
2306 + * @param query The basic query for selecting blog entries.
2307 + *#
2308 +#macro(getAllBlogPostsQuery $query)
2309 + #set ($query = $NULL)
2310 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
2311 + IntegerProperty hidden, DateProperty publishDate
2312 + where doc.fullName <> '$blogPostTemplate' and
2313 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
2314 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
2315 + hidden.id.id = obj.id and hidden.id.name='hidden' and
2316 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
2317 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
2318 +#end
2319 +##
2320 +##
2321 +##
2322 +###**
2323 + * Return the Query for selecting the all wiki blog posts with categories filtering
2324 + *
2325 + * @param query The basic query for selecting blog entries.
2326 + *###
2327 +#macro(getCategoryAllBlogPostsQuery $query)
2328 + #set ($query = $NULL)
2329 + #getAllBlogPostsQuery($baseQuery)
2330 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
2331 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
2332 +#end
2333 +##
2334 +##
2335 +##
2336 +#**
2337 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
2338 + * week), monthly (all entries in a month), or all.
2339 + *
2340 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
2341 + * property set.
2342 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
2343 + *###
2344 +#macro(getBlogDisplayType $blogDoc $displayType)
2345 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
2346 + #set ($displayType = $NULL)
2347 + #setVariable (~"$displayType~" $result)
2348 +#end
2349 +##
2350 +##
2351 +##
2352 +#**
2353 + * Displays a list of entries.
2354 + *
2355 + * @param entries The entries to display, a list of XDocument names.
2356 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
2357 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
2358 + * used values: index, single, category, search, unpublished, hidden.
2359 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
2360 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
2361 + * displayed alone on their page since it's the page title which is used in this case)
2362 + *###
2363 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
2364 + #set($blogDay = '')
2365 + (% class=~"hfeed $!\{displaying}~" ~%)(((
2366 + (% class=~"blogDay~" ~%)(((
2367 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
2368 + #getEntryObject($entryDoc $entryObj)
2369 + ## Although all entries should have one of the two objects, better check to be sure.
2370 + #if(~"$!\{entryObj}~" != '')
2371 + #getEntryDate($entryDoc $entryObj $entryDate)
2372 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
2373 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
2374 + #if($blogDay != $entryDateStr)
2375 + #if($blogDay != '')
2376 + )))
2377 + (% class=~"blogDay~" ~%)(((
2378 + #end
2379 + #displayBlogDate($entryDate)
2380 + #set ($blogDay = $entryDateStr)
2381 + #end
2382 + ## Finally, display the entry.
2383 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
2384 + #end
2385 + #end
2386 + )))## blogDay
2387 + )))## hfeed
2388 +#end
2389 +##
2390 +##
2391 +##
2392 +#**
2393 + * Get the entry object, either a new BlogPost or an old Article.
2394 + *
2395 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2396 + * @param entryObj The resulting xobject of the blog post.
2397 + *###
2398 +#macro(getEntryObject $entryDoc $__entryObj)
2399 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
2400 + #if(!$result)
2401 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
2402 + #end
2403 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
2404 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
2405 + ## overwritten in this case but it's less likely to have such a variable defined before.
2406 + #set ($__entryObj = $NULL)
2407 + #setVariable (~"$__entryObj~" $result)
2408 +#end
2409 +##
2410 +##
2411 +##
2412 +#**
2413 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
2414 + * the document creation date, but can be edited by the user.
2415 + *
2416 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2417 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2418 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
2419 + *###
2420 +#macro(getEntryDate $entryDoc $entryObj $result)
2421 + #set ($result = $NULL)
2422 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
2423 +#end
2424 +##
2425 +##
2426 +##
2427 +#**
2428 + * Displays a date, nicely formatted as a calendar page.
2429 + *
2430 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
2431 + *###
2432 +#macro(displayBlogDate $date)
2433 + #set($year = $xwiki.formatDate($date, 'yyyy'))
2434 + ## 3 letter month name, like Jan, Dec.
2435 + #set($month = $xwiki.formatDate($date, 'MMM'))
2436 + ## Uncomment to get a full length month name, like January, December.
2437 + ## TODO: this could be defined somewhere in the blog style.
2438 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
2439 + #set($day = $xwiki.formatDate($date, 'dd'))
2440 + (% class=~"blogdate~" ~%)
2441 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
2442 +#end
2443 +##
2444 +##
2445 +##
2446 +#**
2447 + * Displays a blog article: management tools, header, content, footer.
2448 + *
2449 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2450 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2451 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
2452 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
2453 + * when they're displayed alone on their page since it's the page title which is used in this case)
2454 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
2455 + *###
2456 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
2457 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
2458 + #isPublished($entryObj $isPublished)
2459 + #isHidden($entryObj $isHidden)
2460 + #if($doc.fullName == $entryDoc.fullName)
2461 + (% class=~"hentry single-article~" ~%)(((
2462 + #else
2463 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
2464 + #end
2465 + #if ($shouldDisplayActions)
2466 + #displayEntryTools($entryDoc $entryObj)
2467 + #end
2468 + #if($shouldDisplayTitle)
2469 + #displayEntryTitle($entryDoc $entryObj)
2470 + #end
2471 + #if($doc.fullName == $entryDoc.fullName)
2472 + #if(!$isPublished)
2473 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
2474 + #elseif($isHidden)
2475 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
2476 + #end
2477 + #end
2478 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
2479 + #displayEntryFooter($entryDoc $entryObj)
2480 + )))## hentry
2481 +#end
2482 +##
2483 +##
2484 +##
2485 +#**
2486 + * Checks if the provided blog is published or not.
2487 + *
2488 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2489 + * @param isPublished The resulting boolean, true if the entry is considered published.
2490 + *###
2491 +#macro(isPublished $entryObj $isPublished)
2492 + #set ($isPublished = $NULL)
2493 + ## This should work for both old articles, which don't have the 'published' property at all, and
2494 + ## are considered published by default, and new entries, that should have 1 if published.
2495 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
2496 + #setVariable (~"$isPublished~" true)
2497 + #else
2498 + #setVariable (~"$isPublished~" false)
2499 + #end
2500 +#end
2501 +##
2502 +##
2503 +##
2504 +#**
2505 + * Checks if the provided blog is hidden or not.
2506 + *
2507 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
2508 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
2509 + *###
2510 +#macro(isHidden $entryObj $isHidden)
2511 + #set ($isHidden = $NULL)
2512 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
2513 + ## are considered visible by default, and new entries, that should have 1 if hidden.
2514 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
2515 + #setVariable (~"$isHidden~" true)
2516 + #else
2517 + #setVariable (~"$isHidden~" false)
2518 + #end
2519 +#end
2520 +##
2521 +##
2522 +##
2523 +#**
2524 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
2525 + *
2526 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2527 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2528 + *###
2529 +#macro(displayEntryTools $entryDoc $entryObj)
2530 + #if($xcontext.action == 'view')
2531 + (% class=~"blog-entry-toolbox~" ~%)(((
2532 + #displayPublishButton($entryDoc $entryObj)
2533 + #displayHideShowButton($entryDoc $entryObj)
2534 + #displayEditButton($entryDoc $entryObj)
2535 + #displayDeleteButton($entryDoc $entryObj)
2536 + )))
2537 + #end
2538 +#end
2539 +##
2540 +##
2541 +##
2542 +#**
2543 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
2544 + *
2545 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2546 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2547 + * @todo AJAX calls.
2548 + *###
2549 +#macro(displayPublishButton $entryDoc $entryObj)
2550 + #isPublished($entryObj $isPublished)
2551 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
2552 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
2553 + #end
2554 +#end
2555 +##
2556 +##
2557 +##
2558 +#**
2559 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
2560 + *
2561 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2562 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2563 + *###
2564 +#macro(displayHideShowButton $entryDoc $entryObj)
2565 + #isPublished($entryObj $isPublished)
2566 + #isHidden($entryObj $isHidden)
2567 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
2568 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
2569 + #set ($queryString = \{
2570 + 'xredirect' : $thisURL,
2571 + 'form_token' : $services.csrf.getToken()
2572 + })
2573 + #if ($isHidden)
2574 + #set ($discard = $queryString.putAll(\{
2575 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
2576 + 'comment' : $services.localization.render('blog.code.madevisible')
2577 + }))
2578 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
2579 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
2580 + #else
2581 + #set ($discard = $queryString.putAll(\{
2582 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
2583 + 'comment' : $services.localization.render('blog.code.hid')
2584 + }))
2585 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
2586 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
2587 + #end
2588 + #end
2589 +#end
2590 +##
2591 +##
2592 +##
2593 +#**
2594 + * Displays the edit button to those that can edit the article.
2595 + *
2596 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2597 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2598 + *###
2599 +#macro(displayEditButton $entryDoc $entryObj)
2600 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
2601 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
2602 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
2603 + #end
2604 +#end
2605 +##
2606 +##
2607 +##
2608 +#**
2609 + * Displays the delete button to those that can edit the article.
2610 + *
2611 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2612 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2613 + * @todo AJAX calls.
2614 + *###
2615 +#macro(displayDeleteButton $entryDoc $entryObj)
2616 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
2617 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
2618 + #end
2619 +#end
2620 +##
2621 +##
2622 +##
2623 +#**
2624 + * Displays the title of the entry.
2625 + *
2626 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2627 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2628 + *###
2629 +#macro(displayEntryTitle $entryDoc $entryObj)
2630 + #if($doc.fullName == $entryDoc.fullName)
2631 + (% class=~"entry-title~" ~%)
2632 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
2633 + #else
2634 + (% class=~"entry-title~" ~%)
2635 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
2636 + #end
2637 +#end
2638 +##
2639 +##
2640 +##
2641 +#**
2642 + * Displays the body of the entry.
2643 + *
2644 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2645 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2646 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
2647 + *###
2648 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
2649 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
2650 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
2651 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
2652 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
2653 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
2654 + ))) ## entry-content
2655 + (% class=~"clearfloats~" ~%)((()))
2656 +#end
2657 +##
2658 +##
2659 +##
2660 +#**
2661 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
2662 + * of the <tt>extract</tt> field (if not empty).
2663 + *
2664 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2665 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2666 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
2667 + * @param entryContent The resulting content.
2668 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
2669 + * <tt>onlyExtract</tt> is <tt>true</tt>)
2670 + *###
2671 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
2672 + #if ($onlyExtract)
2673 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
2674 + ## of the content.
2675 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
2676 + #end
2677 + #if(~"$!macro.result~" == '')
2678 + #set($macro.result = $entryObj.getProperty('content').value)
2679 +#* Disabled until the content can be cleanly cut.
2680 +* #if($onlyExtract && $result.length()>$maxchars)
2681 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
2682 +* #set($i = $i + 1)
2683 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
2684 +* #end
2685 +## *###
2686 + #elseif (!$removeEllipsis)
2687 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
2688 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
2689 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
2690 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
2691 + #end
2692 + #end
2693 + #set ($entryContent = $NULL)
2694 + #setVariable (~"$entryContent~" $macro.result)
2695 +#end
2696 +##
2697 +##
2698 +##
2699 +#**
2700 + * Displays the footer of the entry.
2701 + *
2702 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2703 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2704 + *###
2705 +#macro(displayEntryFooter $entryDoc $entryObj)
2706 + (% class=~"entry-footer~" ~%)(((
2707 + #isPublished($entryObj $isPublished)
2708 + (% class='entry-author-label' ~%)
2709 + #if($isPublished)
2710 + \{\{translation key='blog.code.postedby'/}} ##
2711 + #else
2712 + \{\{translation key='blog.code.createdby'/}} ##
2713 + #end
2714 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
2715 + #getEntryDate($entryDoc $entryObj $entryDate)
2716 + #listCategories($entryObj) #*
2717 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
2718 + ## we assume cannot be more than 3 seconds.
2719 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
2720 + #if ($showcomments)
2721 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
2722 + #end ##
2723 + #if($entryDoc != $doc) ##
2724 + #displayEntryBlogLocation($entryDoc $entryObj) ##
2725 + #end
2726 + )))## entry-footer
2727 +#end
2728 +##
2729 +##
2730 +#**
2731 + * Display the blog for the entry (if it is not the currently displayed blog)
2732 + *
2733 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
2734 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2735 + *###
2736 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
2737 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
2738 + #if(~"$!blogPostsLocation~" != ~"~") ##
2739 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
2740 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
2741 + #if($doc.documentReference != $blogDocRef) ##
2742 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
2743 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
2744 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
2745 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
2746 + )))(%~%)##
2747 + #end
2748 + #end
2749 + #end
2750 +#end
2751 +##
2752 +##
2753 +##
2754 +##
2755 +#**
2756 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
2757 + *
2758 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
2759 + *###
2760 +#macro(listCategories $entryObj)
2761 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
2762 + #set($categories = $entryObj.getProperty('category').value)
2763 + #set($first = true)
2764 + #if($categories.size() > 0)
2765 + #foreach($category in $categories)
2766 + #set($categoryDoc = $!xwiki.getDocument($category))
2767 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
2768 + #if($foreach.count == 1)
2769 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
2770 + #else
2771 + , ##
2772 + #end##
2773 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
2774 + #end##
2775 + #end##
2776 + #end
2777 + #end
2778 +#end
2779 +##
2780 +##
2781 +##
2782 +#**
2783 + * Displays blog pagination links (older and newer entries).
2784 + *
2785 + * @param blogDoc the XDocument holding the blog definition object.
2786 + *###
2787 +#macro(displayNavigationLinks $blogDoc)
2788 + (% class=~"clearfloats~" ~%)((()))
2789 + #getBlogDisplayType($blogDoc $displayType)
2790 + #if($displayType == 'weekly')
2791 + (% class=~"pagingLinks~" ~%)(((
2792 + #getRequestedWeek($weekDate)
2793 + $weekDate.addWeeks(-1)##
2794 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
2795 + #sep()
2796 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
2797 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
2798 + )))
2799 + #elseif($displayType == 'monthly')
2800 + (% class=~"pagingLinks~" ~%)(((
2801 + #getRequestedMonth($monthDate)
2802 + $monthDate.addMonths(-1)##
2803 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
2804 + #sep()
2805 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
2806 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
2807 + )))
2808 + #elseif($displayType == 'all')
2809 + #else
2810 + ## Paginated
2811 + #if(($totalPages > 1))
2812 + #set($queryString = '')
2813 + #foreach($p in $request.getParameterNames())
2814 + #if($p != 'page' && $p != 'ipp')
2815 + #foreach($v in $request.getParameterValues($p))
2816 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
2817 + #end
2818 + #end
2819 + #end
2820 + (% class=~"pagingLinks~" ~%)(((
2821 + #if ($currentPageNumber < $totalPages)
2822 + #set($currentPageNumber = $currentPageNumber + 1)
2823 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
2824 + #set($currentPageNumber = $currentPageNumber - 1)
2825 + #end
2826 + #if ($currentPageNumber > 1)
2827 + #if ($currentPageNumber < $totalPages)
2828 + #sep()
2829 + #end
2830 + #set($currentPageNumber = $currentPageNumber - 1)
2831 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
2832 + #set($currentPageNumber = $currentPageNumber + 1)
2833 + #end
2834 + (% class=~"clear~" ~%)(%~%)
2835 + )))## pagingLinks
2836 + #end
2837 + #end
2838 +#end
2839 +##
2840 +##
2841 +##
2842 +#**
2843 + * Displays a message box with ~"publish~" icon.
2844 + *
2845 + * @param message A text message concerning blog article publishing
2846 + *###
2847 +#macro(publishMessageBox $message)
2848 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
2849 +#end
2850 +#**
2851 + * Displays a message box with ~"show/hide~" icon.
2852 + *
2853 + * @param message A text message concerning blog article hiding
2854 + *###
2855 +#macro(hideMessageBox $message)
2856 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
2857 +#end
2858 +##
2859 +##
2860 +##
2861 +#**
2862 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
2863 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
2864 + *
2865 + * @param monthDate The resulting week, a JODATime MutableDateTime.
2866 + *###
2867 +#macro(getRequestedWeek $weekDate)
2868 + #set ($weekDate = $NULL)
2869 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
2870 + #if(~"$!\{request.year}~" != '')
2871 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
2872 + #end
2873 + #if(~"$!\{request.week}~" != '')
2874 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
2875 + #end
2876 +#end
2877 +##
2878 +##
2879 +##
2880 +#**
2881 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
2882 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
2883 + *
2884 + * @param monthDate The resulting month, a JODATime MutableDateTime.
2885 + *###
2886 +#macro(getRequestedMonth $monthDate)
2887 + #set ($monthDate = $NULL)
2888 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
2889 + #if(~"$!\{request.year}~" != '')
2890 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
2891 + #end
2892 + #if(~"$!\{request.month}~" != '')
2893 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
2894 + #end
2895 +#end
2896 +##
2897 +##
2898 +##
2899 +#**
2900 + * Retrieve a blog property (title, display type, etc).
2901 + *
2902 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
2903 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
2904 + * @param defaultValue The default value to use in case the blog object does not define one.
2905 + * @param propertyValue The resulting value.
2906 + *###
2907 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
2908 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
2909 + #if($result == '')
2910 + #set($result = $defaultValue)
2911 + #end
2912 + #set ($propertyValue = $NULL)
2913 + #setVariable (~"$propertyValue~" $result)
2914 +#end
2915 +
2916 +#**
2917 + * If an error occurs when executing an action, set a specific response status and display an error message.
2918 + *
2919 + * @param status The response status.
2920 + * @param text The user readable error to be displayed. Can be a translation key.
2921 + * @param parameters The parameters to use when decoding the translation key.
2922 + *###
2923 +#macro(blog__actionResponseError $status $text $parameters)
2924 + $response.setStatus($status)
2925 + #if($request.ajax)
2926 + $services.localization.render($text, $!parameters)
2927 + #else
2928 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
2929 + #end
2930 +#end
2931 +##
2932 +##
2933 +##
2934 +#**
2935 + * Check if a blog is the Default blog (The one in the 'Blog' space).
2936 + *
2937 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
2938 + * @param isDefault The resulting boolean.
2939 + *###
2940 +#macro(isDefaultBlog $blogDoc $isDefault)
2941 + #set ($result = false)
2942 + #if ($blogDoc.space == 'Blog')
2943 + #set ($result = true)
2944 + #end
2945 + #setVariable(~"$isDefault~" $result)
2946 +#end
2947 +##
2948 +##
2949 +##
2950 +#**
2951 + * Retrieve the blog posts location (space).
2952 + *
2953 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
2954 + * @param postsLocation The resulting location.
2955 + *###
2956 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
2957 + #getBlogDocument($blogSpace $blogDoc)
2958 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
2959 + #set ($postsLocation = $NULL)
2960 + #setVariable (~"$postsLocation~" $result)
2961 +#end
2962 +##
2963 +##
2964 +##
2965 +#**
2966 + * Retrieve the blog categories location (space).
2967 + *
2968 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
2969 + * @param categoriesLocation The resulting location.
2970 + *###
2971 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
2972 + #getBlogDocument($blogSpace $blogDoc)
2973 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
2974 + #set ($postsLocation = $NULL)
2975 + #setVariable (~"$categoriesLocation~" $result)
2976 +#end
2977 +###**
2978 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
2979 + * for example there is 4 different panel contexts:
2980 + * aBlog.aPost or aBlog.WebHome
2981 + * aCategorySpace.aCategory
2982 + * aCategorySpace.WebHome
2983 + * Blog.aPost or Blog.WebHome
2984 + *
2985 + * @param query The query for selecting blog entries.
2986 + * @param queryParams The parameters to bind with the generated query.
2987 + * @param targetDoc The document in which the articles will be displayed.
2988 + *###
2989 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
2990 + #set ($query = $NULL)
2991 + #set ($queryParams = $NULL)
2992 + #getCategoryAllBlogPostsQuery($resultQuery)
2993 + #set ($resultQueryParams = \{})
2994 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
2995 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
2996 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
2997 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
2998 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
2999 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
3000 + #elseif($targetDoc.getObject($blogCategoryClassname))
3001 + ## Get all posts that are in a category aCategorySpace.aCategory
3002 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
3003 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
3004 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
3005 + ## Get all posts that are in a category aCategorySpace.%
3006 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
3007 + ## Exclude incategorized posts
3008 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
3009 + #if ($targetDoc.space == $defaultBlogSpace)
3010 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
3011 + #end
3012 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
3013 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
3014 + #else
3015 + ## Get all posts in blog space aBlog
3016 + #getAllBlogPostsQuery($resultQuery)
3017 + #getBlogPostsLocation($targetDoc.space $postsLocation)
3018 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
3019 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
3020 + #end
3021 + #setVariable(~"$query~" $resultQuery)
3022 + #setVariable(~"$queryParams~" $resultQueryParams)
3023 +#end
3024 +##
3025 +##
3026 +##
3027 +###**
3028 + * Display blog posts based on the context where the posts are displayed.
3029 + * for example there is 4 different panel contexts:
3030 + * aBlog.aPost or aBlog.WebHome
3031 + * aCategorySpace.aCategory
3032 + * aCategorySpace.WebHome
3033 + * Blog.aPost or Blog.WebHome
3034 + *
3035 + * @param targetDoc The document in which the articles will be displayed.
3036 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
3037 + * @param layout Layout of the the posts to display
3038 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
3039 + * @param limit the number of posts to display
3040 + *###
3041 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
3042 + #if ($postLayout == 'full')
3043 + #set ($macro.paginated = 'yes')
3044 + #end
3045 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
3046 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
3047 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
3048 + #if (~"$!layout~" == '')
3049 + #set ($layout = $postsLayout)
3050 + #end
3051 + #if ($postsVisiblity == 'recent')
3052 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
3053 + #elseif($postsVisiblity == 'unpublished')
3054 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
3055 + #end
3056 + #elseif($targetDoc.getObject($blogCategoryClassname))
3057 + ## Display all posts that are in a category aCategorySpace.aCategory
3058 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
3059 + #getBlogPostsLayout($blogDoc $postsLayout)
3060 + #if (~"$!layout~" == '')
3061 + #set ($layout = $postsLayout)
3062 + #end
3063 + #if ($postsVisiblity == 'recent')
3064 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
3065 + #elseif($postsVisiblity == 'unpublished')
3066 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
3067 + #end
3068 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
3069 + ## Display all posts that are in a category aCategorySpace.%
3070 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
3071 + #getBlogPostsLayout($blogDoc $postsLayout)
3072 + #if (~"$!layout~" == '')
3073 + #set ($layout = $postsLayout)
3074 + #end
3075 + #if ($postsVisiblity == 'recent')
3076 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
3077 + #elseif($postsVisiblity == 'unpublished')
3078 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
3079 + #end
3080 + #else
3081 + ## Display all posts in blog space aBlog
3082 + #getBlogDocument($targetDoc.space $blogDoc)
3083 + #getBlogPostsLayout($blogDoc $postsLayout)
3084 + #if (~"$!layout~" == '')
3085 + #set ($layout = $postsLayout)
3086 + #end
3087 + #if ($postsVisiblity == 'recent')
3088 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
3089 + #elseif($postsVisiblity == 'unpublished')
3090 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
3091 + #end
3092 + #end
3093 +#end
3094 +##
3095 +##
3096 +##
3097 +#**
3098 + * Bind parameters to a query object.
3099 + *
3100 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
3101 + * @param queryParams the query parameters.
3102 + *###
3103 +#macro(bindQueryParameters $queryObj $queryParams)
3104 + #set ($output = $queryObj)
3105 + #foreach( $key in $queryParams.keySet() )
3106 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
3107 + #end
3108 + #setVariable(~"$queryObj~" $output)
3109 +#end
3110 +##
3111 +##
3112 +##
3113 +#**
3114 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
3115 + *
3116 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
3117 + * property set.
3118 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
3119 + *###
3120 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
3121 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
3122 + #set ($postsLayout = $NULL)
3123 + #setVariable (~"$postsLayout~" $res)
3124 +#end
3125 +##
3126 +##
3127 +##
3128 +#**
3129 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
3130 + *
3131 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
3132 + * @param blogDoc The resulting XDocument.
3133 + *###
3134 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
3135 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
3136 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
3137 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
3138 + #else
3139 + ## Fallback to Blog.WebHome, the default blog
3140 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
3141 + #end
3142 + #set ($blogDoc = $NULL)
3143 + #setVariable (~"$blogDoc~" $macro.result)
3144 +#end" %)
3145 +(((
3146 +(% class="macro-placeholder hidden" %)
3147 +(((
3148 +macro:velocity
3149 +)))
3150 +)))
3151 +)))
3152 +
3153 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
3154 +(((
3155 +(% class="macro-placeholder hidden" %)
3156 +(((
3157 +macro:include
3158 +)))
3159 +
3160 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
3161 + * Extract the layout parameters from a string.
3162 + *
3163 + * @param layoutParamsString The string representation of the layout parameters.
3164 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
3165 + * @param layoutsParameters The resulting layout parameters Map.
3166 + *###
3167 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
3168 + #set ($layoutsParameters = $NULL)
3169 + #set ($macro.layoutParams = \{})
3170 + #if (~"$!layoutParamsString~" != '')
3171 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
3172 + #foreach ($item in $macro.paramsArr)
3173 + #set ($itemSplit = $item.split('='))
3174 + #if ($itemSplit.size() == 2)
3175 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
3176 + #end
3177 + #end
3178 + #end
3179 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
3180 +#end" %)
3181 +(((
3182 +(% class="macro-placeholder hidden" %)
3183 +(((
3184 +macro:velocity
3185 +)))
3186 +)))
3187 +)))
3188 +
3189 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
3190 + #initLayoutVars($pDoc $pObj)
3191 + <div class=~"col-xs-12 col-sm-6 next_blog~">
3192 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
3193 + <div class=~"row~">
3194 + <div class=~"col-xs-4~">
3195 + #if ($imageAtt)
3196 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
3197 + #end
3198 + </div>
3199 + <div class=~"col-xs-8 art_det~">
3200 + <p class=~"text-left~">
3201 + #if($displayTitle)$!postTitle #end
3202 + <br/><span class=~"date_info~"> $!dateStr </span>
3203 + </p>
3204 + #displayPostDetails($pDoc)
3205 + </div>
3206 + </div>
3207 + </a>
3208 + </div>
3209 + #end
3210 + ##
3211 + ##
3212 + ##
3213 + #macro(displayPinnedPost $pDoc $pObj)
3214 + #initLayoutVars($pDoc $pObj)
3215 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
3216 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
3217 + <div class=~"thumbnail~">
3218 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
3219 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
3220 + #end
3221 + #if ($imageAtt)
3222 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
3223 + #end
3224 + <div class=~"caption~">
3225 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
3226 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
3227 + #end
3228 + #if ($displaySummaryOnPinnedPosts)
3229 + <div class=~"text-left post-summary~">
3230 + #set ($postContent = $pObj.getProperty('extract').value)
3231 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
3232 + </div>
3233 + #end
3234 + #displayPostDetails($pDoc)
3235 + </div>
3236 + </div>
3237 + </a>
3238 + </div>
3239 + #end
3240 + ##
3241 + ##
3242 + ##
3243 + #macro(formatPostDate $pDoc $pObj)
3244 + #set ($formattedDate = $NULL)
3245 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
3246 + #if (~"$!dateStr~" != '')
3247 + #set ($dateArr = $dateStr.split(' '))
3248 + #if ($dateArr.size() > 3)
3249 + #set ($dateStr = ~"~")
3250 + #foreach($s in $dateArr.subList(0, 3))
3251 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
3252 + #end
3253 + #end
3254 + #end
3255 + #setVariable(~"$formattedDate~" $dateStr)
3256 + #end
3257 + ##
3258 + ##
3259 + ##
3260 + #macro(displayPostDetails $pDoc)
3261 + <div class=~"row post-details~">
3262 + <div class=~"col-xs-8 detail~">
3263 + #if ($services.like.displayButton($pDoc.documentReference))
3264 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
3265 + ## Retrieve the likes number in XWiki 12.9+
3266 + #set ($likeNumber = $optLikeRecord.get())
3267 + #if (!$stringtool.isNumeric($likeNumber.toString()))
3268 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
3269 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
3270 + #end
3271 + #if ($stringtool.isNumeric($likeNumber.toString()))
3272 + <div class=~"post-likes btn btn-default disabled badge~"
3273 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
3274 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
3275 + </div>
3276 + #end
3277 + #elseif ($services.ratings)
3278 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
3279 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
3280 + <ul class=~"pull-left note list-inline~">
3281 + #foreach ($x in [1..5])
3282 + #set ($cls = ~"~")
3283 + #if ($x > $averageVote)
3284 + #set ($cls = ~"-o~")
3285 + #end
3286 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
3287 + #end
3288 + </ul>
3289 + #end
3290 + #end
3291 + </div>
3292 + #if ($showPostComments)
3293 + <div class=~"col-xs-4 com_det~">
3294 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
3295 + </div>
3296 + #end
3297 + </div>
3298 + #end
3299 + ##
3300 + ##
3301 + ##
3302 + #macro(initLayoutVars $pDoc $pObj)
3303 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
3304 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
3305 + #isPublished($pObj $isPublished)
3306 + #isHidden($pObj $isHidden)
3307 + #getEntryDate($pDoc $pObj $postDate)
3308 + #formatPostDate($postDate $dateStr)
3309 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
3310 + #set ($nbComments = $pDoc.getComments().size())
3311 + #set ($showPostComments = true)
3312 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
3313 + #set ($showPostComments = false)
3314 + #end
3315 + #end
3316 + ##
3317 + ##
3318 + ##
3319 + #macro(displayEditPinnedPostsButton)
3320 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
3321 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
3322 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
3323 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
3324 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
3325 + <div class=~"edit-pinned-posts-container~">
3326 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
3327 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
3328 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
3329 + </a>
3330 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
3331 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
3332 + </div>
3333 + </div>
3334 + #if (~"$!pinnedPostsObj~" == '')
3335 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
3336 + #end
3337 + #end
3338 + #end" %)
3339 +(((
3340 +(% class="macro-placeholder hidden" %)
3341 +(((
3342 +macro:velocity
3343 +)))
3344 +)))
3345 +
3346 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
3347 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
3348 + #getEntryObject($postDoc $postObj)
3349 + #if (~"$!postObj~" != '')
3350 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
3351 + ##
3352 + #set ($displayTitle = true)
3353 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
3354 + #set ($displayTitle = false)
3355 + #end
3356 + ##
3357 + #set ($displayTitleFirstOnPinnedPosts = false)
3358 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
3359 + #set ($displayTitleFirstOnPinnedPosts = true)
3360 + #end
3361 + ##
3362 + #set ($displaySummaryOnPinnedPosts = true)
3363 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
3364 + #set ($displaySummaryOnPinnedPosts = false)
3365 + #end
3366 + ##
3367 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
3368 + #if ($postIndex == 0)
3369 + #set ($stopBlogPostsDisplay = false)
3370 + #end
3371 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
3372 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
3373 + #set($scaleWidth = 600)
3374 + #set($imgQs=~"width=$scaleWidth~")
3375 + ## Display pinned posts
3376 + ## Get the list of pinned posts
3377 + #set ($pinnedPosts = [])
3378 + #set ($pinnedPostsSourceDoc = $NULL)
3379 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
3380 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
3381 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
3382 + #end
3383 + #if (~"$!pinnedPostsSourceDoc~" != '')
3384 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
3385 + #if (~"$!pinnedPostsObj~" != '')
3386 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
3387 + #if (~"$!orderedPinnedPostsJSON~" != '')
3388 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
3389 + #else
3390 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
3391 + #end
3392 + #end
3393 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
3394 + \{\{html clean=~"false~"}}
3395 + #set ($x = 0)
3396 + #set ($showPinnedPostsButton = true)
3397 + #foreach ($pinnedPost in $pinnedPosts)
3398 + #if ($x == 0)
3399 + <div class=~"row flex-container~">
3400 + #if ($showPinnedPostsButton)
3401 + #displayEditPinnedPostsButton()
3402 + #set($showPinnedPostsButton = false)
3403 + #end
3404 + #end
3405 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
3406 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
3407 + #if (~"$!pinnedPostObj~" != '')
3408 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
3409 + #end
3410 + #set ($x = $mathtool.add($x, 1))
3411 + #if ($x == 3)
3412 + #set ($x = 0)
3413 + </div>
3414 + #end
3415 + #end
3416 + #if ($mathtool.mod($x, 3) != 0)
3417 + </div>
3418 + #end
3419 + \{\{/html}}
3420 +
3421 + ## If the first post is a pinned post : this means that all the posts are pinned
3422 + ## In this case, avoid displaying the posts again after the pinned posts section.
3423 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
3424 + #set ($stopBlogPostsDisplay = true)
3425 + #end
3426 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
3427 +
3428 + \{\{html}}
3429 + <div class=~"row no-pinnded-posts~">
3430 + #displayEditPinnedPostsButton()
3431 + </div>
3432 + \{\{/html}}
3433 +
3434 + #end
3435 + #end
3436 + #if (!$stopBlogPostsDisplay)
3437 + \{\{html clean=~"false~"}}
3438 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
3439 + #set ($nbDisplayedPosts = 0)
3440 + #end
3441 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
3442 + #if ($nbDisplayedPosts != 0)
3443 + </div>
3444 + #set ($lastHtmlTag = 'c')
3445 + #end
3446 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
3447 + <div class=~"row~">
3448 + #set ($lastHtmlTag = 'o')
3449 + #set ($lastRowClass = ~"~")
3450 + #else
3451 + <div class=~"row flex-container~">
3452 + #set ($lastHtmlTag = 'o')
3453 + #set ($lastRowClass = ~"flex~")
3454 + #end
3455 + #end
3456 + #displaySmallPost($postDoc $postObj)
3457 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
3458 + </div>
3459 + #set ($lastHtmlTag = 'c')
3460 + #end
3461 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
3462 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
3463 + #if (~"$!lastHtmlTag~" == 'o')
3464 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
3465 + <div class=~"col-xs-12 col-sm-6~"></div>
3466 + #end
3467 + </div>
3468 + #end
3469 + #end
3470 + \{\{/html}}
3471 + #end
3472 + #else
3473 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
3474 + #end
3475 + #else
3476 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
3477 + #end" %)
3478 +(((
3479 +(% class="macro-placeholder hidden" %)
3480 +(((
3481 +macro:velocity
3482 +)))
3483 +
3484 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"col-xs-12 col-sm-6 next_blog~">
3485 +<a href=~"/Nieuws/Audit%20BMI%20en%20BORG~" class=~"thumbnail~">
3486 +<div class=~"row~">
3487 +<div class=~"col-xs-4~">
3488 +<img src=~"/download/Nieuws/Audit%20BMI%20en%20BORG/giphy.gif?width=600&rev=1.1~" />
3489 +</div>
3490 +<div class=~"col-xs-8 art_det~">
3491 +<p class=~"text-left~">
3492 +Audit BMI en BORG <br/><span class=~"date_info~"> Jan 15, 2024, </span>
3493 +</p>
3494 +<div class=~"row post-details~">
3495 +<div class=~"col-xs-8 detail~">
3496 +<div class=~"post-likes btn btn-default disabled badge~"
3497 +title=~"Number of likes on this page: 0~">
3498 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">0</span>
3499 +</div>
3500 +</div>
3501 +<div class=~"col-xs-4 com_det~">
3502 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
3503 +</div>
3504 +</div>
3505 +</div>
3506 +</div>
3507 +</a>
3508 +</div>" %)
3509 +(((
3510 +(% class="macro-placeholder hidden" %)
3511 +(((
3512 +macro:html
3513 +)))
3514 +
3515 +(% class="col-xs-12 col-sm-6 next_blog" %)
3516 +(((
3517 +(% class="row" %)
3518 +(((
3519 +(% class="col-xs-4" %)
3520 +(((
3521 +[[~[~[image:/download/Nieuws/Audit%20BMI%20en%20BORG/giphy.gif?width=600&rev=1.1~]~]>>path:/Nieuws/Audit%20BMI%20en%20BORG||class="thumbnail"]]
3522 +)))
3523 +
3524 +(% class="col-xs-8 art_det" %)
3525 +(((
3526 +(% class="text-left" %)
3527 +[[Audit BMI en BORG
3528 +(% class="date_info" %) Jan 15, 2024,>>path:/Nieuws/Audit%20BMI%20en%20BORG||class="thumbnail"]]
3529 +
3530 +(% class="row post-details" %)
3531 +(((
3532 +(% class="col-xs-8 detail" %)
3533 +(((
3534 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 0" %)
3535 +(((
3536 +[[(% class="like-number" %)0>>path:/Nieuws/Audit%20BMI%20en%20BORG||class="thumbnail"]]
3537 +)))
3538 +)))
3539 +
3540 +(% class="col-xs-4 com_det" %)
3541 +(((
3542 +(% class="text-right" %)
3543 +[[(0)>>path:/Nieuws/Audit%20BMI%20en%20BORG||class="thumbnail"]]
3544 +)))
3545 +)))
3546 +)))
3547 +)))
3548 +)))
3549 +)))
3550 +)))
3551 +)))
3552 +
3553 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Nieuwsbrief december 2023~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG~"" %)
3554 +(((
3555 +(% class="macro-placeholder hidden" %)
3556 +(((
3557 +macro:blogPostLayoutCards
3558 +)))
3559 +
3560 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
3561 +(((
3562 +(% class="macro-placeholder hidden" %)
3563 +(((
3564 +macro:include
3565 +)))
3566 +
3567 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
3568 +(((
3569 +(% class="macro-placeholder hidden" %)
3570 +(((
3571 +macro:include
3572 +)))
3573 +
3574 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
3575 +#set($blogClassname = 'Blog.BlogClass')
3576 +#set($blogTemplate = 'Blog.BlogTemplate')
3577 +#set($blogSheet = 'Blog.BlogSheet')
3578 +## Blog entries
3579 +#set($blogPostClassname = 'Blog.BlogPostClass')
3580 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
3581 +#set($blogPostSheet = 'Blog.BlogPostSheet')
3582 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
3583 +#set($oldArticleClassname = 'XWiki.ArticleClass')
3584 +## Categories
3585 +#set($blogCategoryClassname = 'Blog.CategoryClass')
3586 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
3587 +#set($blogCategorySheet = 'Blog.CategorySheet')
3588 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
3589 +#set($oldBlogCategoryClassname = 'Blog.Categories')
3590 +#set($defaultCategoryParent = 'Blog.Categories')
3591 +## Style
3592 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
3593 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
3594 +## Clientside scripts
3595 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
3596 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
3597 +## Misc
3598 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
3599 +#set($isBlogPost = $doc.getObject($blogPostClassname))
3600 +#set($defaultBlogSpace = 'Blog')
3601 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
3602 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
3603 +##
3604 +##
3605 +##
3606 +#**
3607 + * Displays an image, taken from the blog style document.
3608 + *
3609 + * @param $imgName The name of the icon from icons set to use.
3610 + *#
3611 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
3612 +(((
3613 +(% class="macro-placeholder hidden" %)
3614 +(((
3615 +macro:velocity
3616 +)))
3617 +)))
3618 +)))
3619 +
3620 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
3621 +##
3622 +##
3623 +## Import the blog skin and javascripts.
3624 +$!xwiki.ssx.use($blogStyleDocumentName)##
3625 +$!xwiki.jsx.use($blogScriptsDocumentName)##
3626 +##
3627 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
3628 +#template('hierarchy_macros.vm')##
3629 +##
3630 +##
3631 +#**
3632 + * Prints a blog. This is the main macro used in the BlogSheet.
3633 + *
3634 + * @param blogDoc the XDocument holding the blog definition object.
3635 + *###
3636 +#macro(printBlog $blogDoc)
3637 + \{\{include reference='Blog.CreatePost'/}}
3638 +
3639 + ## Use the blogPostList macro to display the blogposts
3640 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
3641 + ## do not support FTM the monthly and weekly blog display types
3642 + #getBlogDisplayType($blogDoc $displayType)
3643 + #if ($displayType == 'weekly' || $displayType == 'monthly')
3644 + #getBlogEntries($blogDoc $entries)
3645 + #displayBlog($entries 'index' true true)
3646 + #displayNavigationLinks($blogDoc)
3647 + #else
3648 + #getBlogDisplayType($blogDoc $displayType)
3649 + #set ($paginated = 'no')
3650 + #if ($displayType == 'paginated')
3651 + #set ($paginated = 'yes')
3652 + #end
3653 + #getBlogPostsLayout($blogDoc $postsLayout)
3654 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
3655 + #end
3656 +#end
3657 +##
3658 +##
3659 +##
3660 +#**
3661 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
3662 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
3663 + * all entries).
3664 + *
3665 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
3666 + *###
3667 +#macro(showBlogInfo $blogDoc)
3668 + #if($blogDoc.getObject($blogClassname))
3669 + ## Keep testing for inline action for backward compatibility with older blogs.
3670 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
3671 + #macro(displayProperty $blogDoc $propname)
3672 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
3673 + : $blogDoc.display($propname)
3674 + #end
3675 + #displayProperty($blogDoc 'title')
3676 + #displayProperty($blogDoc 'description')
3677 + #displayProperty($blogDoc 'displayType')
3678 + #displayProperty($blogDoc 'itemsPerPage')
3679 + #displayProperty($blogDoc 'postsLayout')
3680 + #displayProperty($blogDoc 'postsLayoutParameters')
3681 + #else
3682 + $blogDoc.display('description')
3683 + #end
3684 + #elseif($doc.fullName == $blogSheet)
3685 += $services.localization.render('blog.code.blogsheet') =
3686 + \{\{translation key='blog.code.sheetexplanation'/}}
3687 + #else
3688 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
3689 + #end
3690 +#end
3691 +##
3692 +##
3693 +##
3694 +#**
3695 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
3696 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
3697 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
3698 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
3699 + *
3700 + * @param space A <tt>String</tt>, the name of the space where to search.
3701 + * @param blogDoc The resulting XDocument.
3702 + *###
3703 +#macro(getBlogDocument $space $blogDoc)
3704 + #set ($result = $NULL)
3705 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
3706 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
3707 + ## identify the right blog based on a configuration object in a WebPreferences page.
3708 + #set ($spaceReference = $services.model.resolveSpace($space))
3709 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
3710 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
3711 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
3712 + #if ($preferencesObj)
3713 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
3714 + #end
3715 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
3716 + #if (~"$!result~" == '')
3717 + ## First, try the Space.WebHome, for a whole-space blog
3718 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
3719 + #if(!$result.getObject($blogClassname))
3720 + ## Second, try the Space.Blog document
3721 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
3722 + #if(!$result.getObject($blogClassname))
3723 + ## Third, try searching for a blog document in the current space
3724 + ## Prevent the query fail when the space contains dots '.'
3725 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
3726 + #if($blogDocs.size() > 0)
3727 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
3728 + #else
3729 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
3730 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
3731 + #if($blogDocs.size() > 0)
3732 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
3733 + #else
3734 + ## Last, fallback to Blog.WebHome, the default blog
3735 + #set($result = $xwiki.getDocument('Blog.WebHome'))
3736 + #end
3737 + #end
3738 + #end
3739 + #end
3740 + #end
3741 + #set ($blogDoc = $NULL)
3742 + #setVariable (~"$blogDoc~" $result)
3743 +#end
3744 +##
3745 +##
3746 +##
3747 +#**
3748 + * Retrieve the blog title.
3749 + *
3750 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
3751 + * @param title The resulting title.
3752 + *###
3753 +#macro(getBlogTitle $blogDoc $title)
3754 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
3755 + #set ($title = $NULL)
3756 + #setVariable (~"$title~" $!blogDoc.displayTitle)
3757 +#end
3758 +##
3759 +##
3760 +##
3761 +#**
3762 + * Retrieve the blog description.
3763 + *
3764 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
3765 + * property set.
3766 + * @param description The resulting description.
3767 + *###
3768 +#macro(getBlogDescription $blogDoc $description)
3769 + #getBlogProperty($blogDoc 'description' '' $result)
3770 + #set ($description = $NULL)
3771 + #setVariable (~"$description~" $result)
3772 +#end
3773 +##
3774 +##
3775 +##
3776 +#**
3777 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
3778 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
3779 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
3780 + * month), or all.
3781 + *
3782 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
3783 + * @param entries The resulting list of entries to display, a list of XDocument names.
3784 + *###
3785 +#macro(getBlogEntries $blogDoc $entries)
3786 + #if (!$entries)
3787 + #setVariable (~"$entries~" [])
3788 + #end
3789 + #getAllBlogPostsQuery($query)
3790 + #isDefaultBlog($blogDoc $isDefault)
3791 + #set($queryParams = \{})
3792 + #if ($isDefault)
3793 + #getCategoryAllBlogPostsQuery($query)
3794 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
3795 + #set($discard = $queryParams.put('creator', $xcontext.user))
3796 + #set($discard = $queryParams.put('space', $blogDoc.space))
3797 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
3798 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
3799 + #else
3800 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
3801 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
3802 + #set($discard = $queryParams.put('space', $blogPostsLocation))
3803 + #set($discard = $queryParams.put('parent', $blogDoc.space))
3804 + #end
3805 + #getBlogDisplayType($blogDoc $displayType)
3806 + #if($displayType == 'weekly')
3807 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
3808 + #elseif($displayType == 'monthly')
3809 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
3810 + #elseif($displayType == 'all')
3811 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
3812 + #else
3813 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
3814 + #end
3815 +#end
3816 +##
3817 +##
3818 +##
3819 +#**
3820 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
3821 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
3822 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
3823 + * (10 if not defined).
3824 + *
3825 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
3826 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
3827 + * refined to restrict to a given space, or to a given search criteria, etc.
3828 + * @param entries The resulting list of entries to display, a list of XDocument names.
3829 + * @param queryParams The parameters to bind with the query.
3830 + *###
3831 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
3832 + #if (!$entries)
3833 + #setVariable (~"$entries~" [])
3834 + #end
3835 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
3836 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
3837 + #bindQueryParameters($countQueryObj $queryParams)
3838 + #bindQueryParameters($queryObj $queryParams)
3839 + #set($totalEntries = $countQueryObj.count())
3840 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
3841 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
3842 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
3843 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
3844 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
3845 +#end
3846 +##
3847 +##
3848 +##
3849 +#**
3850 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
3851 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
3852 + * digit year). Initially the current week is displayed.
3853 + *
3854 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
3855 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
3856 + * refined to restrict to a given space, or to a given search criteria, etc.
3857 + * @param entries The resulting list of entries to display, a list of XDocument names.
3858 + * @param queryParams The parameters to bind with the query.
3859 + *###
3860 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
3861 + #if (!$entries)
3862 + #setVariable (~"$entries~" [])
3863 + #end
3864 + #getRequestedWeek($weekDate)
3865 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
3866 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
3867 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
3868 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
3869 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
3870 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
3871 + #bindQueryParameters($countQueryObj $queryParams)
3872 + #bindQueryParameters($queryObj $queryParams)
3873 + #set($totalEntries = $countQueryObj.count())
3874 + #set($discard = $entries.addAll($queryObj.execute()))
3875 +#end
3876 +##
3877 +##
3878 +##
3879 +#**
3880 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
3881 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
3882 + * digit year). Initially the current month is displayed.
3883 + *
3884 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
3885 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
3886 + * refined to restrict to a given space, or to a given search criteria, etc.
3887 + * @param entries The resulting list of entries to display, a list of XDocument names.
3888 + * @param queryParams The parameters to bind with the query.
3889 + *###
3890 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
3891 + #if (!$entries)
3892 + #setVariable (~"$entries~" [])
3893 + #end
3894 + #getRequestedMonth($monthDate)
3895 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
3896 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
3897 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
3898 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
3899 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
3900 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
3901 + #bindQueryParameters($countQueryObj $queryParams)
3902 + #bindQueryParameters($queryObj $queryParams)
3903 + #set($totalEntries = $countQueryObj.count())
3904 + #set($discard = $entries.addAll($queryObj.execute()))
3905 +#end
3906 +##
3907 +##
3908 +##
3909 +#**
3910 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
3911 + *
3912 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
3913 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
3914 + * refined to restrict to a given space, or to a given search criteria, etc.
3915 + * @param entries The resulting list of entries to display, a list of XDocument names.
3916 + * @param queryParams The parameters to bind with the query.
3917 + *###
3918 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
3919 + #if (!$entries)
3920 + #setVariable (~"$entries~" [])
3921 + #end
3922 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
3923 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
3924 + #bindQueryParameters($countQueryObj $queryParams)
3925 + #bindQueryParameters($queryObj $queryParams)
3926 + #set($totalEntries = $countQueryObj.count())
3927 + #set($discard = $entries.addAll($queryObj.execute()))
3928 +#end
3929 +##
3930 +##
3931 +##
3932 +#**
3933 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
3934 + *
3935 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
3936 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
3937 + * refined to restrict to a given space, or to a given search criteria, etc.
3938 + * @param queryParams The parameters to bind with the query.
3939 + * @param entries The resulting list of entries to display, a list of XDocument names.
3940 + *###
3941 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
3942 + #if (!$entries)
3943 + #setVariable (~"$entries~" [])
3944 + #end
3945 + #set($query = ~"$\{query} and isPublished.value = 0~")
3946 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
3947 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
3948 + #bindQueryParameters($countQueryObj $queryParams)
3949 + #bindQueryParameters($queryObj $queryParams)
3950 + #set($totalEntries = $countQueryObj.count())
3951 + #set($discard = $entries.addAll($queryObj.execute()))
3952 +#end
3953 +##
3954 +##
3955 +##
3956 +#**
3957 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
3958 + *
3959 + * @param entries The resulting list of entries to display, a list of XDocument names.
3960 + *###
3961 +#macro(getGlobalBlogEntries $entries)
3962 + #if (!$entries)
3963 + #setVariable (~"$entries~" [])
3964 + #end
3965 + #getAllBlogPostsQuery($query)
3966 + #set($totalEntries = $services.query.hql($query).count())
3967 + #set($defaultItemsPerPage = 20)
3968 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
3969 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
3970 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
3971 +#end
3972 +#**
3973 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
3974 + * blog, nor specify a range or an ordering criteria.
3975 + *
3976 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
3977 + *
3978 + * @param query The basic query for selecting blog entries.
3979 + *#
3980 +#macro(getBlogEntriesBaseQuery $query)
3981 + #getAllBlogPostsQuery($query)
3982 +#end
3983 +#**
3984 + * Return the Query for selecting the all wiki blog posts without filtering
3985 + *
3986 + * @param query The basic query for selecting blog entries.
3987 + *#
3988 +#macro(getAllBlogPostsQuery $query)
3989 + #set ($query = $NULL)
3990 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
3991 + IntegerProperty hidden, DateProperty publishDate
3992 + where doc.fullName <> '$blogPostTemplate' and
3993 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
3994 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
3995 + hidden.id.id = obj.id and hidden.id.name='hidden' and
3996 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
3997 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
3998 +#end
3999 +##
4000 +##
4001 +##
4002 +###**
4003 + * Return the Query for selecting the all wiki blog posts with categories filtering
4004 + *
4005 + * @param query The basic query for selecting blog entries.
4006 + *###
4007 +#macro(getCategoryAllBlogPostsQuery $query)
4008 + #set ($query = $NULL)
4009 + #getAllBlogPostsQuery($baseQuery)
4010 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
4011 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
4012 +#end
4013 +##
4014 +##
4015 +##
4016 +#**
4017 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
4018 + * week), monthly (all entries in a month), or all.
4019 + *
4020 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
4021 + * property set.
4022 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
4023 + *###
4024 +#macro(getBlogDisplayType $blogDoc $displayType)
4025 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
4026 + #set ($displayType = $NULL)
4027 + #setVariable (~"$displayType~" $result)
4028 +#end
4029 +##
4030 +##
4031 +##
4032 +#**
4033 + * Displays a list of entries.
4034 + *
4035 + * @param entries The entries to display, a list of XDocument names.
4036 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
4037 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
4038 + * used values: index, single, category, search, unpublished, hidden.
4039 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
4040 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
4041 + * displayed alone on their page since it's the page title which is used in this case)
4042 + *###
4043 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
4044 + #set($blogDay = '')
4045 + (% class=~"hfeed $!\{displaying}~" ~%)(((
4046 + (% class=~"blogDay~" ~%)(((
4047 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
4048 + #getEntryObject($entryDoc $entryObj)
4049 + ## Although all entries should have one of the two objects, better check to be sure.
4050 + #if(~"$!\{entryObj}~" != '')
4051 + #getEntryDate($entryDoc $entryObj $entryDate)
4052 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
4053 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
4054 + #if($blogDay != $entryDateStr)
4055 + #if($blogDay != '')
4056 + )))
4057 + (% class=~"blogDay~" ~%)(((
4058 + #end
4059 + #displayBlogDate($entryDate)
4060 + #set ($blogDay = $entryDateStr)
4061 + #end
4062 + ## Finally, display the entry.
4063 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
4064 + #end
4065 + #end
4066 + )))## blogDay
4067 + )))## hfeed
4068 +#end
4069 +##
4070 +##
4071 +##
4072 +#**
4073 + * Get the entry object, either a new BlogPost or an old Article.
4074 + *
4075 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4076 + * @param entryObj The resulting xobject of the blog post.
4077 + *###
4078 +#macro(getEntryObject $entryDoc $__entryObj)
4079 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
4080 + #if(!$result)
4081 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
4082 + #end
4083 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
4084 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
4085 + ## overwritten in this case but it's less likely to have such a variable defined before.
4086 + #set ($__entryObj = $NULL)
4087 + #setVariable (~"$__entryObj~" $result)
4088 +#end
4089 +##
4090 +##
4091 +##
4092 +#**
4093 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
4094 + * the document creation date, but can be edited by the user.
4095 + *
4096 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4097 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4098 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
4099 + *###
4100 +#macro(getEntryDate $entryDoc $entryObj $result)
4101 + #set ($result = $NULL)
4102 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
4103 +#end
4104 +##
4105 +##
4106 +##
4107 +#**
4108 + * Displays a date, nicely formatted as a calendar page.
4109 + *
4110 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
4111 + *###
4112 +#macro(displayBlogDate $date)
4113 + #set($year = $xwiki.formatDate($date, 'yyyy'))
4114 + ## 3 letter month name, like Jan, Dec.
4115 + #set($month = $xwiki.formatDate($date, 'MMM'))
4116 + ## Uncomment to get a full length month name, like January, December.
4117 + ## TODO: this could be defined somewhere in the blog style.
4118 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
4119 + #set($day = $xwiki.formatDate($date, 'dd'))
4120 + (% class=~"blogdate~" ~%)
4121 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
4122 +#end
4123 +##
4124 +##
4125 +##
4126 +#**
4127 + * Displays a blog article: management tools, header, content, footer.
4128 + *
4129 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4130 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4131 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
4132 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
4133 + * when they're displayed alone on their page since it's the page title which is used in this case)
4134 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
4135 + *###
4136 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
4137 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
4138 + #isPublished($entryObj $isPublished)
4139 + #isHidden($entryObj $isHidden)
4140 + #if($doc.fullName == $entryDoc.fullName)
4141 + (% class=~"hentry single-article~" ~%)(((
4142 + #else
4143 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
4144 + #end
4145 + #if ($shouldDisplayActions)
4146 + #displayEntryTools($entryDoc $entryObj)
4147 + #end
4148 + #if($shouldDisplayTitle)
4149 + #displayEntryTitle($entryDoc $entryObj)
4150 + #end
4151 + #if($doc.fullName == $entryDoc.fullName)
4152 + #if(!$isPublished)
4153 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
4154 + #elseif($isHidden)
4155 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
4156 + #end
4157 + #end
4158 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
4159 + #displayEntryFooter($entryDoc $entryObj)
4160 + )))## hentry
4161 +#end
4162 +##
4163 +##
4164 +##
4165 +#**
4166 + * Checks if the provided blog is published or not.
4167 + *
4168 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4169 + * @param isPublished The resulting boolean, true if the entry is considered published.
4170 + *###
4171 +#macro(isPublished $entryObj $isPublished)
4172 + #set ($isPublished = $NULL)
4173 + ## This should work for both old articles, which don't have the 'published' property at all, and
4174 + ## are considered published by default, and new entries, that should have 1 if published.
4175 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
4176 + #setVariable (~"$isPublished~" true)
4177 + #else
4178 + #setVariable (~"$isPublished~" false)
4179 + #end
4180 +#end
4181 +##
4182 +##
4183 +##
4184 +#**
4185 + * Checks if the provided blog is hidden or not.
4186 + *
4187 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
4188 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
4189 + *###
4190 +#macro(isHidden $entryObj $isHidden)
4191 + #set ($isHidden = $NULL)
4192 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
4193 + ## are considered visible by default, and new entries, that should have 1 if hidden.
4194 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
4195 + #setVariable (~"$isHidden~" true)
4196 + #else
4197 + #setVariable (~"$isHidden~" false)
4198 + #end
4199 +#end
4200 +##
4201 +##
4202 +##
4203 +#**
4204 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
4205 + *
4206 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4207 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4208 + *###
4209 +#macro(displayEntryTools $entryDoc $entryObj)
4210 + #if($xcontext.action == 'view')
4211 + (% class=~"blog-entry-toolbox~" ~%)(((
4212 + #displayPublishButton($entryDoc $entryObj)
4213 + #displayHideShowButton($entryDoc $entryObj)
4214 + #displayEditButton($entryDoc $entryObj)
4215 + #displayDeleteButton($entryDoc $entryObj)
4216 + )))
4217 + #end
4218 +#end
4219 +##
4220 +##
4221 +##
4222 +#**
4223 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
4224 + *
4225 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4226 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4227 + * @todo AJAX calls.
4228 + *###
4229 +#macro(displayPublishButton $entryDoc $entryObj)
4230 + #isPublished($entryObj $isPublished)
4231 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
4232 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
4233 + #end
4234 +#end
4235 +##
4236 +##
4237 +##
4238 +#**
4239 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
4240 + *
4241 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4242 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4243 + *###
4244 +#macro(displayHideShowButton $entryDoc $entryObj)
4245 + #isPublished($entryObj $isPublished)
4246 + #isHidden($entryObj $isHidden)
4247 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
4248 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
4249 + #set ($queryString = \{
4250 + 'xredirect' : $thisURL,
4251 + 'form_token' : $services.csrf.getToken()
4252 + })
4253 + #if ($isHidden)
4254 + #set ($discard = $queryString.putAll(\{
4255 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
4256 + 'comment' : $services.localization.render('blog.code.madevisible')
4257 + }))
4258 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
4259 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
4260 + #else
4261 + #set ($discard = $queryString.putAll(\{
4262 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
4263 + 'comment' : $services.localization.render('blog.code.hid')
4264 + }))
4265 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
4266 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
4267 + #end
4268 + #end
4269 +#end
4270 +##
4271 +##
4272 +##
4273 +#**
4274 + * Displays the edit button to those that can edit the article.
4275 + *
4276 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4277 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4278 + *###
4279 +#macro(displayEditButton $entryDoc $entryObj)
4280 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
4281 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
4282 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
4283 + #end
4284 +#end
4285 +##
4286 +##
4287 +##
4288 +#**
4289 + * Displays the delete button to those that can edit the article.
4290 + *
4291 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4292 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4293 + * @todo AJAX calls.
4294 + *###
4295 +#macro(displayDeleteButton $entryDoc $entryObj)
4296 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
4297 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
4298 + #end
4299 +#end
4300 +##
4301 +##
4302 +##
4303 +#**
4304 + * Displays the title of the entry.
4305 + *
4306 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4307 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4308 + *###
4309 +#macro(displayEntryTitle $entryDoc $entryObj)
4310 + #if($doc.fullName == $entryDoc.fullName)
4311 + (% class=~"entry-title~" ~%)
4312 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
4313 + #else
4314 + (% class=~"entry-title~" ~%)
4315 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
4316 + #end
4317 +#end
4318 +##
4319 +##
4320 +##
4321 +#**
4322 + * Displays the body of the entry.
4323 + *
4324 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4325 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4326 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
4327 + *###
4328 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
4329 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
4330 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
4331 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
4332 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
4333 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
4334 + ))) ## entry-content
4335 + (% class=~"clearfloats~" ~%)((()))
4336 +#end
4337 +##
4338 +##
4339 +##
4340 +#**
4341 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
4342 + * of the <tt>extract</tt> field (if not empty).
4343 + *
4344 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4345 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4346 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
4347 + * @param entryContent The resulting content.
4348 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
4349 + * <tt>onlyExtract</tt> is <tt>true</tt>)
4350 + *###
4351 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
4352 + #if ($onlyExtract)
4353 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
4354 + ## of the content.
4355 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
4356 + #end
4357 + #if(~"$!macro.result~" == '')
4358 + #set($macro.result = $entryObj.getProperty('content').value)
4359 +#* Disabled until the content can be cleanly cut.
4360 +* #if($onlyExtract && $result.length()>$maxchars)
4361 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
4362 +* #set($i = $i + 1)
4363 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
4364 +* #end
4365 +## *###
4366 + #elseif (!$removeEllipsis)
4367 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
4368 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
4369 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
4370 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
4371 + #end
4372 + #end
4373 + #set ($entryContent = $NULL)
4374 + #setVariable (~"$entryContent~" $macro.result)
4375 +#end
4376 +##
4377 +##
4378 +##
4379 +#**
4380 + * Displays the footer of the entry.
4381 + *
4382 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4383 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4384 + *###
4385 +#macro(displayEntryFooter $entryDoc $entryObj)
4386 + (% class=~"entry-footer~" ~%)(((
4387 + #isPublished($entryObj $isPublished)
4388 + (% class='entry-author-label' ~%)
4389 + #if($isPublished)
4390 + \{\{translation key='blog.code.postedby'/}} ##
4391 + #else
4392 + \{\{translation key='blog.code.createdby'/}} ##
4393 + #end
4394 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
4395 + #getEntryDate($entryDoc $entryObj $entryDate)
4396 + #listCategories($entryObj) #*
4397 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
4398 + ## we assume cannot be more than 3 seconds.
4399 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
4400 + #if ($showcomments)
4401 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
4402 + #end ##
4403 + #if($entryDoc != $doc) ##
4404 + #displayEntryBlogLocation($entryDoc $entryObj) ##
4405 + #end
4406 + )))## entry-footer
4407 +#end
4408 +##
4409 +##
4410 +#**
4411 + * Display the blog for the entry (if it is not the currently displayed blog)
4412 + *
4413 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
4414 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4415 + *###
4416 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
4417 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
4418 + #if(~"$!blogPostsLocation~" != ~"~") ##
4419 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
4420 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
4421 + #if($doc.documentReference != $blogDocRef) ##
4422 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
4423 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
4424 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
4425 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
4426 + )))(%~%)##
4427 + #end
4428 + #end
4429 + #end
4430 +#end
4431 +##
4432 +##
4433 +##
4434 +##
4435 +#**
4436 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
4437 + *
4438 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
4439 + *###
4440 +#macro(listCategories $entryObj)
4441 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
4442 + #set($categories = $entryObj.getProperty('category').value)
4443 + #set($first = true)
4444 + #if($categories.size() > 0)
4445 + #foreach($category in $categories)
4446 + #set($categoryDoc = $!xwiki.getDocument($category))
4447 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
4448 + #if($foreach.count == 1)
4449 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
4450 + #else
4451 + , ##
4452 + #end##
4453 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
4454 + #end##
4455 + #end##
4456 + #end
4457 + #end
4458 +#end
4459 +##
4460 +##
4461 +##
4462 +#**
4463 + * Displays blog pagination links (older and newer entries).
4464 + *
4465 + * @param blogDoc the XDocument holding the blog definition object.
4466 + *###
4467 +#macro(displayNavigationLinks $blogDoc)
4468 + (% class=~"clearfloats~" ~%)((()))
4469 + #getBlogDisplayType($blogDoc $displayType)
4470 + #if($displayType == 'weekly')
4471 + (% class=~"pagingLinks~" ~%)(((
4472 + #getRequestedWeek($weekDate)
4473 + $weekDate.addWeeks(-1)##
4474 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
4475 + #sep()
4476 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
4477 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
4478 + )))
4479 + #elseif($displayType == 'monthly')
4480 + (% class=~"pagingLinks~" ~%)(((
4481 + #getRequestedMonth($monthDate)
4482 + $monthDate.addMonths(-1)##
4483 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
4484 + #sep()
4485 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
4486 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
4487 + )))
4488 + #elseif($displayType == 'all')
4489 + #else
4490 + ## Paginated
4491 + #if(($totalPages > 1))
4492 + #set($queryString = '')
4493 + #foreach($p in $request.getParameterNames())
4494 + #if($p != 'page' && $p != 'ipp')
4495 + #foreach($v in $request.getParameterValues($p))
4496 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
4497 + #end
4498 + #end
4499 + #end
4500 + (% class=~"pagingLinks~" ~%)(((
4501 + #if ($currentPageNumber < $totalPages)
4502 + #set($currentPageNumber = $currentPageNumber + 1)
4503 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
4504 + #set($currentPageNumber = $currentPageNumber - 1)
4505 + #end
4506 + #if ($currentPageNumber > 1)
4507 + #if ($currentPageNumber < $totalPages)
4508 + #sep()
4509 + #end
4510 + #set($currentPageNumber = $currentPageNumber - 1)
4511 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
4512 + #set($currentPageNumber = $currentPageNumber + 1)
4513 + #end
4514 + (% class=~"clear~" ~%)(%~%)
4515 + )))## pagingLinks
4516 + #end
4517 + #end
4518 +#end
4519 +##
4520 +##
4521 +##
4522 +#**
4523 + * Displays a message box with ~"publish~" icon.
4524 + *
4525 + * @param message A text message concerning blog article publishing
4526 + *###
4527 +#macro(publishMessageBox $message)
4528 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
4529 +#end
4530 +#**
4531 + * Displays a message box with ~"show/hide~" icon.
4532 + *
4533 + * @param message A text message concerning blog article hiding
4534 + *###
4535 +#macro(hideMessageBox $message)
4536 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
4537 +#end
4538 +##
4539 +##
4540 +##
4541 +#**
4542 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
4543 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
4544 + *
4545 + * @param monthDate The resulting week, a JODATime MutableDateTime.
4546 + *###
4547 +#macro(getRequestedWeek $weekDate)
4548 + #set ($weekDate = $NULL)
4549 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
4550 + #if(~"$!\{request.year}~" != '')
4551 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
4552 + #end
4553 + #if(~"$!\{request.week}~" != '')
4554 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
4555 + #end
4556 +#end
4557 +##
4558 +##
4559 +##
4560 +#**
4561 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
4562 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
4563 + *
4564 + * @param monthDate The resulting month, a JODATime MutableDateTime.
4565 + *###
4566 +#macro(getRequestedMonth $monthDate)
4567 + #set ($monthDate = $NULL)
4568 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
4569 + #if(~"$!\{request.year}~" != '')
4570 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
4571 + #end
4572 + #if(~"$!\{request.month}~" != '')
4573 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
4574 + #end
4575 +#end
4576 +##
4577 +##
4578 +##
4579 +#**
4580 + * Retrieve a blog property (title, display type, etc).
4581 + *
4582 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
4583 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
4584 + * @param defaultValue The default value to use in case the blog object does not define one.
4585 + * @param propertyValue The resulting value.
4586 + *###
4587 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
4588 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
4589 + #if($result == '')
4590 + #set($result = $defaultValue)
4591 + #end
4592 + #set ($propertyValue = $NULL)
4593 + #setVariable (~"$propertyValue~" $result)
4594 +#end
4595 +
4596 +#**
4597 + * If an error occurs when executing an action, set a specific response status and display an error message.
4598 + *
4599 + * @param status The response status.
4600 + * @param text The user readable error to be displayed. Can be a translation key.
4601 + * @param parameters The parameters to use when decoding the translation key.
4602 + *###
4603 +#macro(blog__actionResponseError $status $text $parameters)
4604 + $response.setStatus($status)
4605 + #if($request.ajax)
4606 + $services.localization.render($text, $!parameters)
4607 + #else
4608 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
4609 + #end
4610 +#end
4611 +##
4612 +##
4613 +##
4614 +#**
4615 + * Check if a blog is the Default blog (The one in the 'Blog' space).
4616 + *
4617 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
4618 + * @param isDefault The resulting boolean.
4619 + *###
4620 +#macro(isDefaultBlog $blogDoc $isDefault)
4621 + #set ($result = false)
4622 + #if ($blogDoc.space == 'Blog')
4623 + #set ($result = true)
4624 + #end
4625 + #setVariable(~"$isDefault~" $result)
4626 +#end
4627 +##
4628 +##
4629 +##
4630 +#**
4631 + * Retrieve the blog posts location (space).
4632 + *
4633 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
4634 + * @param postsLocation The resulting location.
4635 + *###
4636 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
4637 + #getBlogDocument($blogSpace $blogDoc)
4638 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
4639 + #set ($postsLocation = $NULL)
4640 + #setVariable (~"$postsLocation~" $result)
4641 +#end
4642 +##
4643 +##
4644 +##
4645 +#**
4646 + * Retrieve the blog categories location (space).
4647 + *
4648 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
4649 + * @param categoriesLocation The resulting location.
4650 + *###
4651 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
4652 + #getBlogDocument($blogSpace $blogDoc)
4653 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
4654 + #set ($postsLocation = $NULL)
4655 + #setVariable (~"$categoriesLocation~" $result)
4656 +#end
4657 +###**
4658 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
4659 + * for example there is 4 different panel contexts:
4660 + * aBlog.aPost or aBlog.WebHome
4661 + * aCategorySpace.aCategory
4662 + * aCategorySpace.WebHome
4663 + * Blog.aPost or Blog.WebHome
4664 + *
4665 + * @param query The query for selecting blog entries.
4666 + * @param queryParams The parameters to bind with the generated query.
4667 + * @param targetDoc The document in which the articles will be displayed.
4668 + *###
4669 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
4670 + #set ($query = $NULL)
4671 + #set ($queryParams = $NULL)
4672 + #getCategoryAllBlogPostsQuery($resultQuery)
4673 + #set ($resultQueryParams = \{})
4674 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
4675 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
4676 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
4677 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
4678 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
4679 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
4680 + #elseif($targetDoc.getObject($blogCategoryClassname))
4681 + ## Get all posts that are in a category aCategorySpace.aCategory
4682 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
4683 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
4684 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
4685 + ## Get all posts that are in a category aCategorySpace.%
4686 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
4687 + ## Exclude incategorized posts
4688 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
4689 + #if ($targetDoc.space == $defaultBlogSpace)
4690 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
4691 + #end
4692 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
4693 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
4694 + #else
4695 + ## Get all posts in blog space aBlog
4696 + #getAllBlogPostsQuery($resultQuery)
4697 + #getBlogPostsLocation($targetDoc.space $postsLocation)
4698 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
4699 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
4700 + #end
4701 + #setVariable(~"$query~" $resultQuery)
4702 + #setVariable(~"$queryParams~" $resultQueryParams)
4703 +#end
4704 +##
4705 +##
4706 +##
4707 +###**
4708 + * Display blog posts based on the context where the posts are displayed.
4709 + * for example there is 4 different panel contexts:
4710 + * aBlog.aPost or aBlog.WebHome
4711 + * aCategorySpace.aCategory
4712 + * aCategorySpace.WebHome
4713 + * Blog.aPost or Blog.WebHome
4714 + *
4715 + * @param targetDoc The document in which the articles will be displayed.
4716 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
4717 + * @param layout Layout of the the posts to display
4718 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
4719 + * @param limit the number of posts to display
4720 + *###
4721 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
4722 + #if ($postLayout == 'full')
4723 + #set ($macro.paginated = 'yes')
4724 + #end
4725 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
4726 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
4727 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
4728 + #if (~"$!layout~" == '')
4729 + #set ($layout = $postsLayout)
4730 + #end
4731 + #if ($postsVisiblity == 'recent')
4732 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
4733 + #elseif($postsVisiblity == 'unpublished')
4734 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
4735 + #end
4736 + #elseif($targetDoc.getObject($blogCategoryClassname))
4737 + ## Display all posts that are in a category aCategorySpace.aCategory
4738 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
4739 + #getBlogPostsLayout($blogDoc $postsLayout)
4740 + #if (~"$!layout~" == '')
4741 + #set ($layout = $postsLayout)
4742 + #end
4743 + #if ($postsVisiblity == 'recent')
4744 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
4745 + #elseif($postsVisiblity == 'unpublished')
4746 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
4747 + #end
4748 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
4749 + ## Display all posts that are in a category aCategorySpace.%
4750 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
4751 + #getBlogPostsLayout($blogDoc $postsLayout)
4752 + #if (~"$!layout~" == '')
4753 + #set ($layout = $postsLayout)
4754 + #end
4755 + #if ($postsVisiblity == 'recent')
4756 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
4757 + #elseif($postsVisiblity == 'unpublished')
4758 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
4759 + #end
4760 + #else
4761 + ## Display all posts in blog space aBlog
4762 + #getBlogDocument($targetDoc.space $blogDoc)
4763 + #getBlogPostsLayout($blogDoc $postsLayout)
4764 + #if (~"$!layout~" == '')
4765 + #set ($layout = $postsLayout)
4766 + #end
4767 + #if ($postsVisiblity == 'recent')
4768 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
4769 + #elseif($postsVisiblity == 'unpublished')
4770 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
4771 + #end
4772 + #end
4773 +#end
4774 +##
4775 +##
4776 +##
4777 +#**
4778 + * Bind parameters to a query object.
4779 + *
4780 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
4781 + * @param queryParams the query parameters.
4782 + *###
4783 +#macro(bindQueryParameters $queryObj $queryParams)
4784 + #set ($output = $queryObj)
4785 + #foreach( $key in $queryParams.keySet() )
4786 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
4787 + #end
4788 + #setVariable(~"$queryObj~" $output)
4789 +#end
4790 +##
4791 +##
4792 +##
4793 +#**
4794 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
4795 + *
4796 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
4797 + * property set.
4798 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
4799 + *###
4800 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
4801 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
4802 + #set ($postsLayout = $NULL)
4803 + #setVariable (~"$postsLayout~" $res)
4804 +#end
4805 +##
4806 +##
4807 +##
4808 +#**
4809 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
4810 + *
4811 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
4812 + * @param blogDoc The resulting XDocument.
4813 + *###
4814 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
4815 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
4816 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
4817 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
4818 + #else
4819 + ## Fallback to Blog.WebHome, the default blog
4820 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
4821 + #end
4822 + #set ($blogDoc = $NULL)
4823 + #setVariable (~"$blogDoc~" $macro.result)
4824 +#end" %)
4825 +(((
4826 +(% class="macro-placeholder hidden" %)
4827 +(((
4828 +macro:velocity
4829 +)))
4830 +)))
4831 +)))
4832 +
4833 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
4834 +(((
4835 +(% class="macro-placeholder hidden" %)
4836 +(((
4837 +macro:include
4838 +)))
4839 +
4840 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
4841 + * Extract the layout parameters from a string.
4842 + *
4843 + * @param layoutParamsString The string representation of the layout parameters.
4844 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
4845 + * @param layoutsParameters The resulting layout parameters Map.
4846 + *###
4847 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
4848 + #set ($layoutsParameters = $NULL)
4849 + #set ($macro.layoutParams = \{})
4850 + #if (~"$!layoutParamsString~" != '')
4851 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
4852 + #foreach ($item in $macro.paramsArr)
4853 + #set ($itemSplit = $item.split('='))
4854 + #if ($itemSplit.size() == 2)
4855 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
4856 + #end
4857 + #end
4858 + #end
4859 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
4860 +#end" %)
4861 +(((
4862 +(% class="macro-placeholder hidden" %)
4863 +(((
4864 +macro:velocity
4865 +)))
4866 +)))
4867 +)))
4868 +
4869 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
4870 + #initLayoutVars($pDoc $pObj)
4871 + <div class=~"col-xs-12 col-sm-6 next_blog~">
4872 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
4873 + <div class=~"row~">
4874 + <div class=~"col-xs-4~">
4875 + #if ($imageAtt)
4876 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
4877 + #end
4878 + </div>
4879 + <div class=~"col-xs-8 art_det~">
4880 + <p class=~"text-left~">
4881 + #if($displayTitle)$!postTitle #end
4882 + <br/><span class=~"date_info~"> $!dateStr </span>
4883 + </p>
4884 + #displayPostDetails($pDoc)
4885 + </div>
4886 + </div>
4887 + </a>
4888 + </div>
4889 + #end
4890 + ##
4891 + ##
4892 + ##
4893 + #macro(displayPinnedPost $pDoc $pObj)
4894 + #initLayoutVars($pDoc $pObj)
4895 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
4896 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
4897 + <div class=~"thumbnail~">
4898 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
4899 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
4900 + #end
4901 + #if ($imageAtt)
4902 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
4903 + #end
4904 + <div class=~"caption~">
4905 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
4906 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
4907 + #end
4908 + #if ($displaySummaryOnPinnedPosts)
4909 + <div class=~"text-left post-summary~">
4910 + #set ($postContent = $pObj.getProperty('extract').value)
4911 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
4912 + </div>
4913 + #end
4914 + #displayPostDetails($pDoc)
4915 + </div>
4916 + </div>
4917 + </a>
4918 + </div>
4919 + #end
4920 + ##
4921 + ##
4922 + ##
4923 + #macro(formatPostDate $pDoc $pObj)
4924 + #set ($formattedDate = $NULL)
4925 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
4926 + #if (~"$!dateStr~" != '')
4927 + #set ($dateArr = $dateStr.split(' '))
4928 + #if ($dateArr.size() > 3)
4929 + #set ($dateStr = ~"~")
4930 + #foreach($s in $dateArr.subList(0, 3))
4931 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
4932 + #end
4933 + #end
4934 + #end
4935 + #setVariable(~"$formattedDate~" $dateStr)
4936 + #end
4937 + ##
4938 + ##
4939 + ##
4940 + #macro(displayPostDetails $pDoc)
4941 + <div class=~"row post-details~">
4942 + <div class=~"col-xs-8 detail~">
4943 + #if ($services.like.displayButton($pDoc.documentReference))
4944 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
4945 + ## Retrieve the likes number in XWiki 12.9+
4946 + #set ($likeNumber = $optLikeRecord.get())
4947 + #if (!$stringtool.isNumeric($likeNumber.toString()))
4948 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
4949 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
4950 + #end
4951 + #if ($stringtool.isNumeric($likeNumber.toString()))
4952 + <div class=~"post-likes btn btn-default disabled badge~"
4953 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
4954 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
4955 + </div>
4956 + #end
4957 + #elseif ($services.ratings)
4958 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
4959 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
4960 + <ul class=~"pull-left note list-inline~">
4961 + #foreach ($x in [1..5])
4962 + #set ($cls = ~"~")
4963 + #if ($x > $averageVote)
4964 + #set ($cls = ~"-o~")
4965 + #end
4966 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
4967 + #end
4968 + </ul>
4969 + #end
4970 + #end
4971 + </div>
4972 + #if ($showPostComments)
4973 + <div class=~"col-xs-4 com_det~">
4974 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
4975 + </div>
4976 + #end
4977 + </div>
4978 + #end
4979 + ##
4980 + ##
4981 + ##
4982 + #macro(initLayoutVars $pDoc $pObj)
4983 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
4984 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
4985 + #isPublished($pObj $isPublished)
4986 + #isHidden($pObj $isHidden)
4987 + #getEntryDate($pDoc $pObj $postDate)
4988 + #formatPostDate($postDate $dateStr)
4989 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
4990 + #set ($nbComments = $pDoc.getComments().size())
4991 + #set ($showPostComments = true)
4992 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
4993 + #set ($showPostComments = false)
4994 + #end
4995 + #end
4996 + ##
4997 + ##
4998 + ##
4999 + #macro(displayEditPinnedPostsButton)
5000 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
5001 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
5002 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
5003 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
5004 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
5005 + <div class=~"edit-pinned-posts-container~">
5006 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
5007 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
5008 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
5009 + </a>
5010 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
5011 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
5012 + </div>
5013 + </div>
5014 + #if (~"$!pinnedPostsObj~" == '')
5015 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
5016 + #end
5017 + #end
5018 + #end" %)
5019 +(((
5020 +(% class="macro-placeholder hidden" %)
5021 +(((
5022 +macro:velocity
5023 +)))
5024 +)))
5025 +
5026 +(% data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
5027 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
5028 + #getEntryObject($postDoc $postObj)
5029 + #if (~"$!postObj~" != '')
5030 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
5031 + ##
5032 + #set ($displayTitle = true)
5033 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
5034 + #set ($displayTitle = false)
5035 + #end
5036 + ##
5037 + #set ($displayTitleFirstOnPinnedPosts = false)
5038 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
5039 + #set ($displayTitleFirstOnPinnedPosts = true)
5040 + #end
5041 + ##
5042 + #set ($displaySummaryOnPinnedPosts = true)
5043 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
5044 + #set ($displaySummaryOnPinnedPosts = false)
5045 + #end
5046 + ##
5047 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
5048 + #if ($postIndex == 0)
5049 + #set ($stopBlogPostsDisplay = false)
5050 + #end
5051 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
5052 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
5053 + #set($scaleWidth = 600)
5054 + #set($imgQs=~"width=$scaleWidth~")
5055 + ## Display pinned posts
5056 + ## Get the list of pinned posts
5057 + #set ($pinnedPosts = [])
5058 + #set ($pinnedPostsSourceDoc = $NULL)
5059 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
5060 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
5061 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
5062 + #end
5063 + #if (~"$!pinnedPostsSourceDoc~" != '')
5064 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
5065 + #if (~"$!pinnedPostsObj~" != '')
5066 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
5067 + #if (~"$!orderedPinnedPostsJSON~" != '')
5068 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
5069 + #else
5070 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
5071 + #end
5072 + #end
5073 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
5074 + \{\{html clean=~"false~"}}
5075 + #set ($x = 0)
5076 + #set ($showPinnedPostsButton = true)
5077 + #foreach ($pinnedPost in $pinnedPosts)
5078 + #if ($x == 0)
5079 + <div class=~"row flex-container~">
5080 + #if ($showPinnedPostsButton)
5081 + #displayEditPinnedPostsButton()
5082 + #set($showPinnedPostsButton = false)
5083 + #end
5084 + #end
5085 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
5086 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
5087 + #if (~"$!pinnedPostObj~" != '')
5088 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
5089 + #end
5090 + #set ($x = $mathtool.add($x, 1))
5091 + #if ($x == 3)
5092 + #set ($x = 0)
5093 + </div>
5094 + #end
5095 + #end
5096 + #if ($mathtool.mod($x, 3) != 0)
5097 + </div>
5098 + #end
5099 + \{\{/html}}
5100 +
5101 + ## If the first post is a pinned post : this means that all the posts are pinned
5102 + ## In this case, avoid displaying the posts again after the pinned posts section.
5103 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
5104 + #set ($stopBlogPostsDisplay = true)
5105 + #end
5106 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
5107 +
5108 + \{\{html}}
5109 + <div class=~"row no-pinnded-posts~">
5110 + #displayEditPinnedPostsButton()
5111 + </div>
5112 + \{\{/html}}
5113 +
5114 + #end
5115 + #end
5116 + #if (!$stopBlogPostsDisplay)
5117 + \{\{html clean=~"false~"}}
5118 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
5119 + #set ($nbDisplayedPosts = 0)
5120 + #end
5121 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
5122 + #if ($nbDisplayedPosts != 0)
5123 + </div>
5124 + #set ($lastHtmlTag = 'c')
5125 + #end
5126 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
5127 + <div class=~"row~">
5128 + #set ($lastHtmlTag = 'o')
5129 + #set ($lastRowClass = ~"~")
5130 + #else
5131 + <div class=~"row flex-container~">
5132 + #set ($lastHtmlTag = 'o')
5133 + #set ($lastRowClass = ~"flex~")
5134 + #end
5135 + #end
5136 + #displaySmallPost($postDoc $postObj)
5137 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
5138 + </div>
5139 + #set ($lastHtmlTag = 'c')
5140 + #end
5141 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
5142 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
5143 + #if (~"$!lastHtmlTag~" == 'o')
5144 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
5145 + <div class=~"col-xs-12 col-sm-6~"></div>
5146 + #end
5147 + </div>
5148 + #end
5149 + #end
5150 + \{\{/html}}
5151 + #end
5152 + #else
5153 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
5154 + #end
5155 + #else
5156 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
5157 + #end" class="macro hidden macro-placeholder" %)macro:velocity(% data-macro="startmacro:html|-|clean=~"false~"|-|</div>
5158 +<div class=~"row flex-container~">
5159 +<div class=~"col-xs-12 col-sm-6 next_blog~">
5160 +<a href=~"/Nieuws/Nieuwsbrief%20december%202023~" class=~"thumbnail~">
5161 +<div class=~"row~">
5162 +<div class=~"col-xs-4~">
5163 +<img src=~"/download/Nieuws/Nieuwsbrief%20december%202023/snow-cold-winter-white-sweet-weather-1363025-pxhere.com.jpg?width=600&rev=1.1~" />
5164 +</div>
5165 +<div class=~"col-xs-8 art_det~">
5166 +<p class=~"text-left~">
5167 +Nieuwsbrief december 2023 <br/><span class=~"date_info~"> Jan 10, 2024, </span>
5168 +</p>
5169 +<div class=~"row post-details~">
5170 +<div class=~"col-xs-8 detail~">
5171 +<div class=~"post-likes btn btn-default disabled badge~"
5172 +title=~"Number of likes on this page: 1~">
5173 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">1</span>
5174 +</div>
5175 +</div>
5176 +<div class=~"col-xs-4 com_det~">
5177 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
5178 +</div>
5179 +</div>
5180 +</div>
5181 +</div>
5182 +</a>
5183 +</div>" class="macro macro hidden macro-placeholder" %)macro:html
5184 +)))
5185 +)))
5186 +
5187 +(% class="row flex-container" %)
5188 +(((
5189 +(% class="col-xs-12 col-sm-6 next_blog" %)
5190 +(((
5191 +(% class="row" %)
5192 +(((
5193 +(% class="col-xs-4" %)
5194 +(((
5195 +[[~[~[image:/download/Nieuws/Nieuwsbrief%20december%202023/snow-cold-winter-white-sweet-weather-1363025-pxhere.com.jpg?width=600&rev=1.1~]~]>>path:/Nieuws/Nieuwsbrief%20december%202023||class="thumbnail"]]
5196 +)))
5197 +
5198 +(% class="col-xs-8 art_det" %)
5199 +(((
5200 +(% class="text-left" %)
5201 +[[Nieuwsbrief december 2023
5202 +(% class="date_info" %) Jan 10, 2024,>>path:/Nieuws/Nieuwsbrief%20december%202023||class="thumbnail"]]
5203 +
5204 +(% class="row post-details" %)
5205 +(((
5206 +(% class="col-xs-8 detail" %)
5207 +(((
5208 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 1" %)
5209 +(((
5210 +[[(% class="like-number" %)1>>path:/Nieuws/Nieuwsbrief%20december%202023||class="thumbnail"]]
5211 +)))
5212 +)))
5213 +
5214 +(% class="col-xs-4 com_det" %)
5215 +(((
5216 +(% class="text-right" %)
5217 +[[(0)>>path:/Nieuws/Nieuwsbrief%20december%202023||class="thumbnail"]]
5218 +)))
5219 +)))
5220 +)))
5221 +)))
5222 +)))
5223 +
5224 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Nieuwsbrief november 2023~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG|postIndex=3|previousPostReference=Nieuws.Nieuwsbrief december 2023~"" %)
5225 +(((
5226 +(% class="macro-placeholder hidden" %)
5227 +(((
5228 +macro:blogPostLayoutCards
5229 +)))
5230 +
5231 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
5232 +(((
5233 +(% class="macro-placeholder hidden" %)
5234 +(((
5235 +macro:include
5236 +)))
5237 +
5238 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
5239 +(((
5240 +(% class="macro-placeholder hidden" %)
5241 +(((
5242 +macro:include
5243 +)))
5244 +
5245 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
5246 +#set($blogClassname = 'Blog.BlogClass')
5247 +#set($blogTemplate = 'Blog.BlogTemplate')
5248 +#set($blogSheet = 'Blog.BlogSheet')
5249 +## Blog entries
5250 +#set($blogPostClassname = 'Blog.BlogPostClass')
5251 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
5252 +#set($blogPostSheet = 'Blog.BlogPostSheet')
5253 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
5254 +#set($oldArticleClassname = 'XWiki.ArticleClass')
5255 +## Categories
5256 +#set($blogCategoryClassname = 'Blog.CategoryClass')
5257 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
5258 +#set($blogCategorySheet = 'Blog.CategorySheet')
5259 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
5260 +#set($oldBlogCategoryClassname = 'Blog.Categories')
5261 +#set($defaultCategoryParent = 'Blog.Categories')
5262 +## Style
5263 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
5264 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
5265 +## Clientside scripts
5266 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
5267 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
5268 +## Misc
5269 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
5270 +#set($isBlogPost = $doc.getObject($blogPostClassname))
5271 +#set($defaultBlogSpace = 'Blog')
5272 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
5273 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
5274 +##
5275 +##
5276 +##
5277 +#**
5278 + * Displays an image, taken from the blog style document.
5279 + *
5280 + * @param $imgName The name of the icon from icons set to use.
5281 + *#
5282 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
5283 +(((
5284 +(% class="macro-placeholder hidden" %)
5285 +(((
5286 +macro:velocity
5287 +)))
5288 +)))
5289 +)))
5290 +
5291 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
5292 +##
5293 +##
5294 +## Import the blog skin and javascripts.
5295 +$!xwiki.ssx.use($blogStyleDocumentName)##
5296 +$!xwiki.jsx.use($blogScriptsDocumentName)##
5297 +##
5298 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
5299 +#template('hierarchy_macros.vm')##
5300 +##
5301 +##
5302 +#**
5303 + * Prints a blog. This is the main macro used in the BlogSheet.
5304 + *
5305 + * @param blogDoc the XDocument holding the blog definition object.
5306 + *###
5307 +#macro(printBlog $blogDoc)
5308 + \{\{include reference='Blog.CreatePost'/}}
5309 +
5310 + ## Use the blogPostList macro to display the blogposts
5311 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
5312 + ## do not support FTM the monthly and weekly blog display types
5313 + #getBlogDisplayType($blogDoc $displayType)
5314 + #if ($displayType == 'weekly' || $displayType == 'monthly')
5315 + #getBlogEntries($blogDoc $entries)
5316 + #displayBlog($entries 'index' true true)
5317 + #displayNavigationLinks($blogDoc)
5318 + #else
5319 + #getBlogDisplayType($blogDoc $displayType)
5320 + #set ($paginated = 'no')
5321 + #if ($displayType == 'paginated')
5322 + #set ($paginated = 'yes')
5323 + #end
5324 + #getBlogPostsLayout($blogDoc $postsLayout)
5325 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
5326 + #end
5327 +#end
5328 +##
5329 +##
5330 +##
5331 +#**
5332 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
5333 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
5334 + * all entries).
5335 + *
5336 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
5337 + *###
5338 +#macro(showBlogInfo $blogDoc)
5339 + #if($blogDoc.getObject($blogClassname))
5340 + ## Keep testing for inline action for backward compatibility with older blogs.
5341 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
5342 + #macro(displayProperty $blogDoc $propname)
5343 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
5344 + : $blogDoc.display($propname)
5345 + #end
5346 + #displayProperty($blogDoc 'title')
5347 + #displayProperty($blogDoc 'description')
5348 + #displayProperty($blogDoc 'displayType')
5349 + #displayProperty($blogDoc 'itemsPerPage')
5350 + #displayProperty($blogDoc 'postsLayout')
5351 + #displayProperty($blogDoc 'postsLayoutParameters')
5352 + #else
5353 + $blogDoc.display('description')
5354 + #end
5355 + #elseif($doc.fullName == $blogSheet)
5356 += $services.localization.render('blog.code.blogsheet') =
5357 + \{\{translation key='blog.code.sheetexplanation'/}}
5358 + #else
5359 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
5360 + #end
5361 +#end
5362 +##
5363 +##
5364 +##
5365 +#**
5366 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
5367 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
5368 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
5369 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
5370 + *
5371 + * @param space A <tt>String</tt>, the name of the space where to search.
5372 + * @param blogDoc The resulting XDocument.
5373 + *###
5374 +#macro(getBlogDocument $space $blogDoc)
5375 + #set ($result = $NULL)
5376 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
5377 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
5378 + ## identify the right blog based on a configuration object in a WebPreferences page.
5379 + #set ($spaceReference = $services.model.resolveSpace($space))
5380 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
5381 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
5382 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
5383 + #if ($preferencesObj)
5384 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
5385 + #end
5386 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
5387 + #if (~"$!result~" == '')
5388 + ## First, try the Space.WebHome, for a whole-space blog
5389 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
5390 + #if(!$result.getObject($blogClassname))
5391 + ## Second, try the Space.Blog document
5392 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
5393 + #if(!$result.getObject($blogClassname))
5394 + ## Third, try searching for a blog document in the current space
5395 + ## Prevent the query fail when the space contains dots '.'
5396 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
5397 + #if($blogDocs.size() > 0)
5398 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
5399 + #else
5400 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
5401 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
5402 + #if($blogDocs.size() > 0)
5403 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
5404 + #else
5405 + ## Last, fallback to Blog.WebHome, the default blog
5406 + #set($result = $xwiki.getDocument('Blog.WebHome'))
5407 + #end
5408 + #end
5409 + #end
5410 + #end
5411 + #end
5412 + #set ($blogDoc = $NULL)
5413 + #setVariable (~"$blogDoc~" $result)
5414 +#end
5415 +##
5416 +##
5417 +##
5418 +#**
5419 + * Retrieve the blog title.
5420 + *
5421 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
5422 + * @param title The resulting title.
5423 + *###
5424 +#macro(getBlogTitle $blogDoc $title)
5425 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
5426 + #set ($title = $NULL)
5427 + #setVariable (~"$title~" $!blogDoc.displayTitle)
5428 +#end
5429 +##
5430 +##
5431 +##
5432 +#**
5433 + * Retrieve the blog description.
5434 + *
5435 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
5436 + * property set.
5437 + * @param description The resulting description.
5438 + *###
5439 +#macro(getBlogDescription $blogDoc $description)
5440 + #getBlogProperty($blogDoc 'description' '' $result)
5441 + #set ($description = $NULL)
5442 + #setVariable (~"$description~" $result)
5443 +#end
5444 +##
5445 +##
5446 +##
5447 +#**
5448 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
5449 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
5450 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
5451 + * month), or all.
5452 + *
5453 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
5454 + * @param entries The resulting list of entries to display, a list of XDocument names.
5455 + *###
5456 +#macro(getBlogEntries $blogDoc $entries)
5457 + #if (!$entries)
5458 + #setVariable (~"$entries~" [])
5459 + #end
5460 + #getAllBlogPostsQuery($query)
5461 + #isDefaultBlog($blogDoc $isDefault)
5462 + #set($queryParams = \{})
5463 + #if ($isDefault)
5464 + #getCategoryAllBlogPostsQuery($query)
5465 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
5466 + #set($discard = $queryParams.put('creator', $xcontext.user))
5467 + #set($discard = $queryParams.put('space', $blogDoc.space))
5468 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
5469 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
5470 + #else
5471 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
5472 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
5473 + #set($discard = $queryParams.put('space', $blogPostsLocation))
5474 + #set($discard = $queryParams.put('parent', $blogDoc.space))
5475 + #end
5476 + #getBlogDisplayType($blogDoc $displayType)
5477 + #if($displayType == 'weekly')
5478 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
5479 + #elseif($displayType == 'monthly')
5480 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
5481 + #elseif($displayType == 'all')
5482 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
5483 + #else
5484 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
5485 + #end
5486 +#end
5487 +##
5488 +##
5489 +##
5490 +#**
5491 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
5492 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
5493 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
5494 + * (10 if not defined).
5495 + *
5496 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
5497 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
5498 + * refined to restrict to a given space, or to a given search criteria, etc.
5499 + * @param entries The resulting list of entries to display, a list of XDocument names.
5500 + * @param queryParams The parameters to bind with the query.
5501 + *###
5502 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
5503 + #if (!$entries)
5504 + #setVariable (~"$entries~" [])
5505 + #end
5506 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
5507 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
5508 + #bindQueryParameters($countQueryObj $queryParams)
5509 + #bindQueryParameters($queryObj $queryParams)
5510 + #set($totalEntries = $countQueryObj.count())
5511 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
5512 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
5513 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
5514 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
5515 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
5516 +#end
5517 +##
5518 +##
5519 +##
5520 +#**
5521 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
5522 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
5523 + * digit year). Initially the current week is displayed.
5524 + *
5525 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
5526 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
5527 + * refined to restrict to a given space, or to a given search criteria, etc.
5528 + * @param entries The resulting list of entries to display, a list of XDocument names.
5529 + * @param queryParams The parameters to bind with the query.
5530 + *###
5531 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
5532 + #if (!$entries)
5533 + #setVariable (~"$entries~" [])
5534 + #end
5535 + #getRequestedWeek($weekDate)
5536 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
5537 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
5538 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
5539 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
5540 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
5541 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
5542 + #bindQueryParameters($countQueryObj $queryParams)
5543 + #bindQueryParameters($queryObj $queryParams)
5544 + #set($totalEntries = $countQueryObj.count())
5545 + #set($discard = $entries.addAll($queryObj.execute()))
5546 +#end
5547 +##
5548 +##
5549 +##
5550 +#**
5551 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
5552 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
5553 + * digit year). Initially the current month is displayed.
5554 + *
5555 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
5556 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
5557 + * refined to restrict to a given space, or to a given search criteria, etc.
5558 + * @param entries The resulting list of entries to display, a list of XDocument names.
5559 + * @param queryParams The parameters to bind with the query.
5560 + *###
5561 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
5562 + #if (!$entries)
5563 + #setVariable (~"$entries~" [])
5564 + #end
5565 + #getRequestedMonth($monthDate)
5566 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
5567 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
5568 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
5569 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
5570 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
5571 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
5572 + #bindQueryParameters($countQueryObj $queryParams)
5573 + #bindQueryParameters($queryObj $queryParams)
5574 + #set($totalEntries = $countQueryObj.count())
5575 + #set($discard = $entries.addAll($queryObj.execute()))
5576 +#end
5577 +##
5578 +##
5579 +##
5580 +#**
5581 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
5582 + *
5583 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
5584 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
5585 + * refined to restrict to a given space, or to a given search criteria, etc.
5586 + * @param entries The resulting list of entries to display, a list of XDocument names.
5587 + * @param queryParams The parameters to bind with the query.
5588 + *###
5589 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
5590 + #if (!$entries)
5591 + #setVariable (~"$entries~" [])
5592 + #end
5593 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
5594 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
5595 + #bindQueryParameters($countQueryObj $queryParams)
5596 + #bindQueryParameters($queryObj $queryParams)
5597 + #set($totalEntries = $countQueryObj.count())
5598 + #set($discard = $entries.addAll($queryObj.execute()))
5599 +#end
5600 +##
5601 +##
5602 +##
5603 +#**
5604 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
5605 + *
5606 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
5607 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
5608 + * refined to restrict to a given space, or to a given search criteria, etc.
5609 + * @param queryParams The parameters to bind with the query.
5610 + * @param entries The resulting list of entries to display, a list of XDocument names.
5611 + *###
5612 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
5613 + #if (!$entries)
5614 + #setVariable (~"$entries~" [])
5615 + #end
5616 + #set($query = ~"$\{query} and isPublished.value = 0~")
5617 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
5618 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
5619 + #bindQueryParameters($countQueryObj $queryParams)
5620 + #bindQueryParameters($queryObj $queryParams)
5621 + #set($totalEntries = $countQueryObj.count())
5622 + #set($discard = $entries.addAll($queryObj.execute()))
5623 +#end
5624 +##
5625 +##
5626 +##
5627 +#**
5628 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
5629 + *
5630 + * @param entries The resulting list of entries to display, a list of XDocument names.
5631 + *###
5632 +#macro(getGlobalBlogEntries $entries)
5633 + #if (!$entries)
5634 + #setVariable (~"$entries~" [])
5635 + #end
5636 + #getAllBlogPostsQuery($query)
5637 + #set($totalEntries = $services.query.hql($query).count())
5638 + #set($defaultItemsPerPage = 20)
5639 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
5640 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
5641 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
5642 +#end
5643 +#**
5644 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
5645 + * blog, nor specify a range or an ordering criteria.
5646 + *
5647 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
5648 + *
5649 + * @param query The basic query for selecting blog entries.
5650 + *#
5651 +#macro(getBlogEntriesBaseQuery $query)
5652 + #getAllBlogPostsQuery($query)
5653 +#end
5654 +#**
5655 + * Return the Query for selecting the all wiki blog posts without filtering
5656 + *
5657 + * @param query The basic query for selecting blog entries.
5658 + *#
5659 +#macro(getAllBlogPostsQuery $query)
5660 + #set ($query = $NULL)
5661 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
5662 + IntegerProperty hidden, DateProperty publishDate
5663 + where doc.fullName <> '$blogPostTemplate' and
5664 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
5665 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
5666 + hidden.id.id = obj.id and hidden.id.name='hidden' and
5667 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
5668 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
5669 +#end
5670 +##
5671 +##
5672 +##
5673 +###**
5674 + * Return the Query for selecting the all wiki blog posts with categories filtering
5675 + *
5676 + * @param query The basic query for selecting blog entries.
5677 + *###
5678 +#macro(getCategoryAllBlogPostsQuery $query)
5679 + #set ($query = $NULL)
5680 + #getAllBlogPostsQuery($baseQuery)
5681 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
5682 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
5683 +#end
5684 +##
5685 +##
5686 +##
5687 +#**
5688 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
5689 + * week), monthly (all entries in a month), or all.
5690 + *
5691 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
5692 + * property set.
5693 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
5694 + *###
5695 +#macro(getBlogDisplayType $blogDoc $displayType)
5696 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
5697 + #set ($displayType = $NULL)
5698 + #setVariable (~"$displayType~" $result)
5699 +#end
5700 +##
5701 +##
5702 +##
5703 +#**
5704 + * Displays a list of entries.
5705 + *
5706 + * @param entries The entries to display, a list of XDocument names.
5707 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
5708 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
5709 + * used values: index, single, category, search, unpublished, hidden.
5710 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
5711 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
5712 + * displayed alone on their page since it's the page title which is used in this case)
5713 + *###
5714 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
5715 + #set($blogDay = '')
5716 + (% class=~"hfeed $!\{displaying}~" ~%)(((
5717 + (% class=~"blogDay~" ~%)(((
5718 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
5719 + #getEntryObject($entryDoc $entryObj)
5720 + ## Although all entries should have one of the two objects, better check to be sure.
5721 + #if(~"$!\{entryObj}~" != '')
5722 + #getEntryDate($entryDoc $entryObj $entryDate)
5723 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
5724 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
5725 + #if($blogDay != $entryDateStr)
5726 + #if($blogDay != '')
5727 + )))
5728 + (% class=~"blogDay~" ~%)(((
5729 + #end
5730 + #displayBlogDate($entryDate)
5731 + #set ($blogDay = $entryDateStr)
5732 + #end
5733 + ## Finally, display the entry.
5734 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
5735 + #end
5736 + #end
5737 + )))## blogDay
5738 + )))## hfeed
5739 +#end
5740 +##
5741 +##
5742 +##
5743 +#**
5744 + * Get the entry object, either a new BlogPost or an old Article.
5745 + *
5746 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5747 + * @param entryObj The resulting xobject of the blog post.
5748 + *###
5749 +#macro(getEntryObject $entryDoc $__entryObj)
5750 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
5751 + #if(!$result)
5752 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
5753 + #end
5754 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
5755 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
5756 + ## overwritten in this case but it's less likely to have such a variable defined before.
5757 + #set ($__entryObj = $NULL)
5758 + #setVariable (~"$__entryObj~" $result)
5759 +#end
5760 +##
5761 +##
5762 +##
5763 +#**
5764 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
5765 + * the document creation date, but can be edited by the user.
5766 + *
5767 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5768 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5769 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
5770 + *###
5771 +#macro(getEntryDate $entryDoc $entryObj $result)
5772 + #set ($result = $NULL)
5773 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
5774 +#end
5775 +##
5776 +##
5777 +##
5778 +#**
5779 + * Displays a date, nicely formatted as a calendar page.
5780 + *
5781 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
5782 + *###
5783 +#macro(displayBlogDate $date)
5784 + #set($year = $xwiki.formatDate($date, 'yyyy'))
5785 + ## 3 letter month name, like Jan, Dec.
5786 + #set($month = $xwiki.formatDate($date, 'MMM'))
5787 + ## Uncomment to get a full length month name, like January, December.
5788 + ## TODO: this could be defined somewhere in the blog style.
5789 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
5790 + #set($day = $xwiki.formatDate($date, 'dd'))
5791 + (% class=~"blogdate~" ~%)
5792 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
5793 +#end
5794 +##
5795 +##
5796 +##
5797 +#**
5798 + * Displays a blog article: management tools, header, content, footer.
5799 + *
5800 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5801 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5802 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
5803 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
5804 + * when they're displayed alone on their page since it's the page title which is used in this case)
5805 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
5806 + *###
5807 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
5808 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
5809 + #isPublished($entryObj $isPublished)
5810 + #isHidden($entryObj $isHidden)
5811 + #if($doc.fullName == $entryDoc.fullName)
5812 + (% class=~"hentry single-article~" ~%)(((
5813 + #else
5814 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
5815 + #end
5816 + #if ($shouldDisplayActions)
5817 + #displayEntryTools($entryDoc $entryObj)
5818 + #end
5819 + #if($shouldDisplayTitle)
5820 + #displayEntryTitle($entryDoc $entryObj)
5821 + #end
5822 + #if($doc.fullName == $entryDoc.fullName)
5823 + #if(!$isPublished)
5824 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
5825 + #elseif($isHidden)
5826 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
5827 + #end
5828 + #end
5829 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
5830 + #displayEntryFooter($entryDoc $entryObj)
5831 + )))## hentry
5832 +#end
5833 +##
5834 +##
5835 +##
5836 +#**
5837 + * Checks if the provided blog is published or not.
5838 + *
5839 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5840 + * @param isPublished The resulting boolean, true if the entry is considered published.
5841 + *###
5842 +#macro(isPublished $entryObj $isPublished)
5843 + #set ($isPublished = $NULL)
5844 + ## This should work for both old articles, which don't have the 'published' property at all, and
5845 + ## are considered published by default, and new entries, that should have 1 if published.
5846 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
5847 + #setVariable (~"$isPublished~" true)
5848 + #else
5849 + #setVariable (~"$isPublished~" false)
5850 + #end
5851 +#end
5852 +##
5853 +##
5854 +##
5855 +#**
5856 + * Checks if the provided blog is hidden or not.
5857 + *
5858 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
5859 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
5860 + *###
5861 +#macro(isHidden $entryObj $isHidden)
5862 + #set ($isHidden = $NULL)
5863 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
5864 + ## are considered visible by default, and new entries, that should have 1 if hidden.
5865 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
5866 + #setVariable (~"$isHidden~" true)
5867 + #else
5868 + #setVariable (~"$isHidden~" false)
5869 + #end
5870 +#end
5871 +##
5872 +##
5873 +##
5874 +#**
5875 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
5876 + *
5877 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5878 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5879 + *###
5880 +#macro(displayEntryTools $entryDoc $entryObj)
5881 + #if($xcontext.action == 'view')
5882 + (% class=~"blog-entry-toolbox~" ~%)(((
5883 + #displayPublishButton($entryDoc $entryObj)
5884 + #displayHideShowButton($entryDoc $entryObj)
5885 + #displayEditButton($entryDoc $entryObj)
5886 + #displayDeleteButton($entryDoc $entryObj)
5887 + )))
5888 + #end
5889 +#end
5890 +##
5891 +##
5892 +##
5893 +#**
5894 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
5895 + *
5896 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5897 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5898 + * @todo AJAX calls.
5899 + *###
5900 +#macro(displayPublishButton $entryDoc $entryObj)
5901 + #isPublished($entryObj $isPublished)
5902 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
5903 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
5904 + #end
5905 +#end
5906 +##
5907 +##
5908 +##
5909 +#**
5910 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
5911 + *
5912 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5913 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5914 + *###
5915 +#macro(displayHideShowButton $entryDoc $entryObj)
5916 + #isPublished($entryObj $isPublished)
5917 + #isHidden($entryObj $isHidden)
5918 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
5919 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
5920 + #set ($queryString = \{
5921 + 'xredirect' : $thisURL,
5922 + 'form_token' : $services.csrf.getToken()
5923 + })
5924 + #if ($isHidden)
5925 + #set ($discard = $queryString.putAll(\{
5926 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
5927 + 'comment' : $services.localization.render('blog.code.madevisible')
5928 + }))
5929 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
5930 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
5931 + #else
5932 + #set ($discard = $queryString.putAll(\{
5933 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
5934 + 'comment' : $services.localization.render('blog.code.hid')
5935 + }))
5936 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
5937 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
5938 + #end
5939 + #end
5940 +#end
5941 +##
5942 +##
5943 +##
5944 +#**
5945 + * Displays the edit button to those that can edit the article.
5946 + *
5947 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5948 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5949 + *###
5950 +#macro(displayEditButton $entryDoc $entryObj)
5951 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
5952 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
5953 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
5954 + #end
5955 +#end
5956 +##
5957 +##
5958 +##
5959 +#**
5960 + * Displays the delete button to those that can edit the article.
5961 + *
5962 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5963 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5964 + * @todo AJAX calls.
5965 + *###
5966 +#macro(displayDeleteButton $entryDoc $entryObj)
5967 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
5968 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
5969 + #end
5970 +#end
5971 +##
5972 +##
5973 +##
5974 +#**
5975 + * Displays the title of the entry.
5976 + *
5977 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5978 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5979 + *###
5980 +#macro(displayEntryTitle $entryDoc $entryObj)
5981 + #if($doc.fullName == $entryDoc.fullName)
5982 + (% class=~"entry-title~" ~%)
5983 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
5984 + #else
5985 + (% class=~"entry-title~" ~%)
5986 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
5987 + #end
5988 +#end
5989 +##
5990 +##
5991 +##
5992 +#**
5993 + * Displays the body of the entry.
5994 + *
5995 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
5996 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
5997 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
5998 + *###
5999 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
6000 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
6001 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
6002 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
6003 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
6004 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
6005 + ))) ## entry-content
6006 + (% class=~"clearfloats~" ~%)((()))
6007 +#end
6008 +##
6009 +##
6010 +##
6011 +#**
6012 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
6013 + * of the <tt>extract</tt> field (if not empty).
6014 + *
6015 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
6016 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
6017 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
6018 + * @param entryContent The resulting content.
6019 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
6020 + * <tt>onlyExtract</tt> is <tt>true</tt>)
6021 + *###
6022 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
6023 + #if ($onlyExtract)
6024 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
6025 + ## of the content.
6026 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
6027 + #end
6028 + #if(~"$!macro.result~" == '')
6029 + #set($macro.result = $entryObj.getProperty('content').value)
6030 +#* Disabled until the content can be cleanly cut.
6031 +* #if($onlyExtract && $result.length()>$maxchars)
6032 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
6033 +* #set($i = $i + 1)
6034 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
6035 +* #end
6036 +## *###
6037 + #elseif (!$removeEllipsis)
6038 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
6039 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
6040 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
6041 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
6042 + #end
6043 + #end
6044 + #set ($entryContent = $NULL)
6045 + #setVariable (~"$entryContent~" $macro.result)
6046 +#end
6047 +##
6048 +##
6049 +##
6050 +#**
6051 + * Displays the footer of the entry.
6052 + *
6053 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
6054 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
6055 + *###
6056 +#macro(displayEntryFooter $entryDoc $entryObj)
6057 + (% class=~"entry-footer~" ~%)(((
6058 + #isPublished($entryObj $isPublished)
6059 + (% class='entry-author-label' ~%)
6060 + #if($isPublished)
6061 + \{\{translation key='blog.code.postedby'/}} ##
6062 + #else
6063 + \{\{translation key='blog.code.createdby'/}} ##
6064 + #end
6065 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
6066 + #getEntryDate($entryDoc $entryObj $entryDate)
6067 + #listCategories($entryObj) #*
6068 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
6069 + ## we assume cannot be more than 3 seconds.
6070 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
6071 + #if ($showcomments)
6072 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
6073 + #end ##
6074 + #if($entryDoc != $doc) ##
6075 + #displayEntryBlogLocation($entryDoc $entryObj) ##
6076 + #end
6077 + )))## entry-footer
6078 +#end
6079 +##
6080 +##
6081 +#**
6082 + * Display the blog for the entry (if it is not the currently displayed blog)
6083 + *
6084 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
6085 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
6086 + *###
6087 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
6088 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
6089 + #if(~"$!blogPostsLocation~" != ~"~") ##
6090 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
6091 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
6092 + #if($doc.documentReference != $blogDocRef) ##
6093 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
6094 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
6095 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
6096 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
6097 + )))(%~%)##
6098 + #end
6099 + #end
6100 + #end
6101 +#end
6102 +##
6103 +##
6104 +##
6105 +##
6106 +#**
6107 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
6108 + *
6109 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
6110 + *###
6111 +#macro(listCategories $entryObj)
6112 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
6113 + #set($categories = $entryObj.getProperty('category').value)
6114 + #set($first = true)
6115 + #if($categories.size() > 0)
6116 + #foreach($category in $categories)
6117 + #set($categoryDoc = $!xwiki.getDocument($category))
6118 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
6119 + #if($foreach.count == 1)
6120 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
6121 + #else
6122 + , ##
6123 + #end##
6124 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
6125 + #end##
6126 + #end##
6127 + #end
6128 + #end
6129 +#end
6130 +##
6131 +##
6132 +##
6133 +#**
6134 + * Displays blog pagination links (older and newer entries).
6135 + *
6136 + * @param blogDoc the XDocument holding the blog definition object.
6137 + *###
6138 +#macro(displayNavigationLinks $blogDoc)
6139 + (% class=~"clearfloats~" ~%)((()))
6140 + #getBlogDisplayType($blogDoc $displayType)
6141 + #if($displayType == 'weekly')
6142 + (% class=~"pagingLinks~" ~%)(((
6143 + #getRequestedWeek($weekDate)
6144 + $weekDate.addWeeks(-1)##
6145 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
6146 + #sep()
6147 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
6148 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
6149 + )))
6150 + #elseif($displayType == 'monthly')
6151 + (% class=~"pagingLinks~" ~%)(((
6152 + #getRequestedMonth($monthDate)
6153 + $monthDate.addMonths(-1)##
6154 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
6155 + #sep()
6156 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
6157 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
6158 + )))
6159 + #elseif($displayType == 'all')
6160 + #else
6161 + ## Paginated
6162 + #if(($totalPages > 1))
6163 + #set($queryString = '')
6164 + #foreach($p in $request.getParameterNames())
6165 + #if($p != 'page' && $p != 'ipp')
6166 + #foreach($v in $request.getParameterValues($p))
6167 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
6168 + #end
6169 + #end
6170 + #end
6171 + (% class=~"pagingLinks~" ~%)(((
6172 + #if ($currentPageNumber < $totalPages)
6173 + #set($currentPageNumber = $currentPageNumber + 1)
6174 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
6175 + #set($currentPageNumber = $currentPageNumber - 1)
6176 + #end
6177 + #if ($currentPageNumber > 1)
6178 + #if ($currentPageNumber < $totalPages)
6179 + #sep()
6180 + #end
6181 + #set($currentPageNumber = $currentPageNumber - 1)
6182 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
6183 + #set($currentPageNumber = $currentPageNumber + 1)
6184 + #end
6185 + (% class=~"clear~" ~%)(%~%)
6186 + )))## pagingLinks
6187 + #end
6188 + #end
6189 +#end
6190 +##
6191 +##
6192 +##
6193 +#**
6194 + * Displays a message box with ~"publish~" icon.
6195 + *
6196 + * @param message A text message concerning blog article publishing
6197 + *###
6198 +#macro(publishMessageBox $message)
6199 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
6200 +#end
6201 +#**
6202 + * Displays a message box with ~"show/hide~" icon.
6203 + *
6204 + * @param message A text message concerning blog article hiding
6205 + *###
6206 +#macro(hideMessageBox $message)
6207 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
6208 +#end
6209 +##
6210 +##
6211 +##
6212 +#**
6213 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
6214 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
6215 + *
6216 + * @param monthDate The resulting week, a JODATime MutableDateTime.
6217 + *###
6218 +#macro(getRequestedWeek $weekDate)
6219 + #set ($weekDate = $NULL)
6220 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
6221 + #if(~"$!\{request.year}~" != '')
6222 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
6223 + #end
6224 + #if(~"$!\{request.week}~" != '')
6225 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
6226 + #end
6227 +#end
6228 +##
6229 +##
6230 +##
6231 +#**
6232 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
6233 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
6234 + *
6235 + * @param monthDate The resulting month, a JODATime MutableDateTime.
6236 + *###
6237 +#macro(getRequestedMonth $monthDate)
6238 + #set ($monthDate = $NULL)
6239 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
6240 + #if(~"$!\{request.year}~" != '')
6241 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
6242 + #end
6243 + #if(~"$!\{request.month}~" != '')
6244 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
6245 + #end
6246 +#end
6247 +##
6248 +##
6249 +##
6250 +#**
6251 + * Retrieve a blog property (title, display type, etc).
6252 + *
6253 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
6254 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
6255 + * @param defaultValue The default value to use in case the blog object does not define one.
6256 + * @param propertyValue The resulting value.
6257 + *###
6258 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
6259 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
6260 + #if($result == '')
6261 + #set($result = $defaultValue)
6262 + #end
6263 + #set ($propertyValue = $NULL)
6264 + #setVariable (~"$propertyValue~" $result)
6265 +#end
6266 +
6267 +#**
6268 + * If an error occurs when executing an action, set a specific response status and display an error message.
6269 + *
6270 + * @param status The response status.
6271 + * @param text The user readable error to be displayed. Can be a translation key.
6272 + * @param parameters The parameters to use when decoding the translation key.
6273 + *###
6274 +#macro(blog__actionResponseError $status $text $parameters)
6275 + $response.setStatus($status)
6276 + #if($request.ajax)
6277 + $services.localization.render($text, $!parameters)
6278 + #else
6279 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
6280 + #end
6281 +#end
6282 +##
6283 +##
6284 +##
6285 +#**
6286 + * Check if a blog is the Default blog (The one in the 'Blog' space).
6287 + *
6288 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
6289 + * @param isDefault The resulting boolean.
6290 + *###
6291 +#macro(isDefaultBlog $blogDoc $isDefault)
6292 + #set ($result = false)
6293 + #if ($blogDoc.space == 'Blog')
6294 + #set ($result = true)
6295 + #end
6296 + #setVariable(~"$isDefault~" $result)
6297 +#end
6298 +##
6299 +##
6300 +##
6301 +#**
6302 + * Retrieve the blog posts location (space).
6303 + *
6304 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
6305 + * @param postsLocation The resulting location.
6306 + *###
6307 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
6308 + #getBlogDocument($blogSpace $blogDoc)
6309 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
6310 + #set ($postsLocation = $NULL)
6311 + #setVariable (~"$postsLocation~" $result)
6312 +#end
6313 +##
6314 +##
6315 +##
6316 +#**
6317 + * Retrieve the blog categories location (space).
6318 + *
6319 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
6320 + * @param categoriesLocation The resulting location.
6321 + *###
6322 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
6323 + #getBlogDocument($blogSpace $blogDoc)
6324 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
6325 + #set ($postsLocation = $NULL)
6326 + #setVariable (~"$categoriesLocation~" $result)
6327 +#end
6328 +###**
6329 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
6330 + * for example there is 4 different panel contexts:
6331 + * aBlog.aPost or aBlog.WebHome
6332 + * aCategorySpace.aCategory
6333 + * aCategorySpace.WebHome
6334 + * Blog.aPost or Blog.WebHome
6335 + *
6336 + * @param query The query for selecting blog entries.
6337 + * @param queryParams The parameters to bind with the generated query.
6338 + * @param targetDoc The document in which the articles will be displayed.
6339 + *###
6340 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
6341 + #set ($query = $NULL)
6342 + #set ($queryParams = $NULL)
6343 + #getCategoryAllBlogPostsQuery($resultQuery)
6344 + #set ($resultQueryParams = \{})
6345 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
6346 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
6347 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
6348 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
6349 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
6350 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
6351 + #elseif($targetDoc.getObject($blogCategoryClassname))
6352 + ## Get all posts that are in a category aCategorySpace.aCategory
6353 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
6354 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
6355 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
6356 + ## Get all posts that are in a category aCategorySpace.%
6357 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
6358 + ## Exclude incategorized posts
6359 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
6360 + #if ($targetDoc.space == $defaultBlogSpace)
6361 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
6362 + #end
6363 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
6364 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
6365 + #else
6366 + ## Get all posts in blog space aBlog
6367 + #getAllBlogPostsQuery($resultQuery)
6368 + #getBlogPostsLocation($targetDoc.space $postsLocation)
6369 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
6370 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
6371 + #end
6372 + #setVariable(~"$query~" $resultQuery)
6373 + #setVariable(~"$queryParams~" $resultQueryParams)
6374 +#end
6375 +##
6376 +##
6377 +##
6378 +###**
6379 + * Display blog posts based on the context where the posts are displayed.
6380 + * for example there is 4 different panel contexts:
6381 + * aBlog.aPost or aBlog.WebHome
6382 + * aCategorySpace.aCategory
6383 + * aCategorySpace.WebHome
6384 + * Blog.aPost or Blog.WebHome
6385 + *
6386 + * @param targetDoc The document in which the articles will be displayed.
6387 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
6388 + * @param layout Layout of the the posts to display
6389 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
6390 + * @param limit the number of posts to display
6391 + *###
6392 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
6393 + #if ($postLayout == 'full')
6394 + #set ($macro.paginated = 'yes')
6395 + #end
6396 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
6397 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
6398 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
6399 + #if (~"$!layout~" == '')
6400 + #set ($layout = $postsLayout)
6401 + #end
6402 + #if ($postsVisiblity == 'recent')
6403 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
6404 + #elseif($postsVisiblity == 'unpublished')
6405 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
6406 + #end
6407 + #elseif($targetDoc.getObject($blogCategoryClassname))
6408 + ## Display all posts that are in a category aCategorySpace.aCategory
6409 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
6410 + #getBlogPostsLayout($blogDoc $postsLayout)
6411 + #if (~"$!layout~" == '')
6412 + #set ($layout = $postsLayout)
6413 + #end
6414 + #if ($postsVisiblity == 'recent')
6415 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
6416 + #elseif($postsVisiblity == 'unpublished')
6417 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
6418 + #end
6419 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
6420 + ## Display all posts that are in a category aCategorySpace.%
6421 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
6422 + #getBlogPostsLayout($blogDoc $postsLayout)
6423 + #if (~"$!layout~" == '')
6424 + #set ($layout = $postsLayout)
6425 + #end
6426 + #if ($postsVisiblity == 'recent')
6427 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
6428 + #elseif($postsVisiblity == 'unpublished')
6429 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
6430 + #end
6431 + #else
6432 + ## Display all posts in blog space aBlog
6433 + #getBlogDocument($targetDoc.space $blogDoc)
6434 + #getBlogPostsLayout($blogDoc $postsLayout)
6435 + #if (~"$!layout~" == '')
6436 + #set ($layout = $postsLayout)
6437 + #end
6438 + #if ($postsVisiblity == 'recent')
6439 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
6440 + #elseif($postsVisiblity == 'unpublished')
6441 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
6442 + #end
6443 + #end
6444 +#end
6445 +##
6446 +##
6447 +##
6448 +#**
6449 + * Bind parameters to a query object.
6450 + *
6451 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
6452 + * @param queryParams the query parameters.
6453 + *###
6454 +#macro(bindQueryParameters $queryObj $queryParams)
6455 + #set ($output = $queryObj)
6456 + #foreach( $key in $queryParams.keySet() )
6457 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
6458 + #end
6459 + #setVariable(~"$queryObj~" $output)
6460 +#end
6461 +##
6462 +##
6463 +##
6464 +#**
6465 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
6466 + *
6467 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
6468 + * property set.
6469 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
6470 + *###
6471 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
6472 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
6473 + #set ($postsLayout = $NULL)
6474 + #setVariable (~"$postsLayout~" $res)
6475 +#end
6476 +##
6477 +##
6478 +##
6479 +#**
6480 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
6481 + *
6482 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
6483 + * @param blogDoc The resulting XDocument.
6484 + *###
6485 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
6486 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
6487 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
6488 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
6489 + #else
6490 + ## Fallback to Blog.WebHome, the default blog
6491 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
6492 + #end
6493 + #set ($blogDoc = $NULL)
6494 + #setVariable (~"$blogDoc~" $macro.result)
6495 +#end" %)
6496 +(((
6497 +(% class="macro-placeholder hidden" %)
6498 +(((
6499 +macro:velocity
6500 +)))
6501 +)))
6502 +)))
6503 +
6504 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
6505 +(((
6506 +(% class="macro-placeholder hidden" %)
6507 +(((
6508 +macro:include
6509 +)))
6510 +
6511 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
6512 + * Extract the layout parameters from a string.
6513 + *
6514 + * @param layoutParamsString The string representation of the layout parameters.
6515 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
6516 + * @param layoutsParameters The resulting layout parameters Map.
6517 + *###
6518 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
6519 + #set ($layoutsParameters = $NULL)
6520 + #set ($macro.layoutParams = \{})
6521 + #if (~"$!layoutParamsString~" != '')
6522 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
6523 + #foreach ($item in $macro.paramsArr)
6524 + #set ($itemSplit = $item.split('='))
6525 + #if ($itemSplit.size() == 2)
6526 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
6527 + #end
6528 + #end
6529 + #end
6530 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
6531 +#end" %)
6532 +(((
6533 +(% class="macro-placeholder hidden" %)
6534 +(((
6535 +macro:velocity
6536 +)))
6537 +)))
6538 +)))
6539 +
6540 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
6541 + #initLayoutVars($pDoc $pObj)
6542 + <div class=~"col-xs-12 col-sm-6 next_blog~">
6543 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
6544 + <div class=~"row~">
6545 + <div class=~"col-xs-4~">
6546 + #if ($imageAtt)
6547 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
6548 + #end
6549 + </div>
6550 + <div class=~"col-xs-8 art_det~">
6551 + <p class=~"text-left~">
6552 + #if($displayTitle)$!postTitle #end
6553 + <br/><span class=~"date_info~"> $!dateStr </span>
6554 + </p>
6555 + #displayPostDetails($pDoc)
6556 + </div>
6557 + </div>
6558 + </a>
6559 + </div>
6560 + #end
6561 + ##
6562 + ##
6563 + ##
6564 + #macro(displayPinnedPost $pDoc $pObj)
6565 + #initLayoutVars($pDoc $pObj)
6566 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
6567 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
6568 + <div class=~"thumbnail~">
6569 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
6570 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
6571 + #end
6572 + #if ($imageAtt)
6573 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
6574 + #end
6575 + <div class=~"caption~">
6576 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
6577 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
6578 + #end
6579 + #if ($displaySummaryOnPinnedPosts)
6580 + <div class=~"text-left post-summary~">
6581 + #set ($postContent = $pObj.getProperty('extract').value)
6582 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
6583 + </div>
6584 + #end
6585 + #displayPostDetails($pDoc)
6586 + </div>
6587 + </div>
6588 + </a>
6589 + </div>
6590 + #end
6591 + ##
6592 + ##
6593 + ##
6594 + #macro(formatPostDate $pDoc $pObj)
6595 + #set ($formattedDate = $NULL)
6596 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
6597 + #if (~"$!dateStr~" != '')
6598 + #set ($dateArr = $dateStr.split(' '))
6599 + #if ($dateArr.size() > 3)
6600 + #set ($dateStr = ~"~")
6601 + #foreach($s in $dateArr.subList(0, 3))
6602 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
6603 + #end
6604 + #end
6605 + #end
6606 + #setVariable(~"$formattedDate~" $dateStr)
6607 + #end
6608 + ##
6609 + ##
6610 + ##
6611 + #macro(displayPostDetails $pDoc)
6612 + <div class=~"row post-details~">
6613 + <div class=~"col-xs-8 detail~">
6614 + #if ($services.like.displayButton($pDoc.documentReference))
6615 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
6616 + ## Retrieve the likes number in XWiki 12.9+
6617 + #set ($likeNumber = $optLikeRecord.get())
6618 + #if (!$stringtool.isNumeric($likeNumber.toString()))
6619 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
6620 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
6621 + #end
6622 + #if ($stringtool.isNumeric($likeNumber.toString()))
6623 + <div class=~"post-likes btn btn-default disabled badge~"
6624 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
6625 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
6626 + </div>
6627 + #end
6628 + #elseif ($services.ratings)
6629 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
6630 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
6631 + <ul class=~"pull-left note list-inline~">
6632 + #foreach ($x in [1..5])
6633 + #set ($cls = ~"~")
6634 + #if ($x > $averageVote)
6635 + #set ($cls = ~"-o~")
6636 + #end
6637 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
6638 + #end
6639 + </ul>
6640 + #end
6641 + #end
6642 + </div>
6643 + #if ($showPostComments)
6644 + <div class=~"col-xs-4 com_det~">
6645 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
6646 + </div>
6647 + #end
6648 + </div>
6649 + #end
6650 + ##
6651 + ##
6652 + ##
6653 + #macro(initLayoutVars $pDoc $pObj)
6654 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
6655 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
6656 + #isPublished($pObj $isPublished)
6657 + #isHidden($pObj $isHidden)
6658 + #getEntryDate($pDoc $pObj $postDate)
6659 + #formatPostDate($postDate $dateStr)
6660 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
6661 + #set ($nbComments = $pDoc.getComments().size())
6662 + #set ($showPostComments = true)
6663 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
6664 + #set ($showPostComments = false)
6665 + #end
6666 + #end
6667 + ##
6668 + ##
6669 + ##
6670 + #macro(displayEditPinnedPostsButton)
6671 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
6672 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
6673 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
6674 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
6675 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
6676 + <div class=~"edit-pinned-posts-container~">
6677 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
6678 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
6679 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
6680 + </a>
6681 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
6682 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
6683 + </div>
6684 + </div>
6685 + #if (~"$!pinnedPostsObj~" == '')
6686 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
6687 + #end
6688 + #end
6689 + #end" %)
6690 +(((
6691 +(% class="macro-placeholder hidden" %)
6692 +(((
6693 +macro:velocity
6694 +)))
6695 +)))
6696 +
6697 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
6698 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
6699 + #getEntryObject($postDoc $postObj)
6700 + #if (~"$!postObj~" != '')
6701 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
6702 + ##
6703 + #set ($displayTitle = true)
6704 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
6705 + #set ($displayTitle = false)
6706 + #end
6707 + ##
6708 + #set ($displayTitleFirstOnPinnedPosts = false)
6709 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
6710 + #set ($displayTitleFirstOnPinnedPosts = true)
6711 + #end
6712 + ##
6713 + #set ($displaySummaryOnPinnedPosts = true)
6714 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
6715 + #set ($displaySummaryOnPinnedPosts = false)
6716 + #end
6717 + ##
6718 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
6719 + #if ($postIndex == 0)
6720 + #set ($stopBlogPostsDisplay = false)
6721 + #end
6722 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
6723 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
6724 + #set($scaleWidth = 600)
6725 + #set($imgQs=~"width=$scaleWidth~")
6726 + ## Display pinned posts
6727 + ## Get the list of pinned posts
6728 + #set ($pinnedPosts = [])
6729 + #set ($pinnedPostsSourceDoc = $NULL)
6730 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
6731 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
6732 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
6733 + #end
6734 + #if (~"$!pinnedPostsSourceDoc~" != '')
6735 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
6736 + #if (~"$!pinnedPostsObj~" != '')
6737 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
6738 + #if (~"$!orderedPinnedPostsJSON~" != '')
6739 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
6740 + #else
6741 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
6742 + #end
6743 + #end
6744 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
6745 + \{\{html clean=~"false~"}}
6746 + #set ($x = 0)
6747 + #set ($showPinnedPostsButton = true)
6748 + #foreach ($pinnedPost in $pinnedPosts)
6749 + #if ($x == 0)
6750 + <div class=~"row flex-container~">
6751 + #if ($showPinnedPostsButton)
6752 + #displayEditPinnedPostsButton()
6753 + #set($showPinnedPostsButton = false)
6754 + #end
6755 + #end
6756 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
6757 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
6758 + #if (~"$!pinnedPostObj~" != '')
6759 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
6760 + #end
6761 + #set ($x = $mathtool.add($x, 1))
6762 + #if ($x == 3)
6763 + #set ($x = 0)
6764 + </div>
6765 + #end
6766 + #end
6767 + #if ($mathtool.mod($x, 3) != 0)
6768 + </div>
6769 + #end
6770 + \{\{/html}}
6771 +
6772 + ## If the first post is a pinned post : this means that all the posts are pinned
6773 + ## In this case, avoid displaying the posts again after the pinned posts section.
6774 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
6775 + #set ($stopBlogPostsDisplay = true)
6776 + #end
6777 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
6778 +
6779 + \{\{html}}
6780 + <div class=~"row no-pinnded-posts~">
6781 + #displayEditPinnedPostsButton()
6782 + </div>
6783 + \{\{/html}}
6784 +
6785 + #end
6786 + #end
6787 + #if (!$stopBlogPostsDisplay)
6788 + \{\{html clean=~"false~"}}
6789 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
6790 + #set ($nbDisplayedPosts = 0)
6791 + #end
6792 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
6793 + #if ($nbDisplayedPosts != 0)
6794 + </div>
6795 + #set ($lastHtmlTag = 'c')
6796 + #end
6797 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
6798 + <div class=~"row~">
6799 + #set ($lastHtmlTag = 'o')
6800 + #set ($lastRowClass = ~"~")
6801 + #else
6802 + <div class=~"row flex-container~">
6803 + #set ($lastHtmlTag = 'o')
6804 + #set ($lastRowClass = ~"flex~")
6805 + #end
6806 + #end
6807 + #displaySmallPost($postDoc $postObj)
6808 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
6809 + </div>
6810 + #set ($lastHtmlTag = 'c')
6811 + #end
6812 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
6813 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
6814 + #if (~"$!lastHtmlTag~" == 'o')
6815 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
6816 + <div class=~"col-xs-12 col-sm-6~"></div>
6817 + #end
6818 + </div>
6819 + #end
6820 + #end
6821 + \{\{/html}}
6822 + #end
6823 + #else
6824 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
6825 + #end
6826 + #else
6827 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
6828 + #end" %)
6829 +(((
6830 +(% class="macro-placeholder hidden" %)
6831 +(((
6832 +macro:velocity
6833 +)))
6834 +
6835 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"col-xs-12 col-sm-6 next_blog~">
6836 +<a href=~"/Nieuws/Nieuwsbrief%20november%202023~" class=~"thumbnail~">
6837 +<div class=~"row~">
6838 +<div class=~"col-xs-4~">
6839 +<img src=~"/download/Nieuws/Nieuwsbrief%20november%202023/man-person-light-bokeh-blur-road-1268120-pxhere.com.jpg?width=600&rev=1.1~" />
6840 +</div>
6841 +<div class=~"col-xs-8 art_det~">
6842 +<p class=~"text-left~">
6843 +Nieuwsbrief november 2023 <br/><span class=~"date_info~"> Dec 18, 2023, </span>
6844 +</p>
6845 +<div class=~"row post-details~">
6846 +<div class=~"col-xs-8 detail~">
6847 +<div class=~"post-likes btn btn-default disabled badge~"
6848 +title=~"Number of likes on this page: 0~">
6849 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">0</span>
6850 +</div>
6851 +</div>
6852 +<div class=~"col-xs-4 com_det~">
6853 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
6854 +</div>
6855 +</div>
6856 +</div>
6857 +</div>
6858 +</a>
6859 +</div>" %)
6860 +(((
6861 +(% class="macro-placeholder hidden" %)
6862 +(((
6863 +macro:html
6864 +)))
6865 +
6866 +(% class="col-xs-12 col-sm-6 next_blog" %)
6867 +(((
6868 +(% class="row" %)
6869 +(((
6870 +(% class="col-xs-4" %)
6871 +(((
6872 +[[~[~[image:/download/Nieuws/Nieuwsbrief%20november%202023/man-person-light-bokeh-blur-road-1268120-pxhere.com.jpg?width=600&rev=1.1~]~]>>path:/Nieuws/Nieuwsbrief%20november%202023||class="thumbnail"]]
6873 +)))
6874 +
6875 +(% class="col-xs-8 art_det" %)
6876 +(((
6877 +(% class="text-left" %)
6878 +[[Nieuwsbrief november 2023
6879 +(% class="date_info" %) Dec 18, 2023,>>path:/Nieuws/Nieuwsbrief%20november%202023||class="thumbnail"]]
6880 +
6881 +(% class="row post-details" %)
6882 +(((
6883 +(% class="col-xs-8 detail" %)
6884 +(((
6885 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 0" %)
6886 +(((
6887 +[[(% class="like-number" %)0>>path:/Nieuws/Nieuwsbrief%20november%202023||class="thumbnail"]]
6888 +)))
6889 +)))
6890 +
6891 +(% class="col-xs-4 com_det" %)
6892 +(((
6893 +(% class="text-right" %)
6894 +[[(0)>>path:/Nieuws/Nieuwsbrief%20november%202023||class="thumbnail"]]
6895 +)))
6896 +)))
6897 +)))
6898 +)))
6899 +)))
6900 +)))
6901 +)))
6902 +)))
6903 +
6904 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Feestelijke afsluiting, keuring materieel en tellen voorraden~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG|postIndex=3|previousPostReference=Nieuws.Nieuwsbrief december 2023|postIndex=4|previousPostReference=Nieuws.Nieuwsbrief november 2023~"" %)
6905 +(((
6906 +(% class="macro-placeholder hidden" %)
6907 +(((
6908 +macro:blogPostLayoutCards
6909 +)))
6910 +
6911 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
6912 +(((
6913 +(% class="macro-placeholder hidden" %)
6914 +(((
6915 +macro:include
6916 +)))
6917 +
6918 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
6919 +(((
6920 +(% class="macro-placeholder hidden" %)
6921 +(((
6922 +macro:include
6923 +)))
6924 +
6925 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
6926 +#set($blogClassname = 'Blog.BlogClass')
6927 +#set($blogTemplate = 'Blog.BlogTemplate')
6928 +#set($blogSheet = 'Blog.BlogSheet')
6929 +## Blog entries
6930 +#set($blogPostClassname = 'Blog.BlogPostClass')
6931 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
6932 +#set($blogPostSheet = 'Blog.BlogPostSheet')
6933 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
6934 +#set($oldArticleClassname = 'XWiki.ArticleClass')
6935 +## Categories
6936 +#set($blogCategoryClassname = 'Blog.CategoryClass')
6937 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
6938 +#set($blogCategorySheet = 'Blog.CategorySheet')
6939 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
6940 +#set($oldBlogCategoryClassname = 'Blog.Categories')
6941 +#set($defaultCategoryParent = 'Blog.Categories')
6942 +## Style
6943 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
6944 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
6945 +## Clientside scripts
6946 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
6947 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
6948 +## Misc
6949 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
6950 +#set($isBlogPost = $doc.getObject($blogPostClassname))
6951 +#set($defaultBlogSpace = 'Blog')
6952 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
6953 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
6954 +##
6955 +##
6956 +##
6957 +#**
6958 + * Displays an image, taken from the blog style document.
6959 + *
6960 + * @param $imgName The name of the icon from icons set to use.
6961 + *#
6962 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
6963 +(((
6964 +(% class="macro-placeholder hidden" %)
6965 +(((
6966 +macro:velocity
6967 +)))
6968 +)))
6969 +)))
6970 +
6971 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
6972 +##
6973 +##
6974 +## Import the blog skin and javascripts.
6975 +$!xwiki.ssx.use($blogStyleDocumentName)##
6976 +$!xwiki.jsx.use($blogScriptsDocumentName)##
6977 +##
6978 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
6979 +#template('hierarchy_macros.vm')##
6980 +##
6981 +##
6982 +#**
6983 + * Prints a blog. This is the main macro used in the BlogSheet.
6984 + *
6985 + * @param blogDoc the XDocument holding the blog definition object.
6986 + *###
6987 +#macro(printBlog $blogDoc)
6988 + \{\{include reference='Blog.CreatePost'/}}
6989 +
6990 + ## Use the blogPostList macro to display the blogposts
6991 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
6992 + ## do not support FTM the monthly and weekly blog display types
6993 + #getBlogDisplayType($blogDoc $displayType)
6994 + #if ($displayType == 'weekly' || $displayType == 'monthly')
6995 + #getBlogEntries($blogDoc $entries)
6996 + #displayBlog($entries 'index' true true)
6997 + #displayNavigationLinks($blogDoc)
6998 + #else
6999 + #getBlogDisplayType($blogDoc $displayType)
7000 + #set ($paginated = 'no')
7001 + #if ($displayType == 'paginated')
7002 + #set ($paginated = 'yes')
7003 + #end
7004 + #getBlogPostsLayout($blogDoc $postsLayout)
7005 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
7006 + #end
7007 +#end
7008 +##
7009 +##
7010 +##
7011 +#**
7012 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
7013 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
7014 + * all entries).
7015 + *
7016 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7017 + *###
7018 +#macro(showBlogInfo $blogDoc)
7019 + #if($blogDoc.getObject($blogClassname))
7020 + ## Keep testing for inline action for backward compatibility with older blogs.
7021 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
7022 + #macro(displayProperty $blogDoc $propname)
7023 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
7024 + : $blogDoc.display($propname)
7025 + #end
7026 + #displayProperty($blogDoc 'title')
7027 + #displayProperty($blogDoc 'description')
7028 + #displayProperty($blogDoc 'displayType')
7029 + #displayProperty($blogDoc 'itemsPerPage')
7030 + #displayProperty($blogDoc 'postsLayout')
7031 + #displayProperty($blogDoc 'postsLayoutParameters')
7032 + #else
7033 + $blogDoc.display('description')
7034 + #end
7035 + #elseif($doc.fullName == $blogSheet)
7036 += $services.localization.render('blog.code.blogsheet') =
7037 + \{\{translation key='blog.code.sheetexplanation'/}}
7038 + #else
7039 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
7040 + #end
7041 +#end
7042 +##
7043 +##
7044 +##
7045 +#**
7046 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
7047 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
7048 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
7049 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
7050 + *
7051 + * @param space A <tt>String</tt>, the name of the space where to search.
7052 + * @param blogDoc The resulting XDocument.
7053 + *###
7054 +#macro(getBlogDocument $space $blogDoc)
7055 + #set ($result = $NULL)
7056 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
7057 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
7058 + ## identify the right blog based on a configuration object in a WebPreferences page.
7059 + #set ($spaceReference = $services.model.resolveSpace($space))
7060 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
7061 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
7062 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
7063 + #if ($preferencesObj)
7064 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
7065 + #end
7066 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
7067 + #if (~"$!result~" == '')
7068 + ## First, try the Space.WebHome, for a whole-space blog
7069 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
7070 + #if(!$result.getObject($blogClassname))
7071 + ## Second, try the Space.Blog document
7072 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
7073 + #if(!$result.getObject($blogClassname))
7074 + ## Third, try searching for a blog document in the current space
7075 + ## Prevent the query fail when the space contains dots '.'
7076 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
7077 + #if($blogDocs.size() > 0)
7078 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
7079 + #else
7080 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
7081 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
7082 + #if($blogDocs.size() > 0)
7083 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
7084 + #else
7085 + ## Last, fallback to Blog.WebHome, the default blog
7086 + #set($result = $xwiki.getDocument('Blog.WebHome'))
7087 + #end
7088 + #end
7089 + #end
7090 + #end
7091 + #end
7092 + #set ($blogDoc = $NULL)
7093 + #setVariable (~"$blogDoc~" $result)
7094 +#end
7095 +##
7096 +##
7097 +##
7098 +#**
7099 + * Retrieve the blog title.
7100 + *
7101 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
7102 + * @param title The resulting title.
7103 + *###
7104 +#macro(getBlogTitle $blogDoc $title)
7105 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
7106 + #set ($title = $NULL)
7107 + #setVariable (~"$title~" $!blogDoc.displayTitle)
7108 +#end
7109 +##
7110 +##
7111 +##
7112 +#**
7113 + * Retrieve the blog description.
7114 + *
7115 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
7116 + * property set.
7117 + * @param description The resulting description.
7118 + *###
7119 +#macro(getBlogDescription $blogDoc $description)
7120 + #getBlogProperty($blogDoc 'description' '' $result)
7121 + #set ($description = $NULL)
7122 + #setVariable (~"$description~" $result)
7123 +#end
7124 +##
7125 +##
7126 +##
7127 +#**
7128 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
7129 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
7130 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
7131 + * month), or all.
7132 + *
7133 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7134 + * @param entries The resulting list of entries to display, a list of XDocument names.
7135 + *###
7136 +#macro(getBlogEntries $blogDoc $entries)
7137 + #if (!$entries)
7138 + #setVariable (~"$entries~" [])
7139 + #end
7140 + #getAllBlogPostsQuery($query)
7141 + #isDefaultBlog($blogDoc $isDefault)
7142 + #set($queryParams = \{})
7143 + #if ($isDefault)
7144 + #getCategoryAllBlogPostsQuery($query)
7145 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
7146 + #set($discard = $queryParams.put('creator', $xcontext.user))
7147 + #set($discard = $queryParams.put('space', $blogDoc.space))
7148 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
7149 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
7150 + #else
7151 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
7152 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
7153 + #set($discard = $queryParams.put('space', $blogPostsLocation))
7154 + #set($discard = $queryParams.put('parent', $blogDoc.space))
7155 + #end
7156 + #getBlogDisplayType($blogDoc $displayType)
7157 + #if($displayType == 'weekly')
7158 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
7159 + #elseif($displayType == 'monthly')
7160 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
7161 + #elseif($displayType == 'all')
7162 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
7163 + #else
7164 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
7165 + #end
7166 +#end
7167 +##
7168 +##
7169 +##
7170 +#**
7171 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
7172 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
7173 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
7174 + * (10 if not defined).
7175 + *
7176 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7177 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
7178 + * refined to restrict to a given space, or to a given search criteria, etc.
7179 + * @param entries The resulting list of entries to display, a list of XDocument names.
7180 + * @param queryParams The parameters to bind with the query.
7181 + *###
7182 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
7183 + #if (!$entries)
7184 + #setVariable (~"$entries~" [])
7185 + #end
7186 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
7187 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
7188 + #bindQueryParameters($countQueryObj $queryParams)
7189 + #bindQueryParameters($queryObj $queryParams)
7190 + #set($totalEntries = $countQueryObj.count())
7191 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
7192 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
7193 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
7194 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
7195 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
7196 +#end
7197 +##
7198 +##
7199 +##
7200 +#**
7201 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
7202 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
7203 + * digit year). Initially the current week is displayed.
7204 + *
7205 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7206 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
7207 + * refined to restrict to a given space, or to a given search criteria, etc.
7208 + * @param entries The resulting list of entries to display, a list of XDocument names.
7209 + * @param queryParams The parameters to bind with the query.
7210 + *###
7211 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
7212 + #if (!$entries)
7213 + #setVariable (~"$entries~" [])
7214 + #end
7215 + #getRequestedWeek($weekDate)
7216 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
7217 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
7218 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
7219 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
7220 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
7221 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
7222 + #bindQueryParameters($countQueryObj $queryParams)
7223 + #bindQueryParameters($queryObj $queryParams)
7224 + #set($totalEntries = $countQueryObj.count())
7225 + #set($discard = $entries.addAll($queryObj.execute()))
7226 +#end
7227 +##
7228 +##
7229 +##
7230 +#**
7231 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
7232 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
7233 + * digit year). Initially the current month is displayed.
7234 + *
7235 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7236 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
7237 + * refined to restrict to a given space, or to a given search criteria, etc.
7238 + * @param entries The resulting list of entries to display, a list of XDocument names.
7239 + * @param queryParams The parameters to bind with the query.
7240 + *###
7241 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
7242 + #if (!$entries)
7243 + #setVariable (~"$entries~" [])
7244 + #end
7245 + #getRequestedMonth($monthDate)
7246 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
7247 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
7248 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
7249 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
7250 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
7251 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
7252 + #bindQueryParameters($countQueryObj $queryParams)
7253 + #bindQueryParameters($queryObj $queryParams)
7254 + #set($totalEntries = $countQueryObj.count())
7255 + #set($discard = $entries.addAll($queryObj.execute()))
7256 +#end
7257 +##
7258 +##
7259 +##
7260 +#**
7261 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
7262 + *
7263 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7264 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
7265 + * refined to restrict to a given space, or to a given search criteria, etc.
7266 + * @param entries The resulting list of entries to display, a list of XDocument names.
7267 + * @param queryParams The parameters to bind with the query.
7268 + *###
7269 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
7270 + #if (!$entries)
7271 + #setVariable (~"$entries~" [])
7272 + #end
7273 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
7274 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
7275 + #bindQueryParameters($countQueryObj $queryParams)
7276 + #bindQueryParameters($queryObj $queryParams)
7277 + #set($totalEntries = $countQueryObj.count())
7278 + #set($discard = $entries.addAll($queryObj.execute()))
7279 +#end
7280 +##
7281 +##
7282 +##
7283 +#**
7284 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
7285 + *
7286 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7287 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
7288 + * refined to restrict to a given space, or to a given search criteria, etc.
7289 + * @param queryParams The parameters to bind with the query.
7290 + * @param entries The resulting list of entries to display, a list of XDocument names.
7291 + *###
7292 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
7293 + #if (!$entries)
7294 + #setVariable (~"$entries~" [])
7295 + #end
7296 + #set($query = ~"$\{query} and isPublished.value = 0~")
7297 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
7298 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
7299 + #bindQueryParameters($countQueryObj $queryParams)
7300 + #bindQueryParameters($queryObj $queryParams)
7301 + #set($totalEntries = $countQueryObj.count())
7302 + #set($discard = $entries.addAll($queryObj.execute()))
7303 +#end
7304 +##
7305 +##
7306 +##
7307 +#**
7308 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
7309 + *
7310 + * @param entries The resulting list of entries to display, a list of XDocument names.
7311 + *###
7312 +#macro(getGlobalBlogEntries $entries)
7313 + #if (!$entries)
7314 + #setVariable (~"$entries~" [])
7315 + #end
7316 + #getAllBlogPostsQuery($query)
7317 + #set($totalEntries = $services.query.hql($query).count())
7318 + #set($defaultItemsPerPage = 20)
7319 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
7320 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
7321 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
7322 +#end
7323 +#**
7324 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
7325 + * blog, nor specify a range or an ordering criteria.
7326 + *
7327 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
7328 + *
7329 + * @param query The basic query for selecting blog entries.
7330 + *#
7331 +#macro(getBlogEntriesBaseQuery $query)
7332 + #getAllBlogPostsQuery($query)
7333 +#end
7334 +#**
7335 + * Return the Query for selecting the all wiki blog posts without filtering
7336 + *
7337 + * @param query The basic query for selecting blog entries.
7338 + *#
7339 +#macro(getAllBlogPostsQuery $query)
7340 + #set ($query = $NULL)
7341 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
7342 + IntegerProperty hidden, DateProperty publishDate
7343 + where doc.fullName <> '$blogPostTemplate' and
7344 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
7345 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
7346 + hidden.id.id = obj.id and hidden.id.name='hidden' and
7347 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
7348 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
7349 +#end
7350 +##
7351 +##
7352 +##
7353 +###**
7354 + * Return the Query for selecting the all wiki blog posts with categories filtering
7355 + *
7356 + * @param query The basic query for selecting blog entries.
7357 + *###
7358 +#macro(getCategoryAllBlogPostsQuery $query)
7359 + #set ($query = $NULL)
7360 + #getAllBlogPostsQuery($baseQuery)
7361 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
7362 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
7363 +#end
7364 +##
7365 +##
7366 +##
7367 +#**
7368 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
7369 + * week), monthly (all entries in a month), or all.
7370 + *
7371 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
7372 + * property set.
7373 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
7374 + *###
7375 +#macro(getBlogDisplayType $blogDoc $displayType)
7376 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
7377 + #set ($displayType = $NULL)
7378 + #setVariable (~"$displayType~" $result)
7379 +#end
7380 +##
7381 +##
7382 +##
7383 +#**
7384 + * Displays a list of entries.
7385 + *
7386 + * @param entries The entries to display, a list of XDocument names.
7387 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
7388 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
7389 + * used values: index, single, category, search, unpublished, hidden.
7390 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
7391 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
7392 + * displayed alone on their page since it's the page title which is used in this case)
7393 + *###
7394 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
7395 + #set($blogDay = '')
7396 + (% class=~"hfeed $!\{displaying}~" ~%)(((
7397 + (% class=~"blogDay~" ~%)(((
7398 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
7399 + #getEntryObject($entryDoc $entryObj)
7400 + ## Although all entries should have one of the two objects, better check to be sure.
7401 + #if(~"$!\{entryObj}~" != '')
7402 + #getEntryDate($entryDoc $entryObj $entryDate)
7403 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
7404 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
7405 + #if($blogDay != $entryDateStr)
7406 + #if($blogDay != '')
7407 + )))
7408 + (% class=~"blogDay~" ~%)(((
7409 + #end
7410 + #displayBlogDate($entryDate)
7411 + #set ($blogDay = $entryDateStr)
7412 + #end
7413 + ## Finally, display the entry.
7414 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
7415 + #end
7416 + #end
7417 + )))## blogDay
7418 + )))## hfeed
7419 +#end
7420 +##
7421 +##
7422 +##
7423 +#**
7424 + * Get the entry object, either a new BlogPost or an old Article.
7425 + *
7426 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7427 + * @param entryObj The resulting xobject of the blog post.
7428 + *###
7429 +#macro(getEntryObject $entryDoc $__entryObj)
7430 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
7431 + #if(!$result)
7432 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
7433 + #end
7434 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
7435 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
7436 + ## overwritten in this case but it's less likely to have such a variable defined before.
7437 + #set ($__entryObj = $NULL)
7438 + #setVariable (~"$__entryObj~" $result)
7439 +#end
7440 +##
7441 +##
7442 +##
7443 +#**
7444 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
7445 + * the document creation date, but can be edited by the user.
7446 + *
7447 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7448 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7449 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
7450 + *###
7451 +#macro(getEntryDate $entryDoc $entryObj $result)
7452 + #set ($result = $NULL)
7453 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
7454 +#end
7455 +##
7456 +##
7457 +##
7458 +#**
7459 + * Displays a date, nicely formatted as a calendar page.
7460 + *
7461 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
7462 + *###
7463 +#macro(displayBlogDate $date)
7464 + #set($year = $xwiki.formatDate($date, 'yyyy'))
7465 + ## 3 letter month name, like Jan, Dec.
7466 + #set($month = $xwiki.formatDate($date, 'MMM'))
7467 + ## Uncomment to get a full length month name, like January, December.
7468 + ## TODO: this could be defined somewhere in the blog style.
7469 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
7470 + #set($day = $xwiki.formatDate($date, 'dd'))
7471 + (% class=~"blogdate~" ~%)
7472 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
7473 +#end
7474 +##
7475 +##
7476 +##
7477 +#**
7478 + * Displays a blog article: management tools, header, content, footer.
7479 + *
7480 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7481 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7482 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
7483 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
7484 + * when they're displayed alone on their page since it's the page title which is used in this case)
7485 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
7486 + *###
7487 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
7488 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
7489 + #isPublished($entryObj $isPublished)
7490 + #isHidden($entryObj $isHidden)
7491 + #if($doc.fullName == $entryDoc.fullName)
7492 + (% class=~"hentry single-article~" ~%)(((
7493 + #else
7494 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
7495 + #end
7496 + #if ($shouldDisplayActions)
7497 + #displayEntryTools($entryDoc $entryObj)
7498 + #end
7499 + #if($shouldDisplayTitle)
7500 + #displayEntryTitle($entryDoc $entryObj)
7501 + #end
7502 + #if($doc.fullName == $entryDoc.fullName)
7503 + #if(!$isPublished)
7504 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
7505 + #elseif($isHidden)
7506 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
7507 + #end
7508 + #end
7509 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
7510 + #displayEntryFooter($entryDoc $entryObj)
7511 + )))## hentry
7512 +#end
7513 +##
7514 +##
7515 +##
7516 +#**
7517 + * Checks if the provided blog is published or not.
7518 + *
7519 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7520 + * @param isPublished The resulting boolean, true if the entry is considered published.
7521 + *###
7522 +#macro(isPublished $entryObj $isPublished)
7523 + #set ($isPublished = $NULL)
7524 + ## This should work for both old articles, which don't have the 'published' property at all, and
7525 + ## are considered published by default, and new entries, that should have 1 if published.
7526 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
7527 + #setVariable (~"$isPublished~" true)
7528 + #else
7529 + #setVariable (~"$isPublished~" false)
7530 + #end
7531 +#end
7532 +##
7533 +##
7534 +##
7535 +#**
7536 + * Checks if the provided blog is hidden or not.
7537 + *
7538 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
7539 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
7540 + *###
7541 +#macro(isHidden $entryObj $isHidden)
7542 + #set ($isHidden = $NULL)
7543 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
7544 + ## are considered visible by default, and new entries, that should have 1 if hidden.
7545 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
7546 + #setVariable (~"$isHidden~" true)
7547 + #else
7548 + #setVariable (~"$isHidden~" false)
7549 + #end
7550 +#end
7551 +##
7552 +##
7553 +##
7554 +#**
7555 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
7556 + *
7557 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7558 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7559 + *###
7560 +#macro(displayEntryTools $entryDoc $entryObj)
7561 + #if($xcontext.action == 'view')
7562 + (% class=~"blog-entry-toolbox~" ~%)(((
7563 + #displayPublishButton($entryDoc $entryObj)
7564 + #displayHideShowButton($entryDoc $entryObj)
7565 + #displayEditButton($entryDoc $entryObj)
7566 + #displayDeleteButton($entryDoc $entryObj)
7567 + )))
7568 + #end
7569 +#end
7570 +##
7571 +##
7572 +##
7573 +#**
7574 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
7575 + *
7576 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7577 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7578 + * @todo AJAX calls.
7579 + *###
7580 +#macro(displayPublishButton $entryDoc $entryObj)
7581 + #isPublished($entryObj $isPublished)
7582 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
7583 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
7584 + #end
7585 +#end
7586 +##
7587 +##
7588 +##
7589 +#**
7590 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
7591 + *
7592 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7593 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7594 + *###
7595 +#macro(displayHideShowButton $entryDoc $entryObj)
7596 + #isPublished($entryObj $isPublished)
7597 + #isHidden($entryObj $isHidden)
7598 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
7599 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
7600 + #set ($queryString = \{
7601 + 'xredirect' : $thisURL,
7602 + 'form_token' : $services.csrf.getToken()
7603 + })
7604 + #if ($isHidden)
7605 + #set ($discard = $queryString.putAll(\{
7606 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
7607 + 'comment' : $services.localization.render('blog.code.madevisible')
7608 + }))
7609 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
7610 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
7611 + #else
7612 + #set ($discard = $queryString.putAll(\{
7613 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
7614 + 'comment' : $services.localization.render('blog.code.hid')
7615 + }))
7616 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
7617 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
7618 + #end
7619 + #end
7620 +#end
7621 +##
7622 +##
7623 +##
7624 +#**
7625 + * Displays the edit button to those that can edit the article.
7626 + *
7627 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7628 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7629 + *###
7630 +#macro(displayEditButton $entryDoc $entryObj)
7631 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
7632 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
7633 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
7634 + #end
7635 +#end
7636 +##
7637 +##
7638 +##
7639 +#**
7640 + * Displays the delete button to those that can edit the article.
7641 + *
7642 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7643 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7644 + * @todo AJAX calls.
7645 + *###
7646 +#macro(displayDeleteButton $entryDoc $entryObj)
7647 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
7648 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
7649 + #end
7650 +#end
7651 +##
7652 +##
7653 +##
7654 +#**
7655 + * Displays the title of the entry.
7656 + *
7657 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7658 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7659 + *###
7660 +#macro(displayEntryTitle $entryDoc $entryObj)
7661 + #if($doc.fullName == $entryDoc.fullName)
7662 + (% class=~"entry-title~" ~%)
7663 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
7664 + #else
7665 + (% class=~"entry-title~" ~%)
7666 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
7667 + #end
7668 +#end
7669 +##
7670 +##
7671 +##
7672 +#**
7673 + * Displays the body of the entry.
7674 + *
7675 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7676 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7677 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
7678 + *###
7679 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
7680 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
7681 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
7682 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
7683 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
7684 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
7685 + ))) ## entry-content
7686 + (% class=~"clearfloats~" ~%)((()))
7687 +#end
7688 +##
7689 +##
7690 +##
7691 +#**
7692 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
7693 + * of the <tt>extract</tt> field (if not empty).
7694 + *
7695 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7696 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7697 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
7698 + * @param entryContent The resulting content.
7699 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
7700 + * <tt>onlyExtract</tt> is <tt>true</tt>)
7701 + *###
7702 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
7703 + #if ($onlyExtract)
7704 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
7705 + ## of the content.
7706 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
7707 + #end
7708 + #if(~"$!macro.result~" == '')
7709 + #set($macro.result = $entryObj.getProperty('content').value)
7710 +#* Disabled until the content can be cleanly cut.
7711 +* #if($onlyExtract && $result.length()>$maxchars)
7712 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
7713 +* #set($i = $i + 1)
7714 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
7715 +* #end
7716 +## *###
7717 + #elseif (!$removeEllipsis)
7718 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
7719 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
7720 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
7721 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
7722 + #end
7723 + #end
7724 + #set ($entryContent = $NULL)
7725 + #setVariable (~"$entryContent~" $macro.result)
7726 +#end
7727 +##
7728 +##
7729 +##
7730 +#**
7731 + * Displays the footer of the entry.
7732 + *
7733 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7734 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7735 + *###
7736 +#macro(displayEntryFooter $entryDoc $entryObj)
7737 + (% class=~"entry-footer~" ~%)(((
7738 + #isPublished($entryObj $isPublished)
7739 + (% class='entry-author-label' ~%)
7740 + #if($isPublished)
7741 + \{\{translation key='blog.code.postedby'/}} ##
7742 + #else
7743 + \{\{translation key='blog.code.createdby'/}} ##
7744 + #end
7745 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
7746 + #getEntryDate($entryDoc $entryObj $entryDate)
7747 + #listCategories($entryObj) #*
7748 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
7749 + ## we assume cannot be more than 3 seconds.
7750 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
7751 + #if ($showcomments)
7752 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
7753 + #end ##
7754 + #if($entryDoc != $doc) ##
7755 + #displayEntryBlogLocation($entryDoc $entryObj) ##
7756 + #end
7757 + )))## entry-footer
7758 +#end
7759 +##
7760 +##
7761 +#**
7762 + * Display the blog for the entry (if it is not the currently displayed blog)
7763 + *
7764 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
7765 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7766 + *###
7767 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
7768 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
7769 + #if(~"$!blogPostsLocation~" != ~"~") ##
7770 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
7771 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
7772 + #if($doc.documentReference != $blogDocRef) ##
7773 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
7774 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
7775 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
7776 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
7777 + )))(%~%)##
7778 + #end
7779 + #end
7780 + #end
7781 +#end
7782 +##
7783 +##
7784 +##
7785 +##
7786 +#**
7787 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
7788 + *
7789 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
7790 + *###
7791 +#macro(listCategories $entryObj)
7792 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
7793 + #set($categories = $entryObj.getProperty('category').value)
7794 + #set($first = true)
7795 + #if($categories.size() > 0)
7796 + #foreach($category in $categories)
7797 + #set($categoryDoc = $!xwiki.getDocument($category))
7798 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
7799 + #if($foreach.count == 1)
7800 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
7801 + #else
7802 + , ##
7803 + #end##
7804 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
7805 + #end##
7806 + #end##
7807 + #end
7808 + #end
7809 +#end
7810 +##
7811 +##
7812 +##
7813 +#**
7814 + * Displays blog pagination links (older and newer entries).
7815 + *
7816 + * @param blogDoc the XDocument holding the blog definition object.
7817 + *###
7818 +#macro(displayNavigationLinks $blogDoc)
7819 + (% class=~"clearfloats~" ~%)((()))
7820 + #getBlogDisplayType($blogDoc $displayType)
7821 + #if($displayType == 'weekly')
7822 + (% class=~"pagingLinks~" ~%)(((
7823 + #getRequestedWeek($weekDate)
7824 + $weekDate.addWeeks(-1)##
7825 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
7826 + #sep()
7827 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
7828 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
7829 + )))
7830 + #elseif($displayType == 'monthly')
7831 + (% class=~"pagingLinks~" ~%)(((
7832 + #getRequestedMonth($monthDate)
7833 + $monthDate.addMonths(-1)##
7834 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
7835 + #sep()
7836 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
7837 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
7838 + )))
7839 + #elseif($displayType == 'all')
7840 + #else
7841 + ## Paginated
7842 + #if(($totalPages > 1))
7843 + #set($queryString = '')
7844 + #foreach($p in $request.getParameterNames())
7845 + #if($p != 'page' && $p != 'ipp')
7846 + #foreach($v in $request.getParameterValues($p))
7847 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
7848 + #end
7849 + #end
7850 + #end
7851 + (% class=~"pagingLinks~" ~%)(((
7852 + #if ($currentPageNumber < $totalPages)
7853 + #set($currentPageNumber = $currentPageNumber + 1)
7854 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
7855 + #set($currentPageNumber = $currentPageNumber - 1)
7856 + #end
7857 + #if ($currentPageNumber > 1)
7858 + #if ($currentPageNumber < $totalPages)
7859 + #sep()
7860 + #end
7861 + #set($currentPageNumber = $currentPageNumber - 1)
7862 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
7863 + #set($currentPageNumber = $currentPageNumber + 1)
7864 + #end
7865 + (% class=~"clear~" ~%)(%~%)
7866 + )))## pagingLinks
7867 + #end
7868 + #end
7869 +#end
7870 +##
7871 +##
7872 +##
7873 +#**
7874 + * Displays a message box with ~"publish~" icon.
7875 + *
7876 + * @param message A text message concerning blog article publishing
7877 + *###
7878 +#macro(publishMessageBox $message)
7879 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
7880 +#end
7881 +#**
7882 + * Displays a message box with ~"show/hide~" icon.
7883 + *
7884 + * @param message A text message concerning blog article hiding
7885 + *###
7886 +#macro(hideMessageBox $message)
7887 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
7888 +#end
7889 +##
7890 +##
7891 +##
7892 +#**
7893 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
7894 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
7895 + *
7896 + * @param monthDate The resulting week, a JODATime MutableDateTime.
7897 + *###
7898 +#macro(getRequestedWeek $weekDate)
7899 + #set ($weekDate = $NULL)
7900 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
7901 + #if(~"$!\{request.year}~" != '')
7902 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
7903 + #end
7904 + #if(~"$!\{request.week}~" != '')
7905 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
7906 + #end
7907 +#end
7908 +##
7909 +##
7910 +##
7911 +#**
7912 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
7913 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
7914 + *
7915 + * @param monthDate The resulting month, a JODATime MutableDateTime.
7916 + *###
7917 +#macro(getRequestedMonth $monthDate)
7918 + #set ($monthDate = $NULL)
7919 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
7920 + #if(~"$!\{request.year}~" != '')
7921 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
7922 + #end
7923 + #if(~"$!\{request.month}~" != '')
7924 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
7925 + #end
7926 +#end
7927 +##
7928 +##
7929 +##
7930 +#**
7931 + * Retrieve a blog property (title, display type, etc).
7932 + *
7933 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7934 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
7935 + * @param defaultValue The default value to use in case the blog object does not define one.
7936 + * @param propertyValue The resulting value.
7937 + *###
7938 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
7939 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
7940 + #if($result == '')
7941 + #set($result = $defaultValue)
7942 + #end
7943 + #set ($propertyValue = $NULL)
7944 + #setVariable (~"$propertyValue~" $result)
7945 +#end
7946 +
7947 +#**
7948 + * If an error occurs when executing an action, set a specific response status and display an error message.
7949 + *
7950 + * @param status The response status.
7951 + * @param text The user readable error to be displayed. Can be a translation key.
7952 + * @param parameters The parameters to use when decoding the translation key.
7953 + *###
7954 +#macro(blog__actionResponseError $status $text $parameters)
7955 + $response.setStatus($status)
7956 + #if($request.ajax)
7957 + $services.localization.render($text, $!parameters)
7958 + #else
7959 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
7960 + #end
7961 +#end
7962 +##
7963 +##
7964 +##
7965 +#**
7966 + * Check if a blog is the Default blog (The one in the 'Blog' space).
7967 + *
7968 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
7969 + * @param isDefault The resulting boolean.
7970 + *###
7971 +#macro(isDefaultBlog $blogDoc $isDefault)
7972 + #set ($result = false)
7973 + #if ($blogDoc.space == 'Blog')
7974 + #set ($result = true)
7975 + #end
7976 + #setVariable(~"$isDefault~" $result)
7977 +#end
7978 +##
7979 +##
7980 +##
7981 +#**
7982 + * Retrieve the blog posts location (space).
7983 + *
7984 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
7985 + * @param postsLocation The resulting location.
7986 + *###
7987 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
7988 + #getBlogDocument($blogSpace $blogDoc)
7989 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
7990 + #set ($postsLocation = $NULL)
7991 + #setVariable (~"$postsLocation~" $result)
7992 +#end
7993 +##
7994 +##
7995 +##
7996 +#**
7997 + * Retrieve the blog categories location (space).
7998 + *
7999 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
8000 + * @param categoriesLocation The resulting location.
8001 + *###
8002 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
8003 + #getBlogDocument($blogSpace $blogDoc)
8004 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
8005 + #set ($postsLocation = $NULL)
8006 + #setVariable (~"$categoriesLocation~" $result)
8007 +#end
8008 +###**
8009 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
8010 + * for example there is 4 different panel contexts:
8011 + * aBlog.aPost or aBlog.WebHome
8012 + * aCategorySpace.aCategory
8013 + * aCategorySpace.WebHome
8014 + * Blog.aPost or Blog.WebHome
8015 + *
8016 + * @param query The query for selecting blog entries.
8017 + * @param queryParams The parameters to bind with the generated query.
8018 + * @param targetDoc The document in which the articles will be displayed.
8019 + *###
8020 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
8021 + #set ($query = $NULL)
8022 + #set ($queryParams = $NULL)
8023 + #getCategoryAllBlogPostsQuery($resultQuery)
8024 + #set ($resultQueryParams = \{})
8025 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
8026 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
8027 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
8028 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
8029 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
8030 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
8031 + #elseif($targetDoc.getObject($blogCategoryClassname))
8032 + ## Get all posts that are in a category aCategorySpace.aCategory
8033 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
8034 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
8035 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
8036 + ## Get all posts that are in a category aCategorySpace.%
8037 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
8038 + ## Exclude incategorized posts
8039 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
8040 + #if ($targetDoc.space == $defaultBlogSpace)
8041 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
8042 + #end
8043 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
8044 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
8045 + #else
8046 + ## Get all posts in blog space aBlog
8047 + #getAllBlogPostsQuery($resultQuery)
8048 + #getBlogPostsLocation($targetDoc.space $postsLocation)
8049 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
8050 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
8051 + #end
8052 + #setVariable(~"$query~" $resultQuery)
8053 + #setVariable(~"$queryParams~" $resultQueryParams)
8054 +#end
8055 +##
8056 +##
8057 +##
8058 +###**
8059 + * Display blog posts based on the context where the posts are displayed.
8060 + * for example there is 4 different panel contexts:
8061 + * aBlog.aPost or aBlog.WebHome
8062 + * aCategorySpace.aCategory
8063 + * aCategorySpace.WebHome
8064 + * Blog.aPost or Blog.WebHome
8065 + *
8066 + * @param targetDoc The document in which the articles will be displayed.
8067 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
8068 + * @param layout Layout of the the posts to display
8069 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
8070 + * @param limit the number of posts to display
8071 + *###
8072 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
8073 + #if ($postLayout == 'full')
8074 + #set ($macro.paginated = 'yes')
8075 + #end
8076 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
8077 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
8078 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
8079 + #if (~"$!layout~" == '')
8080 + #set ($layout = $postsLayout)
8081 + #end
8082 + #if ($postsVisiblity == 'recent')
8083 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
8084 + #elseif($postsVisiblity == 'unpublished')
8085 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
8086 + #end
8087 + #elseif($targetDoc.getObject($blogCategoryClassname))
8088 + ## Display all posts that are in a category aCategorySpace.aCategory
8089 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
8090 + #getBlogPostsLayout($blogDoc $postsLayout)
8091 + #if (~"$!layout~" == '')
8092 + #set ($layout = $postsLayout)
8093 + #end
8094 + #if ($postsVisiblity == 'recent')
8095 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
8096 + #elseif($postsVisiblity == 'unpublished')
8097 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
8098 + #end
8099 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
8100 + ## Display all posts that are in a category aCategorySpace.%
8101 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
8102 + #getBlogPostsLayout($blogDoc $postsLayout)
8103 + #if (~"$!layout~" == '')
8104 + #set ($layout = $postsLayout)
8105 + #end
8106 + #if ($postsVisiblity == 'recent')
8107 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
8108 + #elseif($postsVisiblity == 'unpublished')
8109 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
8110 + #end
8111 + #else
8112 + ## Display all posts in blog space aBlog
8113 + #getBlogDocument($targetDoc.space $blogDoc)
8114 + #getBlogPostsLayout($blogDoc $postsLayout)
8115 + #if (~"$!layout~" == '')
8116 + #set ($layout = $postsLayout)
8117 + #end
8118 + #if ($postsVisiblity == 'recent')
8119 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
8120 + #elseif($postsVisiblity == 'unpublished')
8121 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
8122 + #end
8123 + #end
8124 +#end
8125 +##
8126 +##
8127 +##
8128 +#**
8129 + * Bind parameters to a query object.
8130 + *
8131 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
8132 + * @param queryParams the query parameters.
8133 + *###
8134 +#macro(bindQueryParameters $queryObj $queryParams)
8135 + #set ($output = $queryObj)
8136 + #foreach( $key in $queryParams.keySet() )
8137 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
8138 + #end
8139 + #setVariable(~"$queryObj~" $output)
8140 +#end
8141 +##
8142 +##
8143 +##
8144 +#**
8145 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
8146 + *
8147 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
8148 + * property set.
8149 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
8150 + *###
8151 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
8152 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
8153 + #set ($postsLayout = $NULL)
8154 + #setVariable (~"$postsLayout~" $res)
8155 +#end
8156 +##
8157 +##
8158 +##
8159 +#**
8160 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
8161 + *
8162 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
8163 + * @param blogDoc The resulting XDocument.
8164 + *###
8165 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
8166 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
8167 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
8168 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
8169 + #else
8170 + ## Fallback to Blog.WebHome, the default blog
8171 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
8172 + #end
8173 + #set ($blogDoc = $NULL)
8174 + #setVariable (~"$blogDoc~" $macro.result)
8175 +#end" %)
8176 +(((
8177 +(% class="macro-placeholder hidden" %)
8178 +(((
8179 +macro:velocity
8180 +)))
8181 +)))
8182 +)))
8183 +
8184 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
8185 +(((
8186 +(% class="macro-placeholder hidden" %)
8187 +(((
8188 +macro:include
8189 +)))
8190 +
8191 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
8192 + * Extract the layout parameters from a string.
8193 + *
8194 + * @param layoutParamsString The string representation of the layout parameters.
8195 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
8196 + * @param layoutsParameters The resulting layout parameters Map.
8197 + *###
8198 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
8199 + #set ($layoutsParameters = $NULL)
8200 + #set ($macro.layoutParams = \{})
8201 + #if (~"$!layoutParamsString~" != '')
8202 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
8203 + #foreach ($item in $macro.paramsArr)
8204 + #set ($itemSplit = $item.split('='))
8205 + #if ($itemSplit.size() == 2)
8206 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
8207 + #end
8208 + #end
8209 + #end
8210 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
8211 +#end" %)
8212 +(((
8213 +(% class="macro-placeholder hidden" %)
8214 +(((
8215 +macro:velocity
8216 +)))
8217 +)))
8218 +)))
8219 +
8220 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
8221 + #initLayoutVars($pDoc $pObj)
8222 + <div class=~"col-xs-12 col-sm-6 next_blog~">
8223 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
8224 + <div class=~"row~">
8225 + <div class=~"col-xs-4~">
8226 + #if ($imageAtt)
8227 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
8228 + #end
8229 + </div>
8230 + <div class=~"col-xs-8 art_det~">
8231 + <p class=~"text-left~">
8232 + #if($displayTitle)$!postTitle #end
8233 + <br/><span class=~"date_info~"> $!dateStr </span>
8234 + </p>
8235 + #displayPostDetails($pDoc)
8236 + </div>
8237 + </div>
8238 + </a>
8239 + </div>
8240 + #end
8241 + ##
8242 + ##
8243 + ##
8244 + #macro(displayPinnedPost $pDoc $pObj)
8245 + #initLayoutVars($pDoc $pObj)
8246 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
8247 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
8248 + <div class=~"thumbnail~">
8249 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
8250 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
8251 + #end
8252 + #if ($imageAtt)
8253 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
8254 + #end
8255 + <div class=~"caption~">
8256 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
8257 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
8258 + #end
8259 + #if ($displaySummaryOnPinnedPosts)
8260 + <div class=~"text-left post-summary~">
8261 + #set ($postContent = $pObj.getProperty('extract').value)
8262 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
8263 + </div>
8264 + #end
8265 + #displayPostDetails($pDoc)
8266 + </div>
8267 + </div>
8268 + </a>
8269 + </div>
8270 + #end
8271 + ##
8272 + ##
8273 + ##
8274 + #macro(formatPostDate $pDoc $pObj)
8275 + #set ($formattedDate = $NULL)
8276 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
8277 + #if (~"$!dateStr~" != '')
8278 + #set ($dateArr = $dateStr.split(' '))
8279 + #if ($dateArr.size() > 3)
8280 + #set ($dateStr = ~"~")
8281 + #foreach($s in $dateArr.subList(0, 3))
8282 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
8283 + #end
8284 + #end
8285 + #end
8286 + #setVariable(~"$formattedDate~" $dateStr)
8287 + #end
8288 + ##
8289 + ##
8290 + ##
8291 + #macro(displayPostDetails $pDoc)
8292 + <div class=~"row post-details~">
8293 + <div class=~"col-xs-8 detail~">
8294 + #if ($services.like.displayButton($pDoc.documentReference))
8295 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
8296 + ## Retrieve the likes number in XWiki 12.9+
8297 + #set ($likeNumber = $optLikeRecord.get())
8298 + #if (!$stringtool.isNumeric($likeNumber.toString()))
8299 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
8300 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
8301 + #end
8302 + #if ($stringtool.isNumeric($likeNumber.toString()))
8303 + <div class=~"post-likes btn btn-default disabled badge~"
8304 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
8305 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
8306 + </div>
8307 + #end
8308 + #elseif ($services.ratings)
8309 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
8310 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
8311 + <ul class=~"pull-left note list-inline~">
8312 + #foreach ($x in [1..5])
8313 + #set ($cls = ~"~")
8314 + #if ($x > $averageVote)
8315 + #set ($cls = ~"-o~")
8316 + #end
8317 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
8318 + #end
8319 + </ul>
8320 + #end
8321 + #end
8322 + </div>
8323 + #if ($showPostComments)
8324 + <div class=~"col-xs-4 com_det~">
8325 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
8326 + </div>
8327 + #end
8328 + </div>
8329 + #end
8330 + ##
8331 + ##
8332 + ##
8333 + #macro(initLayoutVars $pDoc $pObj)
8334 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
8335 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
8336 + #isPublished($pObj $isPublished)
8337 + #isHidden($pObj $isHidden)
8338 + #getEntryDate($pDoc $pObj $postDate)
8339 + #formatPostDate($postDate $dateStr)
8340 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
8341 + #set ($nbComments = $pDoc.getComments().size())
8342 + #set ($showPostComments = true)
8343 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
8344 + #set ($showPostComments = false)
8345 + #end
8346 + #end
8347 + ##
8348 + ##
8349 + ##
8350 + #macro(displayEditPinnedPostsButton)
8351 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
8352 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
8353 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
8354 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
8355 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
8356 + <div class=~"edit-pinned-posts-container~">
8357 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
8358 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
8359 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
8360 + </a>
8361 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
8362 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
8363 + </div>
8364 + </div>
8365 + #if (~"$!pinnedPostsObj~" == '')
8366 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
8367 + #end
8368 + #end
8369 + #end" %)
8370 +(((
8371 +(% class="macro-placeholder hidden" %)
8372 +(((
8373 +macro:velocity
8374 +)))
8375 +)))
8376 +
8377 +(% data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
8378 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
8379 + #getEntryObject($postDoc $postObj)
8380 + #if (~"$!postObj~" != '')
8381 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
8382 + ##
8383 + #set ($displayTitle = true)
8384 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
8385 + #set ($displayTitle = false)
8386 + #end
8387 + ##
8388 + #set ($displayTitleFirstOnPinnedPosts = false)
8389 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
8390 + #set ($displayTitleFirstOnPinnedPosts = true)
8391 + #end
8392 + ##
8393 + #set ($displaySummaryOnPinnedPosts = true)
8394 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
8395 + #set ($displaySummaryOnPinnedPosts = false)
8396 + #end
8397 + ##
8398 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
8399 + #if ($postIndex == 0)
8400 + #set ($stopBlogPostsDisplay = false)
8401 + #end
8402 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
8403 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
8404 + #set($scaleWidth = 600)
8405 + #set($imgQs=~"width=$scaleWidth~")
8406 + ## Display pinned posts
8407 + ## Get the list of pinned posts
8408 + #set ($pinnedPosts = [])
8409 + #set ($pinnedPostsSourceDoc = $NULL)
8410 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
8411 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
8412 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
8413 + #end
8414 + #if (~"$!pinnedPostsSourceDoc~" != '')
8415 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
8416 + #if (~"$!pinnedPostsObj~" != '')
8417 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
8418 + #if (~"$!orderedPinnedPostsJSON~" != '')
8419 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
8420 + #else
8421 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
8422 + #end
8423 + #end
8424 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
8425 + \{\{html clean=~"false~"}}
8426 + #set ($x = 0)
8427 + #set ($showPinnedPostsButton = true)
8428 + #foreach ($pinnedPost in $pinnedPosts)
8429 + #if ($x == 0)
8430 + <div class=~"row flex-container~">
8431 + #if ($showPinnedPostsButton)
8432 + #displayEditPinnedPostsButton()
8433 + #set($showPinnedPostsButton = false)
8434 + #end
8435 + #end
8436 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
8437 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
8438 + #if (~"$!pinnedPostObj~" != '')
8439 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
8440 + #end
8441 + #set ($x = $mathtool.add($x, 1))
8442 + #if ($x == 3)
8443 + #set ($x = 0)
8444 + </div>
8445 + #end
8446 + #end
8447 + #if ($mathtool.mod($x, 3) != 0)
8448 + </div>
8449 + #end
8450 + \{\{/html}}
8451 +
8452 + ## If the first post is a pinned post : this means that all the posts are pinned
8453 + ## In this case, avoid displaying the posts again after the pinned posts section.
8454 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
8455 + #set ($stopBlogPostsDisplay = true)
8456 + #end
8457 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
8458 +
8459 + \{\{html}}
8460 + <div class=~"row no-pinnded-posts~">
8461 + #displayEditPinnedPostsButton()
8462 + </div>
8463 + \{\{/html}}
8464 +
8465 + #end
8466 + #end
8467 + #if (!$stopBlogPostsDisplay)
8468 + \{\{html clean=~"false~"}}
8469 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
8470 + #set ($nbDisplayedPosts = 0)
8471 + #end
8472 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
8473 + #if ($nbDisplayedPosts != 0)
8474 + </div>
8475 + #set ($lastHtmlTag = 'c')
8476 + #end
8477 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
8478 + <div class=~"row~">
8479 + #set ($lastHtmlTag = 'o')
8480 + #set ($lastRowClass = ~"~")
8481 + #else
8482 + <div class=~"row flex-container~">
8483 + #set ($lastHtmlTag = 'o')
8484 + #set ($lastRowClass = ~"flex~")
8485 + #end
8486 + #end
8487 + #displaySmallPost($postDoc $postObj)
8488 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
8489 + </div>
8490 + #set ($lastHtmlTag = 'c')
8491 + #end
8492 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
8493 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
8494 + #if (~"$!lastHtmlTag~" == 'o')
8495 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
8496 + <div class=~"col-xs-12 col-sm-6~"></div>
8497 + #end
8498 + </div>
8499 + #end
8500 + #end
8501 + \{\{/html}}
8502 + #end
8503 + #else
8504 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
8505 + #end
8506 + #else
8507 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
8508 + #end" class="macro hidden macro-placeholder" %)macro:velocity(% data-macro="startmacro:html|-|clean=~"false~"|-|</div>
8509 +<div class=~"row flex-container~">
8510 +<div class=~"col-xs-12 col-sm-6 next_blog~">
8511 +<a href=~"/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden~" class=~"thumbnail~">
8512 +<div class=~"row~">
8513 +<div class=~"col-xs-4~">
8514 +<img src=~"/download/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden/OIP.jpg?width=600&rev=1.1~" />
8515 +</div>
8516 +<div class=~"col-xs-8 art_det~">
8517 +<p class=~"text-left~">
8518 +Feestelijke afsluiting, keuring materieel en tellen voorraden <br/><span class=~"date_info~"> Dec 14, 2023, </span>
8519 +</p>
8520 +<div class=~"row post-details~">
8521 +<div class=~"col-xs-8 detail~">
8522 +<div class=~"post-likes btn btn-default disabled badge~"
8523 +title=~"Number of likes on this page: 1~">
8524 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">1</span>
8525 +</div>
8526 +</div>
8527 +<div class=~"col-xs-4 com_det~">
8528 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
8529 +</div>
8530 +</div>
8531 +</div>
8532 +</div>
8533 +</a>
8534 +</div>" class="macro macro hidden macro-placeholder" %)macro:html
8535 +)))
8536 +)))
8537 +
8538 +(% class="row flex-container" %)
8539 +(((
8540 +(% class="col-xs-12 col-sm-6 next_blog" %)
8541 +(((
8542 +(% class="row" %)
8543 +(((
8544 +(% class="col-xs-4" %)
8545 +(((
8546 +[[~[~[image:/download/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden/OIP.jpg?width=600&rev=1.1~]~]>>path:/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden||class="thumbnail"]]
8547 +)))
8548 +
8549 +(% class="col-xs-8 art_det" %)
8550 +(((
8551 +(% class="text-left" %)
8552 +[[Feestelijke afsluiting, keuring materieel en tellen voorraden
8553 +(% class="date_info" %) Dec 14, 2023,>>path:/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden||class="thumbnail"]]
8554 +
8555 +(% class="row post-details" %)
8556 +(((
8557 +(% class="col-xs-8 detail" %)
8558 +(((
8559 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 1" %)
8560 +(((
8561 +[[(% class="like-number" %)1>>path:/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden||class="thumbnail"]]
8562 +)))
8563 +)))
8564 +
8565 +(% class="col-xs-4 com_det" %)
8566 +(((
8567 +(% class="text-right" %)
8568 +[[(0)>>path:/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden||class="thumbnail"]]
8569 +)))
8570 +)))
8571 +)))
8572 +)))
8573 +)))
8574 +
8575 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.RI&E 2023~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG|postIndex=3|previousPostReference=Nieuws.Nieuwsbrief december 2023|postIndex=4|previousPostReference=Nieuws.Nieuwsbrief november 2023|postIndex=5|previousPostReference=Nieuws.Feestelijke afsluiting, keuring materieel en tellen voorraden~"" %)
8576 +(((
8577 +(% class="macro-placeholder hidden" %)
8578 +(((
8579 +macro:blogPostLayoutCards
8580 +)))
8581 +
8582 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
8583 +(((
8584 +(% class="macro-placeholder hidden" %)
8585 +(((
8586 +macro:include
8587 +)))
8588 +
8589 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
8590 +(((
8591 +(% class="macro-placeholder hidden" %)
8592 +(((
8593 +macro:include
8594 +)))
8595 +
8596 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
8597 +#set($blogClassname = 'Blog.BlogClass')
8598 +#set($blogTemplate = 'Blog.BlogTemplate')
8599 +#set($blogSheet = 'Blog.BlogSheet')
8600 +## Blog entries
8601 +#set($blogPostClassname = 'Blog.BlogPostClass')
8602 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
8603 +#set($blogPostSheet = 'Blog.BlogPostSheet')
8604 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
8605 +#set($oldArticleClassname = 'XWiki.ArticleClass')
8606 +## Categories
8607 +#set($blogCategoryClassname = 'Blog.CategoryClass')
8608 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
8609 +#set($blogCategorySheet = 'Blog.CategorySheet')
8610 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
8611 +#set($oldBlogCategoryClassname = 'Blog.Categories')
8612 +#set($defaultCategoryParent = 'Blog.Categories')
8613 +## Style
8614 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
8615 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
8616 +## Clientside scripts
8617 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
8618 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
8619 +## Misc
8620 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
8621 +#set($isBlogPost = $doc.getObject($blogPostClassname))
8622 +#set($defaultBlogSpace = 'Blog')
8623 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
8624 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
8625 +##
8626 +##
8627 +##
8628 +#**
8629 + * Displays an image, taken from the blog style document.
8630 + *
8631 + * @param $imgName The name of the icon from icons set to use.
8632 + *#
8633 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
8634 +(((
8635 +(% class="macro-placeholder hidden" %)
8636 +(((
8637 +macro:velocity
8638 +)))
8639 +)))
8640 +)))
8641 +
8642 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
8643 +##
8644 +##
8645 +## Import the blog skin and javascripts.
8646 +$!xwiki.ssx.use($blogStyleDocumentName)##
8647 +$!xwiki.jsx.use($blogScriptsDocumentName)##
8648 +##
8649 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
8650 +#template('hierarchy_macros.vm')##
8651 +##
8652 +##
8653 +#**
8654 + * Prints a blog. This is the main macro used in the BlogSheet.
8655 + *
8656 + * @param blogDoc the XDocument holding the blog definition object.
8657 + *###
8658 +#macro(printBlog $blogDoc)
8659 + \{\{include reference='Blog.CreatePost'/}}
8660 +
8661 + ## Use the blogPostList macro to display the blogposts
8662 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
8663 + ## do not support FTM the monthly and weekly blog display types
8664 + #getBlogDisplayType($blogDoc $displayType)
8665 + #if ($displayType == 'weekly' || $displayType == 'monthly')
8666 + #getBlogEntries($blogDoc $entries)
8667 + #displayBlog($entries 'index' true true)
8668 + #displayNavigationLinks($blogDoc)
8669 + #else
8670 + #getBlogDisplayType($blogDoc $displayType)
8671 + #set ($paginated = 'no')
8672 + #if ($displayType == 'paginated')
8673 + #set ($paginated = 'yes')
8674 + #end
8675 + #getBlogPostsLayout($blogDoc $postsLayout)
8676 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
8677 + #end
8678 +#end
8679 +##
8680 +##
8681 +##
8682 +#**
8683 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
8684 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
8685 + * all entries).
8686 + *
8687 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
8688 + *###
8689 +#macro(showBlogInfo $blogDoc)
8690 + #if($blogDoc.getObject($blogClassname))
8691 + ## Keep testing for inline action for backward compatibility with older blogs.
8692 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
8693 + #macro(displayProperty $blogDoc $propname)
8694 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
8695 + : $blogDoc.display($propname)
8696 + #end
8697 + #displayProperty($blogDoc 'title')
8698 + #displayProperty($blogDoc 'description')
8699 + #displayProperty($blogDoc 'displayType')
8700 + #displayProperty($blogDoc 'itemsPerPage')
8701 + #displayProperty($blogDoc 'postsLayout')
8702 + #displayProperty($blogDoc 'postsLayoutParameters')
8703 + #else
8704 + $blogDoc.display('description')
8705 + #end
8706 + #elseif($doc.fullName == $blogSheet)
8707 += $services.localization.render('blog.code.blogsheet') =
8708 + \{\{translation key='blog.code.sheetexplanation'/}}
8709 + #else
8710 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
8711 + #end
8712 +#end
8713 +##
8714 +##
8715 +##
8716 +#**
8717 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
8718 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
8719 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
8720 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
8721 + *
8722 + * @param space A <tt>String</tt>, the name of the space where to search.
8723 + * @param blogDoc The resulting XDocument.
8724 + *###
8725 +#macro(getBlogDocument $space $blogDoc)
8726 + #set ($result = $NULL)
8727 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
8728 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
8729 + ## identify the right blog based on a configuration object in a WebPreferences page.
8730 + #set ($spaceReference = $services.model.resolveSpace($space))
8731 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
8732 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
8733 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
8734 + #if ($preferencesObj)
8735 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
8736 + #end
8737 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
8738 + #if (~"$!result~" == '')
8739 + ## First, try the Space.WebHome, for a whole-space blog
8740 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
8741 + #if(!$result.getObject($blogClassname))
8742 + ## Second, try the Space.Blog document
8743 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
8744 + #if(!$result.getObject($blogClassname))
8745 + ## Third, try searching for a blog document in the current space
8746 + ## Prevent the query fail when the space contains dots '.'
8747 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
8748 + #if($blogDocs.size() > 0)
8749 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
8750 + #else
8751 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
8752 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
8753 + #if($blogDocs.size() > 0)
8754 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
8755 + #else
8756 + ## Last, fallback to Blog.WebHome, the default blog
8757 + #set($result = $xwiki.getDocument('Blog.WebHome'))
8758 + #end
8759 + #end
8760 + #end
8761 + #end
8762 + #end
8763 + #set ($blogDoc = $NULL)
8764 + #setVariable (~"$blogDoc~" $result)
8765 +#end
8766 +##
8767 +##
8768 +##
8769 +#**
8770 + * Retrieve the blog title.
8771 + *
8772 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
8773 + * @param title The resulting title.
8774 + *###
8775 +#macro(getBlogTitle $blogDoc $title)
8776 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
8777 + #set ($title = $NULL)
8778 + #setVariable (~"$title~" $!blogDoc.displayTitle)
8779 +#end
8780 +##
8781 +##
8782 +##
8783 +#**
8784 + * Retrieve the blog description.
8785 + *
8786 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
8787 + * property set.
8788 + * @param description The resulting description.
8789 + *###
8790 +#macro(getBlogDescription $blogDoc $description)
8791 + #getBlogProperty($blogDoc 'description' '' $result)
8792 + #set ($description = $NULL)
8793 + #setVariable (~"$description~" $result)
8794 +#end
8795 +##
8796 +##
8797 +##
8798 +#**
8799 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
8800 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
8801 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
8802 + * month), or all.
8803 + *
8804 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
8805 + * @param entries The resulting list of entries to display, a list of XDocument names.
8806 + *###
8807 +#macro(getBlogEntries $blogDoc $entries)
8808 + #if (!$entries)
8809 + #setVariable (~"$entries~" [])
8810 + #end
8811 + #getAllBlogPostsQuery($query)
8812 + #isDefaultBlog($blogDoc $isDefault)
8813 + #set($queryParams = \{})
8814 + #if ($isDefault)
8815 + #getCategoryAllBlogPostsQuery($query)
8816 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
8817 + #set($discard = $queryParams.put('creator', $xcontext.user))
8818 + #set($discard = $queryParams.put('space', $blogDoc.space))
8819 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
8820 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
8821 + #else
8822 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
8823 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
8824 + #set($discard = $queryParams.put('space', $blogPostsLocation))
8825 + #set($discard = $queryParams.put('parent', $blogDoc.space))
8826 + #end
8827 + #getBlogDisplayType($blogDoc $displayType)
8828 + #if($displayType == 'weekly')
8829 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
8830 + #elseif($displayType == 'monthly')
8831 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
8832 + #elseif($displayType == 'all')
8833 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
8834 + #else
8835 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
8836 + #end
8837 +#end
8838 +##
8839 +##
8840 +##
8841 +#**
8842 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
8843 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
8844 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
8845 + * (10 if not defined).
8846 + *
8847 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
8848 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
8849 + * refined to restrict to a given space, or to a given search criteria, etc.
8850 + * @param entries The resulting list of entries to display, a list of XDocument names.
8851 + * @param queryParams The parameters to bind with the query.
8852 + *###
8853 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
8854 + #if (!$entries)
8855 + #setVariable (~"$entries~" [])
8856 + #end
8857 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
8858 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
8859 + #bindQueryParameters($countQueryObj $queryParams)
8860 + #bindQueryParameters($queryObj $queryParams)
8861 + #set($totalEntries = $countQueryObj.count())
8862 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
8863 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
8864 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
8865 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
8866 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
8867 +#end
8868 +##
8869 +##
8870 +##
8871 +#**
8872 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
8873 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
8874 + * digit year). Initially the current week is displayed.
8875 + *
8876 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
8877 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
8878 + * refined to restrict to a given space, or to a given search criteria, etc.
8879 + * @param entries The resulting list of entries to display, a list of XDocument names.
8880 + * @param queryParams The parameters to bind with the query.
8881 + *###
8882 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
8883 + #if (!$entries)
8884 + #setVariable (~"$entries~" [])
8885 + #end
8886 + #getRequestedWeek($weekDate)
8887 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
8888 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
8889 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
8890 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
8891 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
8892 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
8893 + #bindQueryParameters($countQueryObj $queryParams)
8894 + #bindQueryParameters($queryObj $queryParams)
8895 + #set($totalEntries = $countQueryObj.count())
8896 + #set($discard = $entries.addAll($queryObj.execute()))
8897 +#end
8898 +##
8899 +##
8900 +##
8901 +#**
8902 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
8903 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
8904 + * digit year). Initially the current month is displayed.
8905 + *
8906 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
8907 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
8908 + * refined to restrict to a given space, or to a given search criteria, etc.
8909 + * @param entries The resulting list of entries to display, a list of XDocument names.
8910 + * @param queryParams The parameters to bind with the query.
8911 + *###
8912 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
8913 + #if (!$entries)
8914 + #setVariable (~"$entries~" [])
8915 + #end
8916 + #getRequestedMonth($monthDate)
8917 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
8918 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
8919 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
8920 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
8921 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
8922 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
8923 + #bindQueryParameters($countQueryObj $queryParams)
8924 + #bindQueryParameters($queryObj $queryParams)
8925 + #set($totalEntries = $countQueryObj.count())
8926 + #set($discard = $entries.addAll($queryObj.execute()))
8927 +#end
8928 +##
8929 +##
8930 +##
8931 +#**
8932 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
8933 + *
8934 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
8935 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
8936 + * refined to restrict to a given space, or to a given search criteria, etc.
8937 + * @param entries The resulting list of entries to display, a list of XDocument names.
8938 + * @param queryParams The parameters to bind with the query.
8939 + *###
8940 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
8941 + #if (!$entries)
8942 + #setVariable (~"$entries~" [])
8943 + #end
8944 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
8945 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
8946 + #bindQueryParameters($countQueryObj $queryParams)
8947 + #bindQueryParameters($queryObj $queryParams)
8948 + #set($totalEntries = $countQueryObj.count())
8949 + #set($discard = $entries.addAll($queryObj.execute()))
8950 +#end
8951 +##
8952 +##
8953 +##
8954 +#**
8955 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
8956 + *
8957 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
8958 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
8959 + * refined to restrict to a given space, or to a given search criteria, etc.
8960 + * @param queryParams The parameters to bind with the query.
8961 + * @param entries The resulting list of entries to display, a list of XDocument names.
8962 + *###
8963 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
8964 + #if (!$entries)
8965 + #setVariable (~"$entries~" [])
8966 + #end
8967 + #set($query = ~"$\{query} and isPublished.value = 0~")
8968 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
8969 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
8970 + #bindQueryParameters($countQueryObj $queryParams)
8971 + #bindQueryParameters($queryObj $queryParams)
8972 + #set($totalEntries = $countQueryObj.count())
8973 + #set($discard = $entries.addAll($queryObj.execute()))
8974 +#end
8975 +##
8976 +##
8977 +##
8978 +#**
8979 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
8980 + *
8981 + * @param entries The resulting list of entries to display, a list of XDocument names.
8982 + *###
8983 +#macro(getGlobalBlogEntries $entries)
8984 + #if (!$entries)
8985 + #setVariable (~"$entries~" [])
8986 + #end
8987 + #getAllBlogPostsQuery($query)
8988 + #set($totalEntries = $services.query.hql($query).count())
8989 + #set($defaultItemsPerPage = 20)
8990 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
8991 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
8992 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
8993 +#end
8994 +#**
8995 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
8996 + * blog, nor specify a range or an ordering criteria.
8997 + *
8998 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
8999 + *
9000 + * @param query The basic query for selecting blog entries.
9001 + *#
9002 +#macro(getBlogEntriesBaseQuery $query)
9003 + #getAllBlogPostsQuery($query)
9004 +#end
9005 +#**
9006 + * Return the Query for selecting the all wiki blog posts without filtering
9007 + *
9008 + * @param query The basic query for selecting blog entries.
9009 + *#
9010 +#macro(getAllBlogPostsQuery $query)
9011 + #set ($query = $NULL)
9012 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
9013 + IntegerProperty hidden, DateProperty publishDate
9014 + where doc.fullName <> '$blogPostTemplate' and
9015 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
9016 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
9017 + hidden.id.id = obj.id and hidden.id.name='hidden' and
9018 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
9019 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
9020 +#end
9021 +##
9022 +##
9023 +##
9024 +###**
9025 + * Return the Query for selecting the all wiki blog posts with categories filtering
9026 + *
9027 + * @param query The basic query for selecting blog entries.
9028 + *###
9029 +#macro(getCategoryAllBlogPostsQuery $query)
9030 + #set ($query = $NULL)
9031 + #getAllBlogPostsQuery($baseQuery)
9032 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
9033 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
9034 +#end
9035 +##
9036 +##
9037 +##
9038 +#**
9039 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
9040 + * week), monthly (all entries in a month), or all.
9041 + *
9042 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
9043 + * property set.
9044 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
9045 + *###
9046 +#macro(getBlogDisplayType $blogDoc $displayType)
9047 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
9048 + #set ($displayType = $NULL)
9049 + #setVariable (~"$displayType~" $result)
9050 +#end
9051 +##
9052 +##
9053 +##
9054 +#**
9055 + * Displays a list of entries.
9056 + *
9057 + * @param entries The entries to display, a list of XDocument names.
9058 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
9059 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
9060 + * used values: index, single, category, search, unpublished, hidden.
9061 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
9062 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
9063 + * displayed alone on their page since it's the page title which is used in this case)
9064 + *###
9065 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
9066 + #set($blogDay = '')
9067 + (% class=~"hfeed $!\{displaying}~" ~%)(((
9068 + (% class=~"blogDay~" ~%)(((
9069 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
9070 + #getEntryObject($entryDoc $entryObj)
9071 + ## Although all entries should have one of the two objects, better check to be sure.
9072 + #if(~"$!\{entryObj}~" != '')
9073 + #getEntryDate($entryDoc $entryObj $entryDate)
9074 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
9075 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
9076 + #if($blogDay != $entryDateStr)
9077 + #if($blogDay != '')
9078 + )))
9079 + (% class=~"blogDay~" ~%)(((
9080 + #end
9081 + #displayBlogDate($entryDate)
9082 + #set ($blogDay = $entryDateStr)
9083 + #end
9084 + ## Finally, display the entry.
9085 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
9086 + #end
9087 + #end
9088 + )))## blogDay
9089 + )))## hfeed
9090 +#end
9091 +##
9092 +##
9093 +##
9094 +#**
9095 + * Get the entry object, either a new BlogPost or an old Article.
9096 + *
9097 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9098 + * @param entryObj The resulting xobject of the blog post.
9099 + *###
9100 +#macro(getEntryObject $entryDoc $__entryObj)
9101 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
9102 + #if(!$result)
9103 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
9104 + #end
9105 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
9106 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
9107 + ## overwritten in this case but it's less likely to have such a variable defined before.
9108 + #set ($__entryObj = $NULL)
9109 + #setVariable (~"$__entryObj~" $result)
9110 +#end
9111 +##
9112 +##
9113 +##
9114 +#**
9115 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
9116 + * the document creation date, but can be edited by the user.
9117 + *
9118 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9119 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9120 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
9121 + *###
9122 +#macro(getEntryDate $entryDoc $entryObj $result)
9123 + #set ($result = $NULL)
9124 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
9125 +#end
9126 +##
9127 +##
9128 +##
9129 +#**
9130 + * Displays a date, nicely formatted as a calendar page.
9131 + *
9132 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
9133 + *###
9134 +#macro(displayBlogDate $date)
9135 + #set($year = $xwiki.formatDate($date, 'yyyy'))
9136 + ## 3 letter month name, like Jan, Dec.
9137 + #set($month = $xwiki.formatDate($date, 'MMM'))
9138 + ## Uncomment to get a full length month name, like January, December.
9139 + ## TODO: this could be defined somewhere in the blog style.
9140 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
9141 + #set($day = $xwiki.formatDate($date, 'dd'))
9142 + (% class=~"blogdate~" ~%)
9143 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
9144 +#end
9145 +##
9146 +##
9147 +##
9148 +#**
9149 + * Displays a blog article: management tools, header, content, footer.
9150 + *
9151 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9152 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9153 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
9154 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
9155 + * when they're displayed alone on their page since it's the page title which is used in this case)
9156 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
9157 + *###
9158 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
9159 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
9160 + #isPublished($entryObj $isPublished)
9161 + #isHidden($entryObj $isHidden)
9162 + #if($doc.fullName == $entryDoc.fullName)
9163 + (% class=~"hentry single-article~" ~%)(((
9164 + #else
9165 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
9166 + #end
9167 + #if ($shouldDisplayActions)
9168 + #displayEntryTools($entryDoc $entryObj)
9169 + #end
9170 + #if($shouldDisplayTitle)
9171 + #displayEntryTitle($entryDoc $entryObj)
9172 + #end
9173 + #if($doc.fullName == $entryDoc.fullName)
9174 + #if(!$isPublished)
9175 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
9176 + #elseif($isHidden)
9177 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
9178 + #end
9179 + #end
9180 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
9181 + #displayEntryFooter($entryDoc $entryObj)
9182 + )))## hentry
9183 +#end
9184 +##
9185 +##
9186 +##
9187 +#**
9188 + * Checks if the provided blog is published or not.
9189 + *
9190 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9191 + * @param isPublished The resulting boolean, true if the entry is considered published.
9192 + *###
9193 +#macro(isPublished $entryObj $isPublished)
9194 + #set ($isPublished = $NULL)
9195 + ## This should work for both old articles, which don't have the 'published' property at all, and
9196 + ## are considered published by default, and new entries, that should have 1 if published.
9197 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
9198 + #setVariable (~"$isPublished~" true)
9199 + #else
9200 + #setVariable (~"$isPublished~" false)
9201 + #end
9202 +#end
9203 +##
9204 +##
9205 +##
9206 +#**
9207 + * Checks if the provided blog is hidden or not.
9208 + *
9209 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
9210 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
9211 + *###
9212 +#macro(isHidden $entryObj $isHidden)
9213 + #set ($isHidden = $NULL)
9214 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
9215 + ## are considered visible by default, and new entries, that should have 1 if hidden.
9216 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
9217 + #setVariable (~"$isHidden~" true)
9218 + #else
9219 + #setVariable (~"$isHidden~" false)
9220 + #end
9221 +#end
9222 +##
9223 +##
9224 +##
9225 +#**
9226 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
9227 + *
9228 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9229 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9230 + *###
9231 +#macro(displayEntryTools $entryDoc $entryObj)
9232 + #if($xcontext.action == 'view')
9233 + (% class=~"blog-entry-toolbox~" ~%)(((
9234 + #displayPublishButton($entryDoc $entryObj)
9235 + #displayHideShowButton($entryDoc $entryObj)
9236 + #displayEditButton($entryDoc $entryObj)
9237 + #displayDeleteButton($entryDoc $entryObj)
9238 + )))
9239 + #end
9240 +#end
9241 +##
9242 +##
9243 +##
9244 +#**
9245 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
9246 + *
9247 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9248 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9249 + * @todo AJAX calls.
9250 + *###
9251 +#macro(displayPublishButton $entryDoc $entryObj)
9252 + #isPublished($entryObj $isPublished)
9253 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
9254 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
9255 + #end
9256 +#end
9257 +##
9258 +##
9259 +##
9260 +#**
9261 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
9262 + *
9263 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9264 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9265 + *###
9266 +#macro(displayHideShowButton $entryDoc $entryObj)
9267 + #isPublished($entryObj $isPublished)
9268 + #isHidden($entryObj $isHidden)
9269 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
9270 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
9271 + #set ($queryString = \{
9272 + 'xredirect' : $thisURL,
9273 + 'form_token' : $services.csrf.getToken()
9274 + })
9275 + #if ($isHidden)
9276 + #set ($discard = $queryString.putAll(\{
9277 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
9278 + 'comment' : $services.localization.render('blog.code.madevisible')
9279 + }))
9280 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
9281 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
9282 + #else
9283 + #set ($discard = $queryString.putAll(\{
9284 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
9285 + 'comment' : $services.localization.render('blog.code.hid')
9286 + }))
9287 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
9288 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
9289 + #end
9290 + #end
9291 +#end
9292 +##
9293 +##
9294 +##
9295 +#**
9296 + * Displays the edit button to those that can edit the article.
9297 + *
9298 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9299 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9300 + *###
9301 +#macro(displayEditButton $entryDoc $entryObj)
9302 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
9303 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
9304 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
9305 + #end
9306 +#end
9307 +##
9308 +##
9309 +##
9310 +#**
9311 + * Displays the delete button to those that can edit the article.
9312 + *
9313 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9314 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9315 + * @todo AJAX calls.
9316 + *###
9317 +#macro(displayDeleteButton $entryDoc $entryObj)
9318 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
9319 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
9320 + #end
9321 +#end
9322 +##
9323 +##
9324 +##
9325 +#**
9326 + * Displays the title of the entry.
9327 + *
9328 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9329 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9330 + *###
9331 +#macro(displayEntryTitle $entryDoc $entryObj)
9332 + #if($doc.fullName == $entryDoc.fullName)
9333 + (% class=~"entry-title~" ~%)
9334 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
9335 + #else
9336 + (% class=~"entry-title~" ~%)
9337 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
9338 + #end
9339 +#end
9340 +##
9341 +##
9342 +##
9343 +#**
9344 + * Displays the body of the entry.
9345 + *
9346 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9347 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9348 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
9349 + *###
9350 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
9351 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
9352 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
9353 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
9354 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
9355 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
9356 + ))) ## entry-content
9357 + (% class=~"clearfloats~" ~%)((()))
9358 +#end
9359 +##
9360 +##
9361 +##
9362 +#**
9363 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
9364 + * of the <tt>extract</tt> field (if not empty).
9365 + *
9366 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9367 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9368 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
9369 + * @param entryContent The resulting content.
9370 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
9371 + * <tt>onlyExtract</tt> is <tt>true</tt>)
9372 + *###
9373 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
9374 + #if ($onlyExtract)
9375 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
9376 + ## of the content.
9377 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
9378 + #end
9379 + #if(~"$!macro.result~" == '')
9380 + #set($macro.result = $entryObj.getProperty('content').value)
9381 +#* Disabled until the content can be cleanly cut.
9382 +* #if($onlyExtract && $result.length()>$maxchars)
9383 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
9384 +* #set($i = $i + 1)
9385 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
9386 +* #end
9387 +## *###
9388 + #elseif (!$removeEllipsis)
9389 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
9390 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
9391 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
9392 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
9393 + #end
9394 + #end
9395 + #set ($entryContent = $NULL)
9396 + #setVariable (~"$entryContent~" $macro.result)
9397 +#end
9398 +##
9399 +##
9400 +##
9401 +#**
9402 + * Displays the footer of the entry.
9403 + *
9404 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9405 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9406 + *###
9407 +#macro(displayEntryFooter $entryDoc $entryObj)
9408 + (% class=~"entry-footer~" ~%)(((
9409 + #isPublished($entryObj $isPublished)
9410 + (% class='entry-author-label' ~%)
9411 + #if($isPublished)
9412 + \{\{translation key='blog.code.postedby'/}} ##
9413 + #else
9414 + \{\{translation key='blog.code.createdby'/}} ##
9415 + #end
9416 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
9417 + #getEntryDate($entryDoc $entryObj $entryDate)
9418 + #listCategories($entryObj) #*
9419 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
9420 + ## we assume cannot be more than 3 seconds.
9421 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
9422 + #if ($showcomments)
9423 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
9424 + #end ##
9425 + #if($entryDoc != $doc) ##
9426 + #displayEntryBlogLocation($entryDoc $entryObj) ##
9427 + #end
9428 + )))## entry-footer
9429 +#end
9430 +##
9431 +##
9432 +#**
9433 + * Display the blog for the entry (if it is not the currently displayed blog)
9434 + *
9435 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
9436 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9437 + *###
9438 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
9439 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
9440 + #if(~"$!blogPostsLocation~" != ~"~") ##
9441 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
9442 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
9443 + #if($doc.documentReference != $blogDocRef) ##
9444 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
9445 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
9446 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
9447 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
9448 + )))(%~%)##
9449 + #end
9450 + #end
9451 + #end
9452 +#end
9453 +##
9454 +##
9455 +##
9456 +##
9457 +#**
9458 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
9459 + *
9460 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
9461 + *###
9462 +#macro(listCategories $entryObj)
9463 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
9464 + #set($categories = $entryObj.getProperty('category').value)
9465 + #set($first = true)
9466 + #if($categories.size() > 0)
9467 + #foreach($category in $categories)
9468 + #set($categoryDoc = $!xwiki.getDocument($category))
9469 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
9470 + #if($foreach.count == 1)
9471 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
9472 + #else
9473 + , ##
9474 + #end##
9475 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
9476 + #end##
9477 + #end##
9478 + #end
9479 + #end
9480 +#end
9481 +##
9482 +##
9483 +##
9484 +#**
9485 + * Displays blog pagination links (older and newer entries).
9486 + *
9487 + * @param blogDoc the XDocument holding the blog definition object.
9488 + *###
9489 +#macro(displayNavigationLinks $blogDoc)
9490 + (% class=~"clearfloats~" ~%)((()))
9491 + #getBlogDisplayType($blogDoc $displayType)
9492 + #if($displayType == 'weekly')
9493 + (% class=~"pagingLinks~" ~%)(((
9494 + #getRequestedWeek($weekDate)
9495 + $weekDate.addWeeks(-1)##
9496 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
9497 + #sep()
9498 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
9499 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
9500 + )))
9501 + #elseif($displayType == 'monthly')
9502 + (% class=~"pagingLinks~" ~%)(((
9503 + #getRequestedMonth($monthDate)
9504 + $monthDate.addMonths(-1)##
9505 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
9506 + #sep()
9507 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
9508 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
9509 + )))
9510 + #elseif($displayType == 'all')
9511 + #else
9512 + ## Paginated
9513 + #if(($totalPages > 1))
9514 + #set($queryString = '')
9515 + #foreach($p in $request.getParameterNames())
9516 + #if($p != 'page' && $p != 'ipp')
9517 + #foreach($v in $request.getParameterValues($p))
9518 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
9519 + #end
9520 + #end
9521 + #end
9522 + (% class=~"pagingLinks~" ~%)(((
9523 + #if ($currentPageNumber < $totalPages)
9524 + #set($currentPageNumber = $currentPageNumber + 1)
9525 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
9526 + #set($currentPageNumber = $currentPageNumber - 1)
9527 + #end
9528 + #if ($currentPageNumber > 1)
9529 + #if ($currentPageNumber < $totalPages)
9530 + #sep()
9531 + #end
9532 + #set($currentPageNumber = $currentPageNumber - 1)
9533 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
9534 + #set($currentPageNumber = $currentPageNumber + 1)
9535 + #end
9536 + (% class=~"clear~" ~%)(%~%)
9537 + )))## pagingLinks
9538 + #end
9539 + #end
9540 +#end
9541 +##
9542 +##
9543 +##
9544 +#**
9545 + * Displays a message box with ~"publish~" icon.
9546 + *
9547 + * @param message A text message concerning blog article publishing
9548 + *###
9549 +#macro(publishMessageBox $message)
9550 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
9551 +#end
9552 +#**
9553 + * Displays a message box with ~"show/hide~" icon.
9554 + *
9555 + * @param message A text message concerning blog article hiding
9556 + *###
9557 +#macro(hideMessageBox $message)
9558 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
9559 +#end
9560 +##
9561 +##
9562 +##
9563 +#**
9564 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
9565 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
9566 + *
9567 + * @param monthDate The resulting week, a JODATime MutableDateTime.
9568 + *###
9569 +#macro(getRequestedWeek $weekDate)
9570 + #set ($weekDate = $NULL)
9571 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
9572 + #if(~"$!\{request.year}~" != '')
9573 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
9574 + #end
9575 + #if(~"$!\{request.week}~" != '')
9576 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
9577 + #end
9578 +#end
9579 +##
9580 +##
9581 +##
9582 +#**
9583 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
9584 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
9585 + *
9586 + * @param monthDate The resulting month, a JODATime MutableDateTime.
9587 + *###
9588 +#macro(getRequestedMonth $monthDate)
9589 + #set ($monthDate = $NULL)
9590 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
9591 + #if(~"$!\{request.year}~" != '')
9592 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
9593 + #end
9594 + #if(~"$!\{request.month}~" != '')
9595 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
9596 + #end
9597 +#end
9598 +##
9599 +##
9600 +##
9601 +#**
9602 + * Retrieve a blog property (title, display type, etc).
9603 + *
9604 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
9605 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
9606 + * @param defaultValue The default value to use in case the blog object does not define one.
9607 + * @param propertyValue The resulting value.
9608 + *###
9609 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
9610 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
9611 + #if($result == '')
9612 + #set($result = $defaultValue)
9613 + #end
9614 + #set ($propertyValue = $NULL)
9615 + #setVariable (~"$propertyValue~" $result)
9616 +#end
9617 +
9618 +#**
9619 + * If an error occurs when executing an action, set a specific response status and display an error message.
9620 + *
9621 + * @param status The response status.
9622 + * @param text The user readable error to be displayed. Can be a translation key.
9623 + * @param parameters The parameters to use when decoding the translation key.
9624 + *###
9625 +#macro(blog__actionResponseError $status $text $parameters)
9626 + $response.setStatus($status)
9627 + #if($request.ajax)
9628 + $services.localization.render($text, $!parameters)
9629 + #else
9630 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
9631 + #end
9632 +#end
9633 +##
9634 +##
9635 +##
9636 +#**
9637 + * Check if a blog is the Default blog (The one in the 'Blog' space).
9638 + *
9639 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
9640 + * @param isDefault The resulting boolean.
9641 + *###
9642 +#macro(isDefaultBlog $blogDoc $isDefault)
9643 + #set ($result = false)
9644 + #if ($blogDoc.space == 'Blog')
9645 + #set ($result = true)
9646 + #end
9647 + #setVariable(~"$isDefault~" $result)
9648 +#end
9649 +##
9650 +##
9651 +##
9652 +#**
9653 + * Retrieve the blog posts location (space).
9654 + *
9655 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
9656 + * @param postsLocation The resulting location.
9657 + *###
9658 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
9659 + #getBlogDocument($blogSpace $blogDoc)
9660 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
9661 + #set ($postsLocation = $NULL)
9662 + #setVariable (~"$postsLocation~" $result)
9663 +#end
9664 +##
9665 +##
9666 +##
9667 +#**
9668 + * Retrieve the blog categories location (space).
9669 + *
9670 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
9671 + * @param categoriesLocation The resulting location.
9672 + *###
9673 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
9674 + #getBlogDocument($blogSpace $blogDoc)
9675 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
9676 + #set ($postsLocation = $NULL)
9677 + #setVariable (~"$categoriesLocation~" $result)
9678 +#end
9679 +###**
9680 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
9681 + * for example there is 4 different panel contexts:
9682 + * aBlog.aPost or aBlog.WebHome
9683 + * aCategorySpace.aCategory
9684 + * aCategorySpace.WebHome
9685 + * Blog.aPost or Blog.WebHome
9686 + *
9687 + * @param query The query for selecting blog entries.
9688 + * @param queryParams The parameters to bind with the generated query.
9689 + * @param targetDoc The document in which the articles will be displayed.
9690 + *###
9691 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
9692 + #set ($query = $NULL)
9693 + #set ($queryParams = $NULL)
9694 + #getCategoryAllBlogPostsQuery($resultQuery)
9695 + #set ($resultQueryParams = \{})
9696 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
9697 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
9698 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
9699 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
9700 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
9701 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
9702 + #elseif($targetDoc.getObject($blogCategoryClassname))
9703 + ## Get all posts that are in a category aCategorySpace.aCategory
9704 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
9705 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
9706 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
9707 + ## Get all posts that are in a category aCategorySpace.%
9708 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
9709 + ## Exclude incategorized posts
9710 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
9711 + #if ($targetDoc.space == $defaultBlogSpace)
9712 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
9713 + #end
9714 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
9715 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
9716 + #else
9717 + ## Get all posts in blog space aBlog
9718 + #getAllBlogPostsQuery($resultQuery)
9719 + #getBlogPostsLocation($targetDoc.space $postsLocation)
9720 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
9721 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
9722 + #end
9723 + #setVariable(~"$query~" $resultQuery)
9724 + #setVariable(~"$queryParams~" $resultQueryParams)
9725 +#end
9726 +##
9727 +##
9728 +##
9729 +###**
9730 + * Display blog posts based on the context where the posts are displayed.
9731 + * for example there is 4 different panel contexts:
9732 + * aBlog.aPost or aBlog.WebHome
9733 + * aCategorySpace.aCategory
9734 + * aCategorySpace.WebHome
9735 + * Blog.aPost or Blog.WebHome
9736 + *
9737 + * @param targetDoc The document in which the articles will be displayed.
9738 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
9739 + * @param layout Layout of the the posts to display
9740 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
9741 + * @param limit the number of posts to display
9742 + *###
9743 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
9744 + #if ($postLayout == 'full')
9745 + #set ($macro.paginated = 'yes')
9746 + #end
9747 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
9748 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
9749 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
9750 + #if (~"$!layout~" == '')
9751 + #set ($layout = $postsLayout)
9752 + #end
9753 + #if ($postsVisiblity == 'recent')
9754 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
9755 + #elseif($postsVisiblity == 'unpublished')
9756 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
9757 + #end
9758 + #elseif($targetDoc.getObject($blogCategoryClassname))
9759 + ## Display all posts that are in a category aCategorySpace.aCategory
9760 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
9761 + #getBlogPostsLayout($blogDoc $postsLayout)
9762 + #if (~"$!layout~" == '')
9763 + #set ($layout = $postsLayout)
9764 + #end
9765 + #if ($postsVisiblity == 'recent')
9766 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
9767 + #elseif($postsVisiblity == 'unpublished')
9768 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
9769 + #end
9770 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
9771 + ## Display all posts that are in a category aCategorySpace.%
9772 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
9773 + #getBlogPostsLayout($blogDoc $postsLayout)
9774 + #if (~"$!layout~" == '')
9775 + #set ($layout = $postsLayout)
9776 + #end
9777 + #if ($postsVisiblity == 'recent')
9778 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
9779 + #elseif($postsVisiblity == 'unpublished')
9780 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
9781 + #end
9782 + #else
9783 + ## Display all posts in blog space aBlog
9784 + #getBlogDocument($targetDoc.space $blogDoc)
9785 + #getBlogPostsLayout($blogDoc $postsLayout)
9786 + #if (~"$!layout~" == '')
9787 + #set ($layout = $postsLayout)
9788 + #end
9789 + #if ($postsVisiblity == 'recent')
9790 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
9791 + #elseif($postsVisiblity == 'unpublished')
9792 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
9793 + #end
9794 + #end
9795 +#end
9796 +##
9797 +##
9798 +##
9799 +#**
9800 + * Bind parameters to a query object.
9801 + *
9802 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
9803 + * @param queryParams the query parameters.
9804 + *###
9805 +#macro(bindQueryParameters $queryObj $queryParams)
9806 + #set ($output = $queryObj)
9807 + #foreach( $key in $queryParams.keySet() )
9808 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
9809 + #end
9810 + #setVariable(~"$queryObj~" $output)
9811 +#end
9812 +##
9813 +##
9814 +##
9815 +#**
9816 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
9817 + *
9818 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
9819 + * property set.
9820 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
9821 + *###
9822 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
9823 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
9824 + #set ($postsLayout = $NULL)
9825 + #setVariable (~"$postsLayout~" $res)
9826 +#end
9827 +##
9828 +##
9829 +##
9830 +#**
9831 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
9832 + *
9833 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
9834 + * @param blogDoc The resulting XDocument.
9835 + *###
9836 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
9837 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
9838 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
9839 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
9840 + #else
9841 + ## Fallback to Blog.WebHome, the default blog
9842 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
9843 + #end
9844 + #set ($blogDoc = $NULL)
9845 + #setVariable (~"$blogDoc~" $macro.result)
9846 +#end" %)
9847 +(((
9848 +(% class="macro-placeholder hidden" %)
9849 +(((
9850 +macro:velocity
9851 +)))
9852 +)))
9853 +)))
9854 +
9855 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
9856 +(((
9857 +(% class="macro-placeholder hidden" %)
9858 +(((
9859 +macro:include
9860 +)))
9861 +
9862 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
9863 + * Extract the layout parameters from a string.
9864 + *
9865 + * @param layoutParamsString The string representation of the layout parameters.
9866 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
9867 + * @param layoutsParameters The resulting layout parameters Map.
9868 + *###
9869 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
9870 + #set ($layoutsParameters = $NULL)
9871 + #set ($macro.layoutParams = \{})
9872 + #if (~"$!layoutParamsString~" != '')
9873 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
9874 + #foreach ($item in $macro.paramsArr)
9875 + #set ($itemSplit = $item.split('='))
9876 + #if ($itemSplit.size() == 2)
9877 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
9878 + #end
9879 + #end
9880 + #end
9881 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
9882 +#end" %)
9883 +(((
9884 +(% class="macro-placeholder hidden" %)
9885 +(((
9886 +macro:velocity
9887 +)))
9888 +)))
9889 +)))
9890 +
9891 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
9892 + #initLayoutVars($pDoc $pObj)
9893 + <div class=~"col-xs-12 col-sm-6 next_blog~">
9894 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
9895 + <div class=~"row~">
9896 + <div class=~"col-xs-4~">
9897 + #if ($imageAtt)
9898 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
9899 + #end
9900 + </div>
9901 + <div class=~"col-xs-8 art_det~">
9902 + <p class=~"text-left~">
9903 + #if($displayTitle)$!postTitle #end
9904 + <br/><span class=~"date_info~"> $!dateStr </span>
9905 + </p>
9906 + #displayPostDetails($pDoc)
9907 + </div>
9908 + </div>
9909 + </a>
9910 + </div>
9911 + #end
9912 + ##
9913 + ##
9914 + ##
9915 + #macro(displayPinnedPost $pDoc $pObj)
9916 + #initLayoutVars($pDoc $pObj)
9917 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
9918 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
9919 + <div class=~"thumbnail~">
9920 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
9921 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
9922 + #end
9923 + #if ($imageAtt)
9924 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
9925 + #end
9926 + <div class=~"caption~">
9927 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
9928 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
9929 + #end
9930 + #if ($displaySummaryOnPinnedPosts)
9931 + <div class=~"text-left post-summary~">
9932 + #set ($postContent = $pObj.getProperty('extract').value)
9933 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
9934 + </div>
9935 + #end
9936 + #displayPostDetails($pDoc)
9937 + </div>
9938 + </div>
9939 + </a>
9940 + </div>
9941 + #end
9942 + ##
9943 + ##
9944 + ##
9945 + #macro(formatPostDate $pDoc $pObj)
9946 + #set ($formattedDate = $NULL)
9947 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
9948 + #if (~"$!dateStr~" != '')
9949 + #set ($dateArr = $dateStr.split(' '))
9950 + #if ($dateArr.size() > 3)
9951 + #set ($dateStr = ~"~")
9952 + #foreach($s in $dateArr.subList(0, 3))
9953 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
9954 + #end
9955 + #end
9956 + #end
9957 + #setVariable(~"$formattedDate~" $dateStr)
9958 + #end
9959 + ##
9960 + ##
9961 + ##
9962 + #macro(displayPostDetails $pDoc)
9963 + <div class=~"row post-details~">
9964 + <div class=~"col-xs-8 detail~">
9965 + #if ($services.like.displayButton($pDoc.documentReference))
9966 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
9967 + ## Retrieve the likes number in XWiki 12.9+
9968 + #set ($likeNumber = $optLikeRecord.get())
9969 + #if (!$stringtool.isNumeric($likeNumber.toString()))
9970 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
9971 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
9972 + #end
9973 + #if ($stringtool.isNumeric($likeNumber.toString()))
9974 + <div class=~"post-likes btn btn-default disabled badge~"
9975 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
9976 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
9977 + </div>
9978 + #end
9979 + #elseif ($services.ratings)
9980 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
9981 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
9982 + <ul class=~"pull-left note list-inline~">
9983 + #foreach ($x in [1..5])
9984 + #set ($cls = ~"~")
9985 + #if ($x > $averageVote)
9986 + #set ($cls = ~"-o~")
9987 + #end
9988 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
9989 + #end
9990 + </ul>
9991 + #end
9992 + #end
9993 + </div>
9994 + #if ($showPostComments)
9995 + <div class=~"col-xs-4 com_det~">
9996 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
9997 + </div>
9998 + #end
9999 + </div>
10000 + #end
10001 + ##
10002 + ##
10003 + ##
10004 + #macro(initLayoutVars $pDoc $pObj)
10005 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
10006 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
10007 + #isPublished($pObj $isPublished)
10008 + #isHidden($pObj $isHidden)
10009 + #getEntryDate($pDoc $pObj $postDate)
10010 + #formatPostDate($postDate $dateStr)
10011 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
10012 + #set ($nbComments = $pDoc.getComments().size())
10013 + #set ($showPostComments = true)
10014 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
10015 + #set ($showPostComments = false)
10016 + #end
10017 + #end
10018 + ##
10019 + ##
10020 + ##
10021 + #macro(displayEditPinnedPostsButton)
10022 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
10023 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
10024 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
10025 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
10026 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
10027 + <div class=~"edit-pinned-posts-container~">
10028 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
10029 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
10030 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
10031 + </a>
10032 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
10033 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
10034 + </div>
10035 + </div>
10036 + #if (~"$!pinnedPostsObj~" == '')
10037 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
10038 + #end
10039 + #end
10040 + #end" %)
10041 +(((
10042 +(% class="macro-placeholder hidden" %)
10043 +(((
10044 +macro:velocity
10045 +)))
10046 +)))
10047 +
10048 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
10049 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
10050 + #getEntryObject($postDoc $postObj)
10051 + #if (~"$!postObj~" != '')
10052 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
10053 + ##
10054 + #set ($displayTitle = true)
10055 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
10056 + #set ($displayTitle = false)
10057 + #end
10058 + ##
10059 + #set ($displayTitleFirstOnPinnedPosts = false)
10060 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
10061 + #set ($displayTitleFirstOnPinnedPosts = true)
10062 + #end
10063 + ##
10064 + #set ($displaySummaryOnPinnedPosts = true)
10065 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
10066 + #set ($displaySummaryOnPinnedPosts = false)
10067 + #end
10068 + ##
10069 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
10070 + #if ($postIndex == 0)
10071 + #set ($stopBlogPostsDisplay = false)
10072 + #end
10073 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
10074 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
10075 + #set($scaleWidth = 600)
10076 + #set($imgQs=~"width=$scaleWidth~")
10077 + ## Display pinned posts
10078 + ## Get the list of pinned posts
10079 + #set ($pinnedPosts = [])
10080 + #set ($pinnedPostsSourceDoc = $NULL)
10081 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
10082 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
10083 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
10084 + #end
10085 + #if (~"$!pinnedPostsSourceDoc~" != '')
10086 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
10087 + #if (~"$!pinnedPostsObj~" != '')
10088 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
10089 + #if (~"$!orderedPinnedPostsJSON~" != '')
10090 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
10091 + #else
10092 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
10093 + #end
10094 + #end
10095 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
10096 + \{\{html clean=~"false~"}}
10097 + #set ($x = 0)
10098 + #set ($showPinnedPostsButton = true)
10099 + #foreach ($pinnedPost in $pinnedPosts)
10100 + #if ($x == 0)
10101 + <div class=~"row flex-container~">
10102 + #if ($showPinnedPostsButton)
10103 + #displayEditPinnedPostsButton()
10104 + #set($showPinnedPostsButton = false)
10105 + #end
10106 + #end
10107 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
10108 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
10109 + #if (~"$!pinnedPostObj~" != '')
10110 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
10111 + #end
10112 + #set ($x = $mathtool.add($x, 1))
10113 + #if ($x == 3)
10114 + #set ($x = 0)
10115 + </div>
10116 + #end
10117 + #end
10118 + #if ($mathtool.mod($x, 3) != 0)
10119 + </div>
10120 + #end
10121 + \{\{/html}}
10122 +
10123 + ## If the first post is a pinned post : this means that all the posts are pinned
10124 + ## In this case, avoid displaying the posts again after the pinned posts section.
10125 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
10126 + #set ($stopBlogPostsDisplay = true)
10127 + #end
10128 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
10129 +
10130 + \{\{html}}
10131 + <div class=~"row no-pinnded-posts~">
10132 + #displayEditPinnedPostsButton()
10133 + </div>
10134 + \{\{/html}}
10135 +
10136 + #end
10137 + #end
10138 + #if (!$stopBlogPostsDisplay)
10139 + \{\{html clean=~"false~"}}
10140 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
10141 + #set ($nbDisplayedPosts = 0)
10142 + #end
10143 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
10144 + #if ($nbDisplayedPosts != 0)
10145 + </div>
10146 + #set ($lastHtmlTag = 'c')
10147 + #end
10148 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
10149 + <div class=~"row~">
10150 + #set ($lastHtmlTag = 'o')
10151 + #set ($lastRowClass = ~"~")
10152 + #else
10153 + <div class=~"row flex-container~">
10154 + #set ($lastHtmlTag = 'o')
10155 + #set ($lastRowClass = ~"flex~")
10156 + #end
10157 + #end
10158 + #displaySmallPost($postDoc $postObj)
10159 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
10160 + </div>
10161 + #set ($lastHtmlTag = 'c')
10162 + #end
10163 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
10164 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
10165 + #if (~"$!lastHtmlTag~" == 'o')
10166 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
10167 + <div class=~"col-xs-12 col-sm-6~"></div>
10168 + #end
10169 + </div>
10170 + #end
10171 + #end
10172 + \{\{/html}}
10173 + #end
10174 + #else
10175 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
10176 + #end
10177 + #else
10178 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
10179 + #end" %)
10180 +(((
10181 +(% class="macro-placeholder hidden" %)
10182 +(((
10183 +macro:velocity
10184 +)))
10185 +
10186 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"col-xs-12 col-sm-6 next_blog~">
10187 +<a href=~"/Nieuws/RI%26E%202023~" class=~"thumbnail~">
10188 +<div class=~"row~">
10189 +<div class=~"col-xs-4~">
10190 +<img src=~"/download/Nieuws/RI%26E%202023/Knipsel.JPG?width=600&rev=1.1~" />
10191 +</div>
10192 +<div class=~"col-xs-8 art_det~">
10193 +<p class=~"text-left~">
10194 +RI en E 2023 <br/><span class=~"date_info~"> Dec 13, 2023, </span>
10195 +</p>
10196 +<div class=~"row post-details~">
10197 +<div class=~"col-xs-8 detail~">
10198 +<div class=~"post-likes btn btn-default disabled badge~"
10199 +title=~"Number of likes on this page: 1~">
10200 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">1</span>
10201 +</div>
10202 +</div>
10203 +<div class=~"col-xs-4 com_det~">
10204 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
10205 +</div>
10206 +</div>
10207 +</div>
10208 +</div>
10209 +</a>
10210 +</div>" %)
10211 +(((
10212 +(% class="macro-placeholder hidden" %)
10213 +(((
10214 +macro:html
10215 +)))
10216 +
10217 +(% class="col-xs-12 col-sm-6 next_blog" %)
10218 +(((
10219 +(% class="row" %)
10220 +(((
10221 +(% class="col-xs-4" %)
10222 +(((
10223 +[[~[~[image:/download/Nieuws/RI%26E%202023/Knipsel.JPG?width=600&rev=1.1~]~]>>path:/Nieuws/RI%26E%202023||class="thumbnail"]]
10224 +)))
10225 +
10226 +(% class="col-xs-8 art_det" %)
10227 +(((
10228 +(% class="text-left" %)
10229 +[[RI en E 2023
10230 +(% class="date_info" %) Dec 13, 2023,>>path:/Nieuws/RI%26E%202023||class="thumbnail"]]
10231 +
10232 +(% class="row post-details" %)
10233 +(((
10234 +(% class="col-xs-8 detail" %)
10235 +(((
10236 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 1" %)
10237 +(((
10238 +[[(% class="like-number" %)1>>path:/Nieuws/RI%26E%202023||class="thumbnail"]]
10239 +)))
10240 +)))
10241 +
10242 +(% class="col-xs-4 com_det" %)
10243 +(((
10244 +(% class="text-right" %)
10245 +[[(0)>>path:/Nieuws/RI%26E%202023||class="thumbnail"]]
10246 +)))
10247 +)))
10248 +)))
10249 +)))
10250 +)))
10251 +)))
10252 +)))
10253 +)))
10254 +
10255 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Aankondiging update Syntess 6\\\\.9\\\\.0181~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG|postIndex=3|previousPostReference=Nieuws.Nieuwsbrief december 2023|postIndex=4|previousPostReference=Nieuws.Nieuwsbrief november 2023|postIndex=5|previousPostReference=Nieuws.Feestelijke afsluiting, keuring materieel en tellen voorraden|postIndex=6|previousPostReference=Nieuws.RI&E 2023~"" %)
10256 +(((
10257 +(% class="macro-placeholder hidden" %)
10258 +(((
10259 +macro:blogPostLayoutCards
10260 +)))
10261 +
10262 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
10263 +(((
10264 +(% class="macro-placeholder hidden" %)
10265 +(((
10266 +macro:include
10267 +)))
10268 +
10269 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
10270 +(((
10271 +(% class="macro-placeholder hidden" %)
10272 +(((
10273 +macro:include
10274 +)))
10275 +
10276 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
10277 +#set($blogClassname = 'Blog.BlogClass')
10278 +#set($blogTemplate = 'Blog.BlogTemplate')
10279 +#set($blogSheet = 'Blog.BlogSheet')
10280 +## Blog entries
10281 +#set($blogPostClassname = 'Blog.BlogPostClass')
10282 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
10283 +#set($blogPostSheet = 'Blog.BlogPostSheet')
10284 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
10285 +#set($oldArticleClassname = 'XWiki.ArticleClass')
10286 +## Categories
10287 +#set($blogCategoryClassname = 'Blog.CategoryClass')
10288 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
10289 +#set($blogCategorySheet = 'Blog.CategorySheet')
10290 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
10291 +#set($oldBlogCategoryClassname = 'Blog.Categories')
10292 +#set($defaultCategoryParent = 'Blog.Categories')
10293 +## Style
10294 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
10295 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
10296 +## Clientside scripts
10297 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
10298 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
10299 +## Misc
10300 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
10301 +#set($isBlogPost = $doc.getObject($blogPostClassname))
10302 +#set($defaultBlogSpace = 'Blog')
10303 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
10304 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
10305 +##
10306 +##
10307 +##
10308 +#**
10309 + * Displays an image, taken from the blog style document.
10310 + *
10311 + * @param $imgName The name of the icon from icons set to use.
10312 + *#
10313 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
10314 +(((
10315 +(% class="macro-placeholder hidden" %)
10316 +(((
10317 +macro:velocity
10318 +)))
10319 +)))
10320 +)))
10321 +
10322 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
10323 +##
10324 +##
10325 +## Import the blog skin and javascripts.
10326 +$!xwiki.ssx.use($blogStyleDocumentName)##
10327 +$!xwiki.jsx.use($blogScriptsDocumentName)##
10328 +##
10329 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
10330 +#template('hierarchy_macros.vm')##
10331 +##
10332 +##
10333 +#**
10334 + * Prints a blog. This is the main macro used in the BlogSheet.
10335 + *
10336 + * @param blogDoc the XDocument holding the blog definition object.
10337 + *###
10338 +#macro(printBlog $blogDoc)
10339 + \{\{include reference='Blog.CreatePost'/}}
10340 +
10341 + ## Use the blogPostList macro to display the blogposts
10342 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
10343 + ## do not support FTM the monthly and weekly blog display types
10344 + #getBlogDisplayType($blogDoc $displayType)
10345 + #if ($displayType == 'weekly' || $displayType == 'monthly')
10346 + #getBlogEntries($blogDoc $entries)
10347 + #displayBlog($entries 'index' true true)
10348 + #displayNavigationLinks($blogDoc)
10349 + #else
10350 + #getBlogDisplayType($blogDoc $displayType)
10351 + #set ($paginated = 'no')
10352 + #if ($displayType == 'paginated')
10353 + #set ($paginated = 'yes')
10354 + #end
10355 + #getBlogPostsLayout($blogDoc $postsLayout)
10356 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
10357 + #end
10358 +#end
10359 +##
10360 +##
10361 +##
10362 +#**
10363 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
10364 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
10365 + * all entries).
10366 + *
10367 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
10368 + *###
10369 +#macro(showBlogInfo $blogDoc)
10370 + #if($blogDoc.getObject($blogClassname))
10371 + ## Keep testing for inline action for backward compatibility with older blogs.
10372 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
10373 + #macro(displayProperty $blogDoc $propname)
10374 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
10375 + : $blogDoc.display($propname)
10376 + #end
10377 + #displayProperty($blogDoc 'title')
10378 + #displayProperty($blogDoc 'description')
10379 + #displayProperty($blogDoc 'displayType')
10380 + #displayProperty($blogDoc 'itemsPerPage')
10381 + #displayProperty($blogDoc 'postsLayout')
10382 + #displayProperty($blogDoc 'postsLayoutParameters')
10383 + #else
10384 + $blogDoc.display('description')
10385 + #end
10386 + #elseif($doc.fullName == $blogSheet)
10387 += $services.localization.render('blog.code.blogsheet') =
10388 + \{\{translation key='blog.code.sheetexplanation'/}}
10389 + #else
10390 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
10391 + #end
10392 +#end
10393 +##
10394 +##
10395 +##
10396 +#**
10397 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
10398 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
10399 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
10400 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
10401 + *
10402 + * @param space A <tt>String</tt>, the name of the space where to search.
10403 + * @param blogDoc The resulting XDocument.
10404 + *###
10405 +#macro(getBlogDocument $space $blogDoc)
10406 + #set ($result = $NULL)
10407 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
10408 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
10409 + ## identify the right blog based on a configuration object in a WebPreferences page.
10410 + #set ($spaceReference = $services.model.resolveSpace($space))
10411 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
10412 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
10413 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
10414 + #if ($preferencesObj)
10415 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
10416 + #end
10417 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
10418 + #if (~"$!result~" == '')
10419 + ## First, try the Space.WebHome, for a whole-space blog
10420 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
10421 + #if(!$result.getObject($blogClassname))
10422 + ## Second, try the Space.Blog document
10423 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
10424 + #if(!$result.getObject($blogClassname))
10425 + ## Third, try searching for a blog document in the current space
10426 + ## Prevent the query fail when the space contains dots '.'
10427 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
10428 + #if($blogDocs.size() > 0)
10429 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
10430 + #else
10431 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
10432 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
10433 + #if($blogDocs.size() > 0)
10434 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
10435 + #else
10436 + ## Last, fallback to Blog.WebHome, the default blog
10437 + #set($result = $xwiki.getDocument('Blog.WebHome'))
10438 + #end
10439 + #end
10440 + #end
10441 + #end
10442 + #end
10443 + #set ($blogDoc = $NULL)
10444 + #setVariable (~"$blogDoc~" $result)
10445 +#end
10446 +##
10447 +##
10448 +##
10449 +#**
10450 + * Retrieve the blog title.
10451 + *
10452 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
10453 + * @param title The resulting title.
10454 + *###
10455 +#macro(getBlogTitle $blogDoc $title)
10456 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
10457 + #set ($title = $NULL)
10458 + #setVariable (~"$title~" $!blogDoc.displayTitle)
10459 +#end
10460 +##
10461 +##
10462 +##
10463 +#**
10464 + * Retrieve the blog description.
10465 + *
10466 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
10467 + * property set.
10468 + * @param description The resulting description.
10469 + *###
10470 +#macro(getBlogDescription $blogDoc $description)
10471 + #getBlogProperty($blogDoc 'description' '' $result)
10472 + #set ($description = $NULL)
10473 + #setVariable (~"$description~" $result)
10474 +#end
10475 +##
10476 +##
10477 +##
10478 +#**
10479 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
10480 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
10481 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
10482 + * month), or all.
10483 + *
10484 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
10485 + * @param entries The resulting list of entries to display, a list of XDocument names.
10486 + *###
10487 +#macro(getBlogEntries $blogDoc $entries)
10488 + #if (!$entries)
10489 + #setVariable (~"$entries~" [])
10490 + #end
10491 + #getAllBlogPostsQuery($query)
10492 + #isDefaultBlog($blogDoc $isDefault)
10493 + #set($queryParams = \{})
10494 + #if ($isDefault)
10495 + #getCategoryAllBlogPostsQuery($query)
10496 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
10497 + #set($discard = $queryParams.put('creator', $xcontext.user))
10498 + #set($discard = $queryParams.put('space', $blogDoc.space))
10499 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
10500 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
10501 + #else
10502 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
10503 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
10504 + #set($discard = $queryParams.put('space', $blogPostsLocation))
10505 + #set($discard = $queryParams.put('parent', $blogDoc.space))
10506 + #end
10507 + #getBlogDisplayType($blogDoc $displayType)
10508 + #if($displayType == 'weekly')
10509 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
10510 + #elseif($displayType == 'monthly')
10511 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
10512 + #elseif($displayType == 'all')
10513 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
10514 + #else
10515 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
10516 + #end
10517 +#end
10518 +##
10519 +##
10520 +##
10521 +#**
10522 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
10523 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
10524 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
10525 + * (10 if not defined).
10526 + *
10527 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
10528 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
10529 + * refined to restrict to a given space, or to a given search criteria, etc.
10530 + * @param entries The resulting list of entries to display, a list of XDocument names.
10531 + * @param queryParams The parameters to bind with the query.
10532 + *###
10533 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
10534 + #if (!$entries)
10535 + #setVariable (~"$entries~" [])
10536 + #end
10537 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
10538 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
10539 + #bindQueryParameters($countQueryObj $queryParams)
10540 + #bindQueryParameters($queryObj $queryParams)
10541 + #set($totalEntries = $countQueryObj.count())
10542 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
10543 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
10544 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
10545 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
10546 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
10547 +#end
10548 +##
10549 +##
10550 +##
10551 +#**
10552 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
10553 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
10554 + * digit year). Initially the current week is displayed.
10555 + *
10556 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
10557 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
10558 + * refined to restrict to a given space, or to a given search criteria, etc.
10559 + * @param entries The resulting list of entries to display, a list of XDocument names.
10560 + * @param queryParams The parameters to bind with the query.
10561 + *###
10562 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
10563 + #if (!$entries)
10564 + #setVariable (~"$entries~" [])
10565 + #end
10566 + #getRequestedWeek($weekDate)
10567 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
10568 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
10569 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
10570 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
10571 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
10572 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
10573 + #bindQueryParameters($countQueryObj $queryParams)
10574 + #bindQueryParameters($queryObj $queryParams)
10575 + #set($totalEntries = $countQueryObj.count())
10576 + #set($discard = $entries.addAll($queryObj.execute()))
10577 +#end
10578 +##
10579 +##
10580 +##
10581 +#**
10582 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
10583 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
10584 + * digit year). Initially the current month is displayed.
10585 + *
10586 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
10587 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
10588 + * refined to restrict to a given space, or to a given search criteria, etc.
10589 + * @param entries The resulting list of entries to display, a list of XDocument names.
10590 + * @param queryParams The parameters to bind with the query.
10591 + *###
10592 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
10593 + #if (!$entries)
10594 + #setVariable (~"$entries~" [])
10595 + #end
10596 + #getRequestedMonth($monthDate)
10597 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
10598 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
10599 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
10600 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
10601 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
10602 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
10603 + #bindQueryParameters($countQueryObj $queryParams)
10604 + #bindQueryParameters($queryObj $queryParams)
10605 + #set($totalEntries = $countQueryObj.count())
10606 + #set($discard = $entries.addAll($queryObj.execute()))
10607 +#end
10608 +##
10609 +##
10610 +##
10611 +#**
10612 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
10613 + *
10614 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
10615 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
10616 + * refined to restrict to a given space, or to a given search criteria, etc.
10617 + * @param entries The resulting list of entries to display, a list of XDocument names.
10618 + * @param queryParams The parameters to bind with the query.
10619 + *###
10620 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
10621 + #if (!$entries)
10622 + #setVariable (~"$entries~" [])
10623 + #end
10624 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
10625 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
10626 + #bindQueryParameters($countQueryObj $queryParams)
10627 + #bindQueryParameters($queryObj $queryParams)
10628 + #set($totalEntries = $countQueryObj.count())
10629 + #set($discard = $entries.addAll($queryObj.execute()))
10630 +#end
10631 +##
10632 +##
10633 +##
10634 +#**
10635 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
10636 + *
10637 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
10638 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
10639 + * refined to restrict to a given space, or to a given search criteria, etc.
10640 + * @param queryParams The parameters to bind with the query.
10641 + * @param entries The resulting list of entries to display, a list of XDocument names.
10642 + *###
10643 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
10644 + #if (!$entries)
10645 + #setVariable (~"$entries~" [])
10646 + #end
10647 + #set($query = ~"$\{query} and isPublished.value = 0~")
10648 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
10649 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
10650 + #bindQueryParameters($countQueryObj $queryParams)
10651 + #bindQueryParameters($queryObj $queryParams)
10652 + #set($totalEntries = $countQueryObj.count())
10653 + #set($discard = $entries.addAll($queryObj.execute()))
10654 +#end
10655 +##
10656 +##
10657 +##
10658 +#**
10659 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
10660 + *
10661 + * @param entries The resulting list of entries to display, a list of XDocument names.
10662 + *###
10663 +#macro(getGlobalBlogEntries $entries)
10664 + #if (!$entries)
10665 + #setVariable (~"$entries~" [])
10666 + #end
10667 + #getAllBlogPostsQuery($query)
10668 + #set($totalEntries = $services.query.hql($query).count())
10669 + #set($defaultItemsPerPage = 20)
10670 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
10671 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
10672 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
10673 +#end
10674 +#**
10675 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
10676 + * blog, nor specify a range or an ordering criteria.
10677 + *
10678 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
10679 + *
10680 + * @param query The basic query for selecting blog entries.
10681 + *#
10682 +#macro(getBlogEntriesBaseQuery $query)
10683 + #getAllBlogPostsQuery($query)
10684 +#end
10685 +#**
10686 + * Return the Query for selecting the all wiki blog posts without filtering
10687 + *
10688 + * @param query The basic query for selecting blog entries.
10689 + *#
10690 +#macro(getAllBlogPostsQuery $query)
10691 + #set ($query = $NULL)
10692 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
10693 + IntegerProperty hidden, DateProperty publishDate
10694 + where doc.fullName <> '$blogPostTemplate' and
10695 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
10696 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
10697 + hidden.id.id = obj.id and hidden.id.name='hidden' and
10698 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
10699 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
10700 +#end
10701 +##
10702 +##
10703 +##
10704 +###**
10705 + * Return the Query for selecting the all wiki blog posts with categories filtering
10706 + *
10707 + * @param query The basic query for selecting blog entries.
10708 + *###
10709 +#macro(getCategoryAllBlogPostsQuery $query)
10710 + #set ($query = $NULL)
10711 + #getAllBlogPostsQuery($baseQuery)
10712 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
10713 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
10714 +#end
10715 +##
10716 +##
10717 +##
10718 +#**
10719 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
10720 + * week), monthly (all entries in a month), or all.
10721 + *
10722 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
10723 + * property set.
10724 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
10725 + *###
10726 +#macro(getBlogDisplayType $blogDoc $displayType)
10727 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
10728 + #set ($displayType = $NULL)
10729 + #setVariable (~"$displayType~" $result)
10730 +#end
10731 +##
10732 +##
10733 +##
10734 +#**
10735 + * Displays a list of entries.
10736 + *
10737 + * @param entries The entries to display, a list of XDocument names.
10738 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
10739 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
10740 + * used values: index, single, category, search, unpublished, hidden.
10741 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
10742 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
10743 + * displayed alone on their page since it's the page title which is used in this case)
10744 + *###
10745 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
10746 + #set($blogDay = '')
10747 + (% class=~"hfeed $!\{displaying}~" ~%)(((
10748 + (% class=~"blogDay~" ~%)(((
10749 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
10750 + #getEntryObject($entryDoc $entryObj)
10751 + ## Although all entries should have one of the two objects, better check to be sure.
10752 + #if(~"$!\{entryObj}~" != '')
10753 + #getEntryDate($entryDoc $entryObj $entryDate)
10754 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
10755 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
10756 + #if($blogDay != $entryDateStr)
10757 + #if($blogDay != '')
10758 + )))
10759 + (% class=~"blogDay~" ~%)(((
10760 + #end
10761 + #displayBlogDate($entryDate)
10762 + #set ($blogDay = $entryDateStr)
10763 + #end
10764 + ## Finally, display the entry.
10765 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
10766 + #end
10767 + #end
10768 + )))## blogDay
10769 + )))## hfeed
10770 +#end
10771 +##
10772 +##
10773 +##
10774 +#**
10775 + * Get the entry object, either a new BlogPost or an old Article.
10776 + *
10777 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
10778 + * @param entryObj The resulting xobject of the blog post.
10779 + *###
10780 +#macro(getEntryObject $entryDoc $__entryObj)
10781 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
10782 + #if(!$result)
10783 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
10784 + #end
10785 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
10786 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
10787 + ## overwritten in this case but it's less likely to have such a variable defined before.
10788 + #set ($__entryObj = $NULL)
10789 + #setVariable (~"$__entryObj~" $result)
10790 +#end
10791 +##
10792 +##
10793 +##
10794 +#**
10795 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
10796 + * the document creation date, but can be edited by the user.
10797 + *
10798 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
10799 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
10800 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
10801 + *###
10802 +#macro(getEntryDate $entryDoc $entryObj $result)
10803 + #set ($result = $NULL)
10804 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
10805 +#end
10806 +##
10807 +##
10808 +##
10809 +#**
10810 + * Displays a date, nicely formatted as a calendar page.
10811 + *
10812 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
10813 + *###
10814 +#macro(displayBlogDate $date)
10815 + #set($year = $xwiki.formatDate($date, 'yyyy'))
10816 + ## 3 letter month name, like Jan, Dec.
10817 + #set($month = $xwiki.formatDate($date, 'MMM'))
10818 + ## Uncomment to get a full length month name, like January, December.
10819 + ## TODO: this could be defined somewhere in the blog style.
10820 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
10821 + #set($day = $xwiki.formatDate($date, 'dd'))
10822 + (% class=~"blogdate~" ~%)
10823 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
10824 +#end
10825 +##
10826 +##
10827 +##
10828 +#**
10829 + * Displays a blog article: management tools, header, content, footer.
10830 + *
10831 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
10832 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
10833 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
10834 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
10835 + * when they're displayed alone on their page since it's the page title which is used in this case)
10836 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
10837 + *###
10838 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
10839 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
10840 + #isPublished($entryObj $isPublished)
10841 + #isHidden($entryObj $isHidden)
10842 + #if($doc.fullName == $entryDoc.fullName)
10843 + (% class=~"hentry single-article~" ~%)(((
10844 + #else
10845 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
10846 + #end
10847 + #if ($shouldDisplayActions)
10848 + #displayEntryTools($entryDoc $entryObj)
10849 + #end
10850 + #if($shouldDisplayTitle)
10851 + #displayEntryTitle($entryDoc $entryObj)
10852 + #end
10853 + #if($doc.fullName == $entryDoc.fullName)
10854 + #if(!$isPublished)
10855 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
10856 + #elseif($isHidden)
10857 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
10858 + #end
10859 + #end
10860 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
10861 + #displayEntryFooter($entryDoc $entryObj)
10862 + )))## hentry
10863 +#end
10864 +##
10865 +##
10866 +##
10867 +#**
10868 + * Checks if the provided blog is published or not.
10869 + *
10870 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
10871 + * @param isPublished The resulting boolean, true if the entry is considered published.
10872 + *###
10873 +#macro(isPublished $entryObj $isPublished)
10874 + #set ($isPublished = $NULL)
10875 + ## This should work for both old articles, which don't have the 'published' property at all, and
10876 + ## are considered published by default, and new entries, that should have 1 if published.
10877 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
10878 + #setVariable (~"$isPublished~" true)
10879 + #else
10880 + #setVariable (~"$isPublished~" false)
10881 + #end
10882 +#end
10883 +##
10884 +##
10885 +##
10886 +#**
10887 + * Checks if the provided blog is hidden or not.
10888 + *
10889 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
10890 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
10891 + *###
10892 +#macro(isHidden $entryObj $isHidden)
10893 + #set ($isHidden = $NULL)
10894 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
10895 + ## are considered visible by default, and new entries, that should have 1 if hidden.
10896 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
10897 + #setVariable (~"$isHidden~" true)
10898 + #else
10899 + #setVariable (~"$isHidden~" false)
10900 + #end
10901 +#end
10902 +##
10903 +##
10904 +##
10905 +#**
10906 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
10907 + *
10908 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
10909 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
10910 + *###
10911 +#macro(displayEntryTools $entryDoc $entryObj)
10912 + #if($xcontext.action == 'view')
10913 + (% class=~"blog-entry-toolbox~" ~%)(((
10914 + #displayPublishButton($entryDoc $entryObj)
10915 + #displayHideShowButton($entryDoc $entryObj)
10916 + #displayEditButton($entryDoc $entryObj)
10917 + #displayDeleteButton($entryDoc $entryObj)
10918 + )))
10919 + #end
10920 +#end
10921 +##
10922 +##
10923 +##
10924 +#**
10925 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
10926 + *
10927 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
10928 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
10929 + * @todo AJAX calls.
10930 + *###
10931 +#macro(displayPublishButton $entryDoc $entryObj)
10932 + #isPublished($entryObj $isPublished)
10933 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
10934 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
10935 + #end
10936 +#end
10937 +##
10938 +##
10939 +##
10940 +#**
10941 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
10942 + *
10943 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
10944 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
10945 + *###
10946 +#macro(displayHideShowButton $entryDoc $entryObj)
10947 + #isPublished($entryObj $isPublished)
10948 + #isHidden($entryObj $isHidden)
10949 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
10950 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
10951 + #set ($queryString = \{
10952 + 'xredirect' : $thisURL,
10953 + 'form_token' : $services.csrf.getToken()
10954 + })
10955 + #if ($isHidden)
10956 + #set ($discard = $queryString.putAll(\{
10957 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
10958 + 'comment' : $services.localization.render('blog.code.madevisible')
10959 + }))
10960 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
10961 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
10962 + #else
10963 + #set ($discard = $queryString.putAll(\{
10964 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
10965 + 'comment' : $services.localization.render('blog.code.hid')
10966 + }))
10967 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
10968 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
10969 + #end
10970 + #end
10971 +#end
10972 +##
10973 +##
10974 +##
10975 +#**
10976 + * Displays the edit button to those that can edit the article.
10977 + *
10978 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
10979 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
10980 + *###
10981 +#macro(displayEditButton $entryDoc $entryObj)
10982 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
10983 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
10984 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
10985 + #end
10986 +#end
10987 +##
10988 +##
10989 +##
10990 +#**
10991 + * Displays the delete button to those that can edit the article.
10992 + *
10993 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
10994 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
10995 + * @todo AJAX calls.
10996 + *###
10997 +#macro(displayDeleteButton $entryDoc $entryObj)
10998 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
10999 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
11000 + #end
11001 +#end
11002 +##
11003 +##
11004 +##
11005 +#**
11006 + * Displays the title of the entry.
11007 + *
11008 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
11009 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
11010 + *###
11011 +#macro(displayEntryTitle $entryDoc $entryObj)
11012 + #if($doc.fullName == $entryDoc.fullName)
11013 + (% class=~"entry-title~" ~%)
11014 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
11015 + #else
11016 + (% class=~"entry-title~" ~%)
11017 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
11018 + #end
11019 +#end
11020 +##
11021 +##
11022 +##
11023 +#**
11024 + * Displays the body of the entry.
11025 + *
11026 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
11027 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
11028 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
11029 + *###
11030 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
11031 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
11032 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
11033 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
11034 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
11035 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
11036 + ))) ## entry-content
11037 + (% class=~"clearfloats~" ~%)((()))
11038 +#end
11039 +##
11040 +##
11041 +##
11042 +#**
11043 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
11044 + * of the <tt>extract</tt> field (if not empty).
11045 + *
11046 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
11047 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
11048 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
11049 + * @param entryContent The resulting content.
11050 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
11051 + * <tt>onlyExtract</tt> is <tt>true</tt>)
11052 + *###
11053 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
11054 + #if ($onlyExtract)
11055 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
11056 + ## of the content.
11057 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
11058 + #end
11059 + #if(~"$!macro.result~" == '')
11060 + #set($macro.result = $entryObj.getProperty('content').value)
11061 +#* Disabled until the content can be cleanly cut.
11062 +* #if($onlyExtract && $result.length()>$maxchars)
11063 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
11064 +* #set($i = $i + 1)
11065 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
11066 +* #end
11067 +## *###
11068 + #elseif (!$removeEllipsis)
11069 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
11070 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
11071 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
11072 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
11073 + #end
11074 + #end
11075 + #set ($entryContent = $NULL)
11076 + #setVariable (~"$entryContent~" $macro.result)
11077 +#end
11078 +##
11079 +##
11080 +##
11081 +#**
11082 + * Displays the footer of the entry.
11083 + *
11084 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
11085 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
11086 + *###
11087 +#macro(displayEntryFooter $entryDoc $entryObj)
11088 + (% class=~"entry-footer~" ~%)(((
11089 + #isPublished($entryObj $isPublished)
11090 + (% class='entry-author-label' ~%)
11091 + #if($isPublished)
11092 + \{\{translation key='blog.code.postedby'/}} ##
11093 + #else
11094 + \{\{translation key='blog.code.createdby'/}} ##
11095 + #end
11096 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
11097 + #getEntryDate($entryDoc $entryObj $entryDate)
11098 + #listCategories($entryObj) #*
11099 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
11100 + ## we assume cannot be more than 3 seconds.
11101 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
11102 + #if ($showcomments)
11103 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
11104 + #end ##
11105 + #if($entryDoc != $doc) ##
11106 + #displayEntryBlogLocation($entryDoc $entryObj) ##
11107 + #end
11108 + )))## entry-footer
11109 +#end
11110 +##
11111 +##
11112 +#**
11113 + * Display the blog for the entry (if it is not the currently displayed blog)
11114 + *
11115 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
11116 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
11117 + *###
11118 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
11119 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
11120 + #if(~"$!blogPostsLocation~" != ~"~") ##
11121 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
11122 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
11123 + #if($doc.documentReference != $blogDocRef) ##
11124 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
11125 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
11126 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
11127 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
11128 + )))(%~%)##
11129 + #end
11130 + #end
11131 + #end
11132 +#end
11133 +##
11134 +##
11135 +##
11136 +##
11137 +#**
11138 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
11139 + *
11140 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
11141 + *###
11142 +#macro(listCategories $entryObj)
11143 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
11144 + #set($categories = $entryObj.getProperty('category').value)
11145 + #set($first = true)
11146 + #if($categories.size() > 0)
11147 + #foreach($category in $categories)
11148 + #set($categoryDoc = $!xwiki.getDocument($category))
11149 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
11150 + #if($foreach.count == 1)
11151 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
11152 + #else
11153 + , ##
11154 + #end##
11155 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
11156 + #end##
11157 + #end##
11158 + #end
11159 + #end
11160 +#end
11161 +##
11162 +##
11163 +##
11164 +#**
11165 + * Displays blog pagination links (older and newer entries).
11166 + *
11167 + * @param blogDoc the XDocument holding the blog definition object.
11168 + *###
11169 +#macro(displayNavigationLinks $blogDoc)
11170 + (% class=~"clearfloats~" ~%)((()))
11171 + #getBlogDisplayType($blogDoc $displayType)
11172 + #if($displayType == 'weekly')
11173 + (% class=~"pagingLinks~" ~%)(((
11174 + #getRequestedWeek($weekDate)
11175 + $weekDate.addWeeks(-1)##
11176 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
11177 + #sep()
11178 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
11179 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
11180 + )))
11181 + #elseif($displayType == 'monthly')
11182 + (% class=~"pagingLinks~" ~%)(((
11183 + #getRequestedMonth($monthDate)
11184 + $monthDate.addMonths(-1)##
11185 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
11186 + #sep()
11187 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
11188 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
11189 + )))
11190 + #elseif($displayType == 'all')
11191 + #else
11192 + ## Paginated
11193 + #if(($totalPages > 1))
11194 + #set($queryString = '')
11195 + #foreach($p in $request.getParameterNames())
11196 + #if($p != 'page' && $p != 'ipp')
11197 + #foreach($v in $request.getParameterValues($p))
11198 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
11199 + #end
11200 + #end
11201 + #end
11202 + (% class=~"pagingLinks~" ~%)(((
11203 + #if ($currentPageNumber < $totalPages)
11204 + #set($currentPageNumber = $currentPageNumber + 1)
11205 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
11206 + #set($currentPageNumber = $currentPageNumber - 1)
11207 + #end
11208 + #if ($currentPageNumber > 1)
11209 + #if ($currentPageNumber < $totalPages)
11210 + #sep()
11211 + #end
11212 + #set($currentPageNumber = $currentPageNumber - 1)
11213 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
11214 + #set($currentPageNumber = $currentPageNumber + 1)
11215 + #end
11216 + (% class=~"clear~" ~%)(%~%)
11217 + )))## pagingLinks
11218 + #end
11219 + #end
11220 +#end
11221 +##
11222 +##
11223 +##
11224 +#**
11225 + * Displays a message box with ~"publish~" icon.
11226 + *
11227 + * @param message A text message concerning blog article publishing
11228 + *###
11229 +#macro(publishMessageBox $message)
11230 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
11231 +#end
11232 +#**
11233 + * Displays a message box with ~"show/hide~" icon.
11234 + *
11235 + * @param message A text message concerning blog article hiding
11236 + *###
11237 +#macro(hideMessageBox $message)
11238 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
11239 +#end
11240 +##
11241 +##
11242 +##
11243 +#**
11244 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
11245 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
11246 + *
11247 + * @param monthDate The resulting week, a JODATime MutableDateTime.
11248 + *###
11249 +#macro(getRequestedWeek $weekDate)
11250 + #set ($weekDate = $NULL)
11251 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
11252 + #if(~"$!\{request.year}~" != '')
11253 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
11254 + #end
11255 + #if(~"$!\{request.week}~" != '')
11256 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
11257 + #end
11258 +#end
11259 +##
11260 +##
11261 +##
11262 +#**
11263 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
11264 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
11265 + *
11266 + * @param monthDate The resulting month, a JODATime MutableDateTime.
11267 + *###
11268 +#macro(getRequestedMonth $monthDate)
11269 + #set ($monthDate = $NULL)
11270 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
11271 + #if(~"$!\{request.year}~" != '')
11272 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
11273 + #end
11274 + #if(~"$!\{request.month}~" != '')
11275 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
11276 + #end
11277 +#end
11278 +##
11279 +##
11280 +##
11281 +#**
11282 + * Retrieve a blog property (title, display type, etc).
11283 + *
11284 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
11285 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
11286 + * @param defaultValue The default value to use in case the blog object does not define one.
11287 + * @param propertyValue The resulting value.
11288 + *###
11289 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
11290 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
11291 + #if($result == '')
11292 + #set($result = $defaultValue)
11293 + #end
11294 + #set ($propertyValue = $NULL)
11295 + #setVariable (~"$propertyValue~" $result)
11296 +#end
11297 +
11298 +#**
11299 + * If an error occurs when executing an action, set a specific response status and display an error message.
11300 + *
11301 + * @param status The response status.
11302 + * @param text The user readable error to be displayed. Can be a translation key.
11303 + * @param parameters The parameters to use when decoding the translation key.
11304 + *###
11305 +#macro(blog__actionResponseError $status $text $parameters)
11306 + $response.setStatus($status)
11307 + #if($request.ajax)
11308 + $services.localization.render($text, $!parameters)
11309 + #else
11310 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
11311 + #end
11312 +#end
11313 +##
11314 +##
11315 +##
11316 +#**
11317 + * Check if a blog is the Default blog (The one in the 'Blog' space).
11318 + *
11319 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
11320 + * @param isDefault The resulting boolean.
11321 + *###
11322 +#macro(isDefaultBlog $blogDoc $isDefault)
11323 + #set ($result = false)
11324 + #if ($blogDoc.space == 'Blog')
11325 + #set ($result = true)
11326 + #end
11327 + #setVariable(~"$isDefault~" $result)
11328 +#end
11329 +##
11330 +##
11331 +##
11332 +#**
11333 + * Retrieve the blog posts location (space).
11334 + *
11335 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
11336 + * @param postsLocation The resulting location.
11337 + *###
11338 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
11339 + #getBlogDocument($blogSpace $blogDoc)
11340 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
11341 + #set ($postsLocation = $NULL)
11342 + #setVariable (~"$postsLocation~" $result)
11343 +#end
11344 +##
11345 +##
11346 +##
11347 +#**
11348 + * Retrieve the blog categories location (space).
11349 + *
11350 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
11351 + * @param categoriesLocation The resulting location.
11352 + *###
11353 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
11354 + #getBlogDocument($blogSpace $blogDoc)
11355 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
11356 + #set ($postsLocation = $NULL)
11357 + #setVariable (~"$categoriesLocation~" $result)
11358 +#end
11359 +###**
11360 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
11361 + * for example there is 4 different panel contexts:
11362 + * aBlog.aPost or aBlog.WebHome
11363 + * aCategorySpace.aCategory
11364 + * aCategorySpace.WebHome
11365 + * Blog.aPost or Blog.WebHome
11366 + *
11367 + * @param query The query for selecting blog entries.
11368 + * @param queryParams The parameters to bind with the generated query.
11369 + * @param targetDoc The document in which the articles will be displayed.
11370 + *###
11371 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
11372 + #set ($query = $NULL)
11373 + #set ($queryParams = $NULL)
11374 + #getCategoryAllBlogPostsQuery($resultQuery)
11375 + #set ($resultQueryParams = \{})
11376 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
11377 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
11378 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
11379 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
11380 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
11381 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
11382 + #elseif($targetDoc.getObject($blogCategoryClassname))
11383 + ## Get all posts that are in a category aCategorySpace.aCategory
11384 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
11385 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
11386 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
11387 + ## Get all posts that are in a category aCategorySpace.%
11388 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
11389 + ## Exclude incategorized posts
11390 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
11391 + #if ($targetDoc.space == $defaultBlogSpace)
11392 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
11393 + #end
11394 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
11395 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
11396 + #else
11397 + ## Get all posts in blog space aBlog
11398 + #getAllBlogPostsQuery($resultQuery)
11399 + #getBlogPostsLocation($targetDoc.space $postsLocation)
11400 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
11401 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
11402 + #end
11403 + #setVariable(~"$query~" $resultQuery)
11404 + #setVariable(~"$queryParams~" $resultQueryParams)
11405 +#end
11406 +##
11407 +##
11408 +##
11409 +###**
11410 + * Display blog posts based on the context where the posts are displayed.
11411 + * for example there is 4 different panel contexts:
11412 + * aBlog.aPost or aBlog.WebHome
11413 + * aCategorySpace.aCategory
11414 + * aCategorySpace.WebHome
11415 + * Blog.aPost or Blog.WebHome
11416 + *
11417 + * @param targetDoc The document in which the articles will be displayed.
11418 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
11419 + * @param layout Layout of the the posts to display
11420 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
11421 + * @param limit the number of posts to display
11422 + *###
11423 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
11424 + #if ($postLayout == 'full')
11425 + #set ($macro.paginated = 'yes')
11426 + #end
11427 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
11428 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
11429 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
11430 + #if (~"$!layout~" == '')
11431 + #set ($layout = $postsLayout)
11432 + #end
11433 + #if ($postsVisiblity == 'recent')
11434 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
11435 + #elseif($postsVisiblity == 'unpublished')
11436 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
11437 + #end
11438 + #elseif($targetDoc.getObject($blogCategoryClassname))
11439 + ## Display all posts that are in a category aCategorySpace.aCategory
11440 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
11441 + #getBlogPostsLayout($blogDoc $postsLayout)
11442 + #if (~"$!layout~" == '')
11443 + #set ($layout = $postsLayout)
11444 + #end
11445 + #if ($postsVisiblity == 'recent')
11446 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
11447 + #elseif($postsVisiblity == 'unpublished')
11448 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
11449 + #end
11450 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
11451 + ## Display all posts that are in a category aCategorySpace.%
11452 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
11453 + #getBlogPostsLayout($blogDoc $postsLayout)
11454 + #if (~"$!layout~" == '')
11455 + #set ($layout = $postsLayout)
11456 + #end
11457 + #if ($postsVisiblity == 'recent')
11458 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
11459 + #elseif($postsVisiblity == 'unpublished')
11460 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
11461 + #end
11462 + #else
11463 + ## Display all posts in blog space aBlog
11464 + #getBlogDocument($targetDoc.space $blogDoc)
11465 + #getBlogPostsLayout($blogDoc $postsLayout)
11466 + #if (~"$!layout~" == '')
11467 + #set ($layout = $postsLayout)
11468 + #end
11469 + #if ($postsVisiblity == 'recent')
11470 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
11471 + #elseif($postsVisiblity == 'unpublished')
11472 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
11473 + #end
11474 + #end
11475 +#end
11476 +##
11477 +##
11478 +##
11479 +#**
11480 + * Bind parameters to a query object.
11481 + *
11482 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
11483 + * @param queryParams the query parameters.
11484 + *###
11485 +#macro(bindQueryParameters $queryObj $queryParams)
11486 + #set ($output = $queryObj)
11487 + #foreach( $key in $queryParams.keySet() )
11488 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
11489 + #end
11490 + #setVariable(~"$queryObj~" $output)
11491 +#end
11492 +##
11493 +##
11494 +##
11495 +#**
11496 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
11497 + *
11498 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
11499 + * property set.
11500 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
11501 + *###
11502 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
11503 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
11504 + #set ($postsLayout = $NULL)
11505 + #setVariable (~"$postsLayout~" $res)
11506 +#end
11507 +##
11508 +##
11509 +##
11510 +#**
11511 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
11512 + *
11513 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
11514 + * @param blogDoc The resulting XDocument.
11515 + *###
11516 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
11517 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
11518 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
11519 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
11520 + #else
11521 + ## Fallback to Blog.WebHome, the default blog
11522 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
11523 + #end
11524 + #set ($blogDoc = $NULL)
11525 + #setVariable (~"$blogDoc~" $macro.result)
11526 +#end" %)
11527 +(((
11528 +(% class="macro-placeholder hidden" %)
11529 +(((
11530 +macro:velocity
11531 +)))
11532 +)))
11533 +)))
11534 +
11535 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
11536 +(((
11537 +(% class="macro-placeholder hidden" %)
11538 +(((
11539 +macro:include
11540 +)))
11541 +
11542 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
11543 + * Extract the layout parameters from a string.
11544 + *
11545 + * @param layoutParamsString The string representation of the layout parameters.
11546 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
11547 + * @param layoutsParameters The resulting layout parameters Map.
11548 + *###
11549 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
11550 + #set ($layoutsParameters = $NULL)
11551 + #set ($macro.layoutParams = \{})
11552 + #if (~"$!layoutParamsString~" != '')
11553 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
11554 + #foreach ($item in $macro.paramsArr)
11555 + #set ($itemSplit = $item.split('='))
11556 + #if ($itemSplit.size() == 2)
11557 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
11558 + #end
11559 + #end
11560 + #end
11561 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
11562 +#end" %)
11563 +(((
11564 +(% class="macro-placeholder hidden" %)
11565 +(((
11566 +macro:velocity
11567 +)))
11568 +)))
11569 +)))
11570 +
11571 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
11572 + #initLayoutVars($pDoc $pObj)
11573 + <div class=~"col-xs-12 col-sm-6 next_blog~">
11574 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
11575 + <div class=~"row~">
11576 + <div class=~"col-xs-4~">
11577 + #if ($imageAtt)
11578 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
11579 + #end
11580 + </div>
11581 + <div class=~"col-xs-8 art_det~">
11582 + <p class=~"text-left~">
11583 + #if($displayTitle)$!postTitle #end
11584 + <br/><span class=~"date_info~"> $!dateStr </span>
11585 + </p>
11586 + #displayPostDetails($pDoc)
11587 + </div>
11588 + </div>
11589 + </a>
11590 + </div>
11591 + #end
11592 + ##
11593 + ##
11594 + ##
11595 + #macro(displayPinnedPost $pDoc $pObj)
11596 + #initLayoutVars($pDoc $pObj)
11597 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
11598 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
11599 + <div class=~"thumbnail~">
11600 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
11601 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
11602 + #end
11603 + #if ($imageAtt)
11604 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
11605 + #end
11606 + <div class=~"caption~">
11607 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
11608 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
11609 + #end
11610 + #if ($displaySummaryOnPinnedPosts)
11611 + <div class=~"text-left post-summary~">
11612 + #set ($postContent = $pObj.getProperty('extract').value)
11613 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
11614 + </div>
11615 + #end
11616 + #displayPostDetails($pDoc)
11617 + </div>
11618 + </div>
11619 + </a>
11620 + </div>
11621 + #end
11622 + ##
11623 + ##
11624 + ##
11625 + #macro(formatPostDate $pDoc $pObj)
11626 + #set ($formattedDate = $NULL)
11627 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
11628 + #if (~"$!dateStr~" != '')
11629 + #set ($dateArr = $dateStr.split(' '))
11630 + #if ($dateArr.size() > 3)
11631 + #set ($dateStr = ~"~")
11632 + #foreach($s in $dateArr.subList(0, 3))
11633 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
11634 + #end
11635 + #end
11636 + #end
11637 + #setVariable(~"$formattedDate~" $dateStr)
11638 + #end
11639 + ##
11640 + ##
11641 + ##
11642 + #macro(displayPostDetails $pDoc)
11643 + <div class=~"row post-details~">
11644 + <div class=~"col-xs-8 detail~">
11645 + #if ($services.like.displayButton($pDoc.documentReference))
11646 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
11647 + ## Retrieve the likes number in XWiki 12.9+
11648 + #set ($likeNumber = $optLikeRecord.get())
11649 + #if (!$stringtool.isNumeric($likeNumber.toString()))
11650 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
11651 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
11652 + #end
11653 + #if ($stringtool.isNumeric($likeNumber.toString()))
11654 + <div class=~"post-likes btn btn-default disabled badge~"
11655 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
11656 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
11657 + </div>
11658 + #end
11659 + #elseif ($services.ratings)
11660 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
11661 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
11662 + <ul class=~"pull-left note list-inline~">
11663 + #foreach ($x in [1..5])
11664 + #set ($cls = ~"~")
11665 + #if ($x > $averageVote)
11666 + #set ($cls = ~"-o~")
11667 + #end
11668 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
11669 + #end
11670 + </ul>
11671 + #end
11672 + #end
11673 + </div>
11674 + #if ($showPostComments)
11675 + <div class=~"col-xs-4 com_det~">
11676 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
11677 + </div>
11678 + #end
11679 + </div>
11680 + #end
11681 + ##
11682 + ##
11683 + ##
11684 + #macro(initLayoutVars $pDoc $pObj)
11685 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
11686 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
11687 + #isPublished($pObj $isPublished)
11688 + #isHidden($pObj $isHidden)
11689 + #getEntryDate($pDoc $pObj $postDate)
11690 + #formatPostDate($postDate $dateStr)
11691 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
11692 + #set ($nbComments = $pDoc.getComments().size())
11693 + #set ($showPostComments = true)
11694 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
11695 + #set ($showPostComments = false)
11696 + #end
11697 + #end
11698 + ##
11699 + ##
11700 + ##
11701 + #macro(displayEditPinnedPostsButton)
11702 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
11703 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
11704 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
11705 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
11706 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
11707 + <div class=~"edit-pinned-posts-container~">
11708 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
11709 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
11710 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
11711 + </a>
11712 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
11713 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
11714 + </div>
11715 + </div>
11716 + #if (~"$!pinnedPostsObj~" == '')
11717 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
11718 + #end
11719 + #end
11720 + #end" %)
11721 +(((
11722 +(% class="macro-placeholder hidden" %)
11723 +(((
11724 +macro:velocity
11725 +)))
11726 +)))
11727 +
11728 +(% data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
11729 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
11730 + #getEntryObject($postDoc $postObj)
11731 + #if (~"$!postObj~" != '')
11732 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
11733 + ##
11734 + #set ($displayTitle = true)
11735 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
11736 + #set ($displayTitle = false)
11737 + #end
11738 + ##
11739 + #set ($displayTitleFirstOnPinnedPosts = false)
11740 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
11741 + #set ($displayTitleFirstOnPinnedPosts = true)
11742 + #end
11743 + ##
11744 + #set ($displaySummaryOnPinnedPosts = true)
11745 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
11746 + #set ($displaySummaryOnPinnedPosts = false)
11747 + #end
11748 + ##
11749 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
11750 + #if ($postIndex == 0)
11751 + #set ($stopBlogPostsDisplay = false)
11752 + #end
11753 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
11754 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
11755 + #set($scaleWidth = 600)
11756 + #set($imgQs=~"width=$scaleWidth~")
11757 + ## Display pinned posts
11758 + ## Get the list of pinned posts
11759 + #set ($pinnedPosts = [])
11760 + #set ($pinnedPostsSourceDoc = $NULL)
11761 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
11762 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
11763 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
11764 + #end
11765 + #if (~"$!pinnedPostsSourceDoc~" != '')
11766 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
11767 + #if (~"$!pinnedPostsObj~" != '')
11768 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
11769 + #if (~"$!orderedPinnedPostsJSON~" != '')
11770 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
11771 + #else
11772 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
11773 + #end
11774 + #end
11775 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
11776 + \{\{html clean=~"false~"}}
11777 + #set ($x = 0)
11778 + #set ($showPinnedPostsButton = true)
11779 + #foreach ($pinnedPost in $pinnedPosts)
11780 + #if ($x == 0)
11781 + <div class=~"row flex-container~">
11782 + #if ($showPinnedPostsButton)
11783 + #displayEditPinnedPostsButton()
11784 + #set($showPinnedPostsButton = false)
11785 + #end
11786 + #end
11787 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
11788 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
11789 + #if (~"$!pinnedPostObj~" != '')
11790 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
11791 + #end
11792 + #set ($x = $mathtool.add($x, 1))
11793 + #if ($x == 3)
11794 + #set ($x = 0)
11795 + </div>
11796 + #end
11797 + #end
11798 + #if ($mathtool.mod($x, 3) != 0)
11799 + </div>
11800 + #end
11801 + \{\{/html}}
11802 +
11803 + ## If the first post is a pinned post : this means that all the posts are pinned
11804 + ## In this case, avoid displaying the posts again after the pinned posts section.
11805 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
11806 + #set ($stopBlogPostsDisplay = true)
11807 + #end
11808 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
11809 +
11810 + \{\{html}}
11811 + <div class=~"row no-pinnded-posts~">
11812 + #displayEditPinnedPostsButton()
11813 + </div>
11814 + \{\{/html}}
11815 +
11816 + #end
11817 + #end
11818 + #if (!$stopBlogPostsDisplay)
11819 + \{\{html clean=~"false~"}}
11820 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
11821 + #set ($nbDisplayedPosts = 0)
11822 + #end
11823 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
11824 + #if ($nbDisplayedPosts != 0)
11825 + </div>
11826 + #set ($lastHtmlTag = 'c')
11827 + #end
11828 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
11829 + <div class=~"row~">
11830 + #set ($lastHtmlTag = 'o')
11831 + #set ($lastRowClass = ~"~")
11832 + #else
11833 + <div class=~"row flex-container~">
11834 + #set ($lastHtmlTag = 'o')
11835 + #set ($lastRowClass = ~"flex~")
11836 + #end
11837 + #end
11838 + #displaySmallPost($postDoc $postObj)
11839 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
11840 + </div>
11841 + #set ($lastHtmlTag = 'c')
11842 + #end
11843 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
11844 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
11845 + #if (~"$!lastHtmlTag~" == 'o')
11846 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
11847 + <div class=~"col-xs-12 col-sm-6~"></div>
11848 + #end
11849 + </div>
11850 + #end
11851 + #end
11852 + \{\{/html}}
11853 + #end
11854 + #else
11855 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
11856 + #end
11857 + #else
11858 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
11859 + #end" class="macro hidden macro-placeholder" %)macro:velocity(% data-macro="startmacro:html|-|clean=~"false~"|-|</div>
11860 +<div class=~"row flex-container~">
11861 +<div class=~"col-xs-12 col-sm-6 next_blog~">
11862 +<a href=~"/Nieuws/Aankondiging%20update%20Syntess%206.9.0181~" class=~"thumbnail~">
11863 +<div class=~"row~">
11864 +<div class=~"col-xs-4~">
11865 +<img src=~"/download/Nieuws/Aankondiging%20update%20Syntess%206.9.0181/05-12-37-113_512.gif?width=600&rev=1.1~" />
11866 +</div>
11867 +<div class=~"col-xs-8 art_det~">
11868 +<p class=~"text-left~">
11869 +Aankondiging update Syntess 6.9.0181 <br/><span class=~"date_info~"> Dec 12, 2023, </span>
11870 +</p>
11871 +<div class=~"row post-details~">
11872 +<div class=~"col-xs-8 detail~">
11873 +<div class=~"post-likes btn btn-default disabled badge~"
11874 +title=~"Number of likes on this page: 0~">
11875 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">0</span>
11876 +</div>
11877 +</div>
11878 +<div class=~"col-xs-4 com_det~">
11879 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
11880 +</div>
11881 +</div>
11882 +</div>
11883 +</div>
11884 +</a>
11885 +</div>" class="macro macro hidden macro-placeholder" %)macro:html
11886 +)))
11887 +)))
11888 +
11889 +(% class="row flex-container" %)
11890 +(((
11891 +(% class="col-xs-12 col-sm-6 next_blog" %)
11892 +(((
11893 +(% class="row" %)
11894 +(((
11895 +(% class="col-xs-4" %)
11896 +(((
11897 +[[~[~[image:/download/Nieuws/Aankondiging%20update%20Syntess%206.9.0181/05-12-37-113_512.gif?width=600&rev=1.1~]~]>>path:/Nieuws/Aankondiging%20update%20Syntess%206.9.0181||class="thumbnail"]]
11898 +)))
11899 +
11900 +(% class="col-xs-8 art_det" %)
11901 +(((
11902 +(% class="text-left" %)
11903 +[[Aankondiging update Syntess 6.9.0181
11904 +(% class="date_info" %) Dec 12, 2023,>>path:/Nieuws/Aankondiging%20update%20Syntess%206.9.0181||class="thumbnail"]]
11905 +
11906 +(% class="row post-details" %)
11907 +(((
11908 +(% class="col-xs-8 detail" %)
11909 +(((
11910 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 0" %)
11911 +(((
11912 +[[(% class="like-number" %)0>>path:/Nieuws/Aankondiging%20update%20Syntess%206.9.0181||class="thumbnail"]]
11913 +)))
11914 +)))
11915 +
11916 +(% class="col-xs-4 com_det" %)
11917 +(((
11918 +(% class="text-right" %)
11919 +[[(0)>>path:/Nieuws/Aankondiging%20update%20Syntess%206.9.0181||class="thumbnail"]]
11920 +)))
11921 +)))
11922 +)))
11923 +)))
11924 +)))
11925 +
11926 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Nieuwsbrief oktober 2023~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG|postIndex=3|previousPostReference=Nieuws.Nieuwsbrief december 2023|postIndex=4|previousPostReference=Nieuws.Nieuwsbrief november 2023|postIndex=5|previousPostReference=Nieuws.Feestelijke afsluiting, keuring materieel en tellen voorraden|postIndex=6|previousPostReference=Nieuws.RI&E 2023|postIndex=7|previousPostReference=Nieuws.Aankondiging update Syntess 6\\\\.9\\\\.0181~"" %)
11927 +(((
11928 +(% class="macro-placeholder hidden" %)
11929 +(((
11930 +macro:blogPostLayoutCards
11931 +)))
11932 +
11933 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
11934 +(((
11935 +(% class="macro-placeholder hidden" %)
11936 +(((
11937 +macro:include
11938 +)))
11939 +
11940 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
11941 +(((
11942 +(% class="macro-placeholder hidden" %)
11943 +(((
11944 +macro:include
11945 +)))
11946 +
11947 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
11948 +#set($blogClassname = 'Blog.BlogClass')
11949 +#set($blogTemplate = 'Blog.BlogTemplate')
11950 +#set($blogSheet = 'Blog.BlogSheet')
11951 +## Blog entries
11952 +#set($blogPostClassname = 'Blog.BlogPostClass')
11953 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
11954 +#set($blogPostSheet = 'Blog.BlogPostSheet')
11955 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
11956 +#set($oldArticleClassname = 'XWiki.ArticleClass')
11957 +## Categories
11958 +#set($blogCategoryClassname = 'Blog.CategoryClass')
11959 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
11960 +#set($blogCategorySheet = 'Blog.CategorySheet')
11961 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
11962 +#set($oldBlogCategoryClassname = 'Blog.Categories')
11963 +#set($defaultCategoryParent = 'Blog.Categories')
11964 +## Style
11965 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
11966 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
11967 +## Clientside scripts
11968 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
11969 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
11970 +## Misc
11971 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
11972 +#set($isBlogPost = $doc.getObject($blogPostClassname))
11973 +#set($defaultBlogSpace = 'Blog')
11974 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
11975 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
11976 +##
11977 +##
11978 +##
11979 +#**
11980 + * Displays an image, taken from the blog style document.
11981 + *
11982 + * @param $imgName The name of the icon from icons set to use.
11983 + *#
11984 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
11985 +(((
11986 +(% class="macro-placeholder hidden" %)
11987 +(((
11988 +macro:velocity
11989 +)))
11990 +)))
11991 +)))
11992 +
11993 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
11994 +##
11995 +##
11996 +## Import the blog skin and javascripts.
11997 +$!xwiki.ssx.use($blogStyleDocumentName)##
11998 +$!xwiki.jsx.use($blogScriptsDocumentName)##
11999 +##
12000 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
12001 +#template('hierarchy_macros.vm')##
12002 +##
12003 +##
12004 +#**
12005 + * Prints a blog. This is the main macro used in the BlogSheet.
12006 + *
12007 + * @param blogDoc the XDocument holding the blog definition object.
12008 + *###
12009 +#macro(printBlog $blogDoc)
12010 + \{\{include reference='Blog.CreatePost'/}}
12011 +
12012 + ## Use the blogPostList macro to display the blogposts
12013 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
12014 + ## do not support FTM the monthly and weekly blog display types
12015 + #getBlogDisplayType($blogDoc $displayType)
12016 + #if ($displayType == 'weekly' || $displayType == 'monthly')
12017 + #getBlogEntries($blogDoc $entries)
12018 + #displayBlog($entries 'index' true true)
12019 + #displayNavigationLinks($blogDoc)
12020 + #else
12021 + #getBlogDisplayType($blogDoc $displayType)
12022 + #set ($paginated = 'no')
12023 + #if ($displayType == 'paginated')
12024 + #set ($paginated = 'yes')
12025 + #end
12026 + #getBlogPostsLayout($blogDoc $postsLayout)
12027 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
12028 + #end
12029 +#end
12030 +##
12031 +##
12032 +##
12033 +#**
12034 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
12035 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
12036 + * all entries).
12037 + *
12038 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12039 + *###
12040 +#macro(showBlogInfo $blogDoc)
12041 + #if($blogDoc.getObject($blogClassname))
12042 + ## Keep testing for inline action for backward compatibility with older blogs.
12043 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
12044 + #macro(displayProperty $blogDoc $propname)
12045 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
12046 + : $blogDoc.display($propname)
12047 + #end
12048 + #displayProperty($blogDoc 'title')
12049 + #displayProperty($blogDoc 'description')
12050 + #displayProperty($blogDoc 'displayType')
12051 + #displayProperty($blogDoc 'itemsPerPage')
12052 + #displayProperty($blogDoc 'postsLayout')
12053 + #displayProperty($blogDoc 'postsLayoutParameters')
12054 + #else
12055 + $blogDoc.display('description')
12056 + #end
12057 + #elseif($doc.fullName == $blogSheet)
12058 += $services.localization.render('blog.code.blogsheet') =
12059 + \{\{translation key='blog.code.sheetexplanation'/}}
12060 + #else
12061 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
12062 + #end
12063 +#end
12064 +##
12065 +##
12066 +##
12067 +#**
12068 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
12069 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
12070 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
12071 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
12072 + *
12073 + * @param space A <tt>String</tt>, the name of the space where to search.
12074 + * @param blogDoc The resulting XDocument.
12075 + *###
12076 +#macro(getBlogDocument $space $blogDoc)
12077 + #set ($result = $NULL)
12078 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
12079 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
12080 + ## identify the right blog based on a configuration object in a WebPreferences page.
12081 + #set ($spaceReference = $services.model.resolveSpace($space))
12082 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
12083 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
12084 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
12085 + #if ($preferencesObj)
12086 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
12087 + #end
12088 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
12089 + #if (~"$!result~" == '')
12090 + ## First, try the Space.WebHome, for a whole-space blog
12091 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
12092 + #if(!$result.getObject($blogClassname))
12093 + ## Second, try the Space.Blog document
12094 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
12095 + #if(!$result.getObject($blogClassname))
12096 + ## Third, try searching for a blog document in the current space
12097 + ## Prevent the query fail when the space contains dots '.'
12098 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
12099 + #if($blogDocs.size() > 0)
12100 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
12101 + #else
12102 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
12103 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
12104 + #if($blogDocs.size() > 0)
12105 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
12106 + #else
12107 + ## Last, fallback to Blog.WebHome, the default blog
12108 + #set($result = $xwiki.getDocument('Blog.WebHome'))
12109 + #end
12110 + #end
12111 + #end
12112 + #end
12113 + #end
12114 + #set ($blogDoc = $NULL)
12115 + #setVariable (~"$blogDoc~" $result)
12116 +#end
12117 +##
12118 +##
12119 +##
12120 +#**
12121 + * Retrieve the blog title.
12122 + *
12123 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
12124 + * @param title The resulting title.
12125 + *###
12126 +#macro(getBlogTitle $blogDoc $title)
12127 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
12128 + #set ($title = $NULL)
12129 + #setVariable (~"$title~" $!blogDoc.displayTitle)
12130 +#end
12131 +##
12132 +##
12133 +##
12134 +#**
12135 + * Retrieve the blog description.
12136 + *
12137 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
12138 + * property set.
12139 + * @param description The resulting description.
12140 + *###
12141 +#macro(getBlogDescription $blogDoc $description)
12142 + #getBlogProperty($blogDoc 'description' '' $result)
12143 + #set ($description = $NULL)
12144 + #setVariable (~"$description~" $result)
12145 +#end
12146 +##
12147 +##
12148 +##
12149 +#**
12150 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
12151 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
12152 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
12153 + * month), or all.
12154 + *
12155 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12156 + * @param entries The resulting list of entries to display, a list of XDocument names.
12157 + *###
12158 +#macro(getBlogEntries $blogDoc $entries)
12159 + #if (!$entries)
12160 + #setVariable (~"$entries~" [])
12161 + #end
12162 + #getAllBlogPostsQuery($query)
12163 + #isDefaultBlog($blogDoc $isDefault)
12164 + #set($queryParams = \{})
12165 + #if ($isDefault)
12166 + #getCategoryAllBlogPostsQuery($query)
12167 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
12168 + #set($discard = $queryParams.put('creator', $xcontext.user))
12169 + #set($discard = $queryParams.put('space', $blogDoc.space))
12170 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
12171 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
12172 + #else
12173 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
12174 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
12175 + #set($discard = $queryParams.put('space', $blogPostsLocation))
12176 + #set($discard = $queryParams.put('parent', $blogDoc.space))
12177 + #end
12178 + #getBlogDisplayType($blogDoc $displayType)
12179 + #if($displayType == 'weekly')
12180 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
12181 + #elseif($displayType == 'monthly')
12182 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
12183 + #elseif($displayType == 'all')
12184 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
12185 + #else
12186 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
12187 + #end
12188 +#end
12189 +##
12190 +##
12191 +##
12192 +#**
12193 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
12194 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
12195 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
12196 + * (10 if not defined).
12197 + *
12198 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12199 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
12200 + * refined to restrict to a given space, or to a given search criteria, etc.
12201 + * @param entries The resulting list of entries to display, a list of XDocument names.
12202 + * @param queryParams The parameters to bind with the query.
12203 + *###
12204 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
12205 + #if (!$entries)
12206 + #setVariable (~"$entries~" [])
12207 + #end
12208 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
12209 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
12210 + #bindQueryParameters($countQueryObj $queryParams)
12211 + #bindQueryParameters($queryObj $queryParams)
12212 + #set($totalEntries = $countQueryObj.count())
12213 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
12214 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
12215 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
12216 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
12217 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
12218 +#end
12219 +##
12220 +##
12221 +##
12222 +#**
12223 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
12224 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
12225 + * digit year). Initially the current week is displayed.
12226 + *
12227 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12228 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
12229 + * refined to restrict to a given space, or to a given search criteria, etc.
12230 + * @param entries The resulting list of entries to display, a list of XDocument names.
12231 + * @param queryParams The parameters to bind with the query.
12232 + *###
12233 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
12234 + #if (!$entries)
12235 + #setVariable (~"$entries~" [])
12236 + #end
12237 + #getRequestedWeek($weekDate)
12238 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
12239 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
12240 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
12241 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
12242 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
12243 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
12244 + #bindQueryParameters($countQueryObj $queryParams)
12245 + #bindQueryParameters($queryObj $queryParams)
12246 + #set($totalEntries = $countQueryObj.count())
12247 + #set($discard = $entries.addAll($queryObj.execute()))
12248 +#end
12249 +##
12250 +##
12251 +##
12252 +#**
12253 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
12254 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
12255 + * digit year). Initially the current month is displayed.
12256 + *
12257 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12258 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
12259 + * refined to restrict to a given space, or to a given search criteria, etc.
12260 + * @param entries The resulting list of entries to display, a list of XDocument names.
12261 + * @param queryParams The parameters to bind with the query.
12262 + *###
12263 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
12264 + #if (!$entries)
12265 + #setVariable (~"$entries~" [])
12266 + #end
12267 + #getRequestedMonth($monthDate)
12268 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
12269 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
12270 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
12271 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
12272 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
12273 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
12274 + #bindQueryParameters($countQueryObj $queryParams)
12275 + #bindQueryParameters($queryObj $queryParams)
12276 + #set($totalEntries = $countQueryObj.count())
12277 + #set($discard = $entries.addAll($queryObj.execute()))
12278 +#end
12279 +##
12280 +##
12281 +##
12282 +#**
12283 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
12284 + *
12285 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12286 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
12287 + * refined to restrict to a given space, or to a given search criteria, etc.
12288 + * @param entries The resulting list of entries to display, a list of XDocument names.
12289 + * @param queryParams The parameters to bind with the query.
12290 + *###
12291 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
12292 + #if (!$entries)
12293 + #setVariable (~"$entries~" [])
12294 + #end
12295 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
12296 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
12297 + #bindQueryParameters($countQueryObj $queryParams)
12298 + #bindQueryParameters($queryObj $queryParams)
12299 + #set($totalEntries = $countQueryObj.count())
12300 + #set($discard = $entries.addAll($queryObj.execute()))
12301 +#end
12302 +##
12303 +##
12304 +##
12305 +#**
12306 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
12307 + *
12308 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12309 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
12310 + * refined to restrict to a given space, or to a given search criteria, etc.
12311 + * @param queryParams The parameters to bind with the query.
12312 + * @param entries The resulting list of entries to display, a list of XDocument names.
12313 + *###
12314 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
12315 + #if (!$entries)
12316 + #setVariable (~"$entries~" [])
12317 + #end
12318 + #set($query = ~"$\{query} and isPublished.value = 0~")
12319 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
12320 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
12321 + #bindQueryParameters($countQueryObj $queryParams)
12322 + #bindQueryParameters($queryObj $queryParams)
12323 + #set($totalEntries = $countQueryObj.count())
12324 + #set($discard = $entries.addAll($queryObj.execute()))
12325 +#end
12326 +##
12327 +##
12328 +##
12329 +#**
12330 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
12331 + *
12332 + * @param entries The resulting list of entries to display, a list of XDocument names.
12333 + *###
12334 +#macro(getGlobalBlogEntries $entries)
12335 + #if (!$entries)
12336 + #setVariable (~"$entries~" [])
12337 + #end
12338 + #getAllBlogPostsQuery($query)
12339 + #set($totalEntries = $services.query.hql($query).count())
12340 + #set($defaultItemsPerPage = 20)
12341 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
12342 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
12343 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
12344 +#end
12345 +#**
12346 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
12347 + * blog, nor specify a range or an ordering criteria.
12348 + *
12349 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
12350 + *
12351 + * @param query The basic query for selecting blog entries.
12352 + *#
12353 +#macro(getBlogEntriesBaseQuery $query)
12354 + #getAllBlogPostsQuery($query)
12355 +#end
12356 +#**
12357 + * Return the Query for selecting the all wiki blog posts without filtering
12358 + *
12359 + * @param query The basic query for selecting blog entries.
12360 + *#
12361 +#macro(getAllBlogPostsQuery $query)
12362 + #set ($query = $NULL)
12363 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
12364 + IntegerProperty hidden, DateProperty publishDate
12365 + where doc.fullName <> '$blogPostTemplate' and
12366 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
12367 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
12368 + hidden.id.id = obj.id and hidden.id.name='hidden' and
12369 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
12370 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
12371 +#end
12372 +##
12373 +##
12374 +##
12375 +###**
12376 + * Return the Query for selecting the all wiki blog posts with categories filtering
12377 + *
12378 + * @param query The basic query for selecting blog entries.
12379 + *###
12380 +#macro(getCategoryAllBlogPostsQuery $query)
12381 + #set ($query = $NULL)
12382 + #getAllBlogPostsQuery($baseQuery)
12383 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
12384 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
12385 +#end
12386 +##
12387 +##
12388 +##
12389 +#**
12390 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
12391 + * week), monthly (all entries in a month), or all.
12392 + *
12393 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
12394 + * property set.
12395 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
12396 + *###
12397 +#macro(getBlogDisplayType $blogDoc $displayType)
12398 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
12399 + #set ($displayType = $NULL)
12400 + #setVariable (~"$displayType~" $result)
12401 +#end
12402 +##
12403 +##
12404 +##
12405 +#**
12406 + * Displays a list of entries.
12407 + *
12408 + * @param entries The entries to display, a list of XDocument names.
12409 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
12410 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
12411 + * used values: index, single, category, search, unpublished, hidden.
12412 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
12413 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
12414 + * displayed alone on their page since it's the page title which is used in this case)
12415 + *###
12416 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
12417 + #set($blogDay = '')
12418 + (% class=~"hfeed $!\{displaying}~" ~%)(((
12419 + (% class=~"blogDay~" ~%)(((
12420 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
12421 + #getEntryObject($entryDoc $entryObj)
12422 + ## Although all entries should have one of the two objects, better check to be sure.
12423 + #if(~"$!\{entryObj}~" != '')
12424 + #getEntryDate($entryDoc $entryObj $entryDate)
12425 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
12426 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
12427 + #if($blogDay != $entryDateStr)
12428 + #if($blogDay != '')
12429 + )))
12430 + (% class=~"blogDay~" ~%)(((
12431 + #end
12432 + #displayBlogDate($entryDate)
12433 + #set ($blogDay = $entryDateStr)
12434 + #end
12435 + ## Finally, display the entry.
12436 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
12437 + #end
12438 + #end
12439 + )))## blogDay
12440 + )))## hfeed
12441 +#end
12442 +##
12443 +##
12444 +##
12445 +#**
12446 + * Get the entry object, either a new BlogPost or an old Article.
12447 + *
12448 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12449 + * @param entryObj The resulting xobject of the blog post.
12450 + *###
12451 +#macro(getEntryObject $entryDoc $__entryObj)
12452 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
12453 + #if(!$result)
12454 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
12455 + #end
12456 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
12457 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
12458 + ## overwritten in this case but it's less likely to have such a variable defined before.
12459 + #set ($__entryObj = $NULL)
12460 + #setVariable (~"$__entryObj~" $result)
12461 +#end
12462 +##
12463 +##
12464 +##
12465 +#**
12466 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
12467 + * the document creation date, but can be edited by the user.
12468 + *
12469 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12470 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12471 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
12472 + *###
12473 +#macro(getEntryDate $entryDoc $entryObj $result)
12474 + #set ($result = $NULL)
12475 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
12476 +#end
12477 +##
12478 +##
12479 +##
12480 +#**
12481 + * Displays a date, nicely formatted as a calendar page.
12482 + *
12483 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
12484 + *###
12485 +#macro(displayBlogDate $date)
12486 + #set($year = $xwiki.formatDate($date, 'yyyy'))
12487 + ## 3 letter month name, like Jan, Dec.
12488 + #set($month = $xwiki.formatDate($date, 'MMM'))
12489 + ## Uncomment to get a full length month name, like January, December.
12490 + ## TODO: this could be defined somewhere in the blog style.
12491 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
12492 + #set($day = $xwiki.formatDate($date, 'dd'))
12493 + (% class=~"blogdate~" ~%)
12494 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
12495 +#end
12496 +##
12497 +##
12498 +##
12499 +#**
12500 + * Displays a blog article: management tools, header, content, footer.
12501 + *
12502 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12503 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12504 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
12505 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
12506 + * when they're displayed alone on their page since it's the page title which is used in this case)
12507 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
12508 + *###
12509 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
12510 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
12511 + #isPublished($entryObj $isPublished)
12512 + #isHidden($entryObj $isHidden)
12513 + #if($doc.fullName == $entryDoc.fullName)
12514 + (% class=~"hentry single-article~" ~%)(((
12515 + #else
12516 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
12517 + #end
12518 + #if ($shouldDisplayActions)
12519 + #displayEntryTools($entryDoc $entryObj)
12520 + #end
12521 + #if($shouldDisplayTitle)
12522 + #displayEntryTitle($entryDoc $entryObj)
12523 + #end
12524 + #if($doc.fullName == $entryDoc.fullName)
12525 + #if(!$isPublished)
12526 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
12527 + #elseif($isHidden)
12528 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
12529 + #end
12530 + #end
12531 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
12532 + #displayEntryFooter($entryDoc $entryObj)
12533 + )))## hentry
12534 +#end
12535 +##
12536 +##
12537 +##
12538 +#**
12539 + * Checks if the provided blog is published or not.
12540 + *
12541 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12542 + * @param isPublished The resulting boolean, true if the entry is considered published.
12543 + *###
12544 +#macro(isPublished $entryObj $isPublished)
12545 + #set ($isPublished = $NULL)
12546 + ## This should work for both old articles, which don't have the 'published' property at all, and
12547 + ## are considered published by default, and new entries, that should have 1 if published.
12548 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
12549 + #setVariable (~"$isPublished~" true)
12550 + #else
12551 + #setVariable (~"$isPublished~" false)
12552 + #end
12553 +#end
12554 +##
12555 +##
12556 +##
12557 +#**
12558 + * Checks if the provided blog is hidden or not.
12559 + *
12560 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
12561 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
12562 + *###
12563 +#macro(isHidden $entryObj $isHidden)
12564 + #set ($isHidden = $NULL)
12565 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
12566 + ## are considered visible by default, and new entries, that should have 1 if hidden.
12567 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
12568 + #setVariable (~"$isHidden~" true)
12569 + #else
12570 + #setVariable (~"$isHidden~" false)
12571 + #end
12572 +#end
12573 +##
12574 +##
12575 +##
12576 +#**
12577 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
12578 + *
12579 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12580 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12581 + *###
12582 +#macro(displayEntryTools $entryDoc $entryObj)
12583 + #if($xcontext.action == 'view')
12584 + (% class=~"blog-entry-toolbox~" ~%)(((
12585 + #displayPublishButton($entryDoc $entryObj)
12586 + #displayHideShowButton($entryDoc $entryObj)
12587 + #displayEditButton($entryDoc $entryObj)
12588 + #displayDeleteButton($entryDoc $entryObj)
12589 + )))
12590 + #end
12591 +#end
12592 +##
12593 +##
12594 +##
12595 +#**
12596 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
12597 + *
12598 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12599 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12600 + * @todo AJAX calls.
12601 + *###
12602 +#macro(displayPublishButton $entryDoc $entryObj)
12603 + #isPublished($entryObj $isPublished)
12604 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
12605 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
12606 + #end
12607 +#end
12608 +##
12609 +##
12610 +##
12611 +#**
12612 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
12613 + *
12614 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12615 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12616 + *###
12617 +#macro(displayHideShowButton $entryDoc $entryObj)
12618 + #isPublished($entryObj $isPublished)
12619 + #isHidden($entryObj $isHidden)
12620 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
12621 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
12622 + #set ($queryString = \{
12623 + 'xredirect' : $thisURL,
12624 + 'form_token' : $services.csrf.getToken()
12625 + })
12626 + #if ($isHidden)
12627 + #set ($discard = $queryString.putAll(\{
12628 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
12629 + 'comment' : $services.localization.render('blog.code.madevisible')
12630 + }))
12631 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
12632 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
12633 + #else
12634 + #set ($discard = $queryString.putAll(\{
12635 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
12636 + 'comment' : $services.localization.render('blog.code.hid')
12637 + }))
12638 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
12639 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
12640 + #end
12641 + #end
12642 +#end
12643 +##
12644 +##
12645 +##
12646 +#**
12647 + * Displays the edit button to those that can edit the article.
12648 + *
12649 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12650 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12651 + *###
12652 +#macro(displayEditButton $entryDoc $entryObj)
12653 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
12654 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
12655 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
12656 + #end
12657 +#end
12658 +##
12659 +##
12660 +##
12661 +#**
12662 + * Displays the delete button to those that can edit the article.
12663 + *
12664 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12665 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12666 + * @todo AJAX calls.
12667 + *###
12668 +#macro(displayDeleteButton $entryDoc $entryObj)
12669 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
12670 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
12671 + #end
12672 +#end
12673 +##
12674 +##
12675 +##
12676 +#**
12677 + * Displays the title of the entry.
12678 + *
12679 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12680 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12681 + *###
12682 +#macro(displayEntryTitle $entryDoc $entryObj)
12683 + #if($doc.fullName == $entryDoc.fullName)
12684 + (% class=~"entry-title~" ~%)
12685 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
12686 + #else
12687 + (% class=~"entry-title~" ~%)
12688 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
12689 + #end
12690 +#end
12691 +##
12692 +##
12693 +##
12694 +#**
12695 + * Displays the body of the entry.
12696 + *
12697 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12698 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12699 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
12700 + *###
12701 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
12702 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
12703 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
12704 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
12705 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
12706 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
12707 + ))) ## entry-content
12708 + (% class=~"clearfloats~" ~%)((()))
12709 +#end
12710 +##
12711 +##
12712 +##
12713 +#**
12714 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
12715 + * of the <tt>extract</tt> field (if not empty).
12716 + *
12717 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12718 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12719 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
12720 + * @param entryContent The resulting content.
12721 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
12722 + * <tt>onlyExtract</tt> is <tt>true</tt>)
12723 + *###
12724 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
12725 + #if ($onlyExtract)
12726 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
12727 + ## of the content.
12728 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
12729 + #end
12730 + #if(~"$!macro.result~" == '')
12731 + #set($macro.result = $entryObj.getProperty('content').value)
12732 +#* Disabled until the content can be cleanly cut.
12733 +* #if($onlyExtract && $result.length()>$maxchars)
12734 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
12735 +* #set($i = $i + 1)
12736 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
12737 +* #end
12738 +## *###
12739 + #elseif (!$removeEllipsis)
12740 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
12741 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
12742 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
12743 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
12744 + #end
12745 + #end
12746 + #set ($entryContent = $NULL)
12747 + #setVariable (~"$entryContent~" $macro.result)
12748 +#end
12749 +##
12750 +##
12751 +##
12752 +#**
12753 + * Displays the footer of the entry.
12754 + *
12755 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12756 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12757 + *###
12758 +#macro(displayEntryFooter $entryDoc $entryObj)
12759 + (% class=~"entry-footer~" ~%)(((
12760 + #isPublished($entryObj $isPublished)
12761 + (% class='entry-author-label' ~%)
12762 + #if($isPublished)
12763 + \{\{translation key='blog.code.postedby'/}} ##
12764 + #else
12765 + \{\{translation key='blog.code.createdby'/}} ##
12766 + #end
12767 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
12768 + #getEntryDate($entryDoc $entryObj $entryDate)
12769 + #listCategories($entryObj) #*
12770 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
12771 + ## we assume cannot be more than 3 seconds.
12772 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
12773 + #if ($showcomments)
12774 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
12775 + #end ##
12776 + #if($entryDoc != $doc) ##
12777 + #displayEntryBlogLocation($entryDoc $entryObj) ##
12778 + #end
12779 + )))## entry-footer
12780 +#end
12781 +##
12782 +##
12783 +#**
12784 + * Display the blog for the entry (if it is not the currently displayed blog)
12785 + *
12786 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
12787 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12788 + *###
12789 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
12790 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
12791 + #if(~"$!blogPostsLocation~" != ~"~") ##
12792 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
12793 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
12794 + #if($doc.documentReference != $blogDocRef) ##
12795 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
12796 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
12797 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
12798 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
12799 + )))(%~%)##
12800 + #end
12801 + #end
12802 + #end
12803 +#end
12804 +##
12805 +##
12806 +##
12807 +##
12808 +#**
12809 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
12810 + *
12811 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
12812 + *###
12813 +#macro(listCategories $entryObj)
12814 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
12815 + #set($categories = $entryObj.getProperty('category').value)
12816 + #set($first = true)
12817 + #if($categories.size() > 0)
12818 + #foreach($category in $categories)
12819 + #set($categoryDoc = $!xwiki.getDocument($category))
12820 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
12821 + #if($foreach.count == 1)
12822 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
12823 + #else
12824 + , ##
12825 + #end##
12826 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
12827 + #end##
12828 + #end##
12829 + #end
12830 + #end
12831 +#end
12832 +##
12833 +##
12834 +##
12835 +#**
12836 + * Displays blog pagination links (older and newer entries).
12837 + *
12838 + * @param blogDoc the XDocument holding the blog definition object.
12839 + *###
12840 +#macro(displayNavigationLinks $blogDoc)
12841 + (% class=~"clearfloats~" ~%)((()))
12842 + #getBlogDisplayType($blogDoc $displayType)
12843 + #if($displayType == 'weekly')
12844 + (% class=~"pagingLinks~" ~%)(((
12845 + #getRequestedWeek($weekDate)
12846 + $weekDate.addWeeks(-1)##
12847 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
12848 + #sep()
12849 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
12850 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
12851 + )))
12852 + #elseif($displayType == 'monthly')
12853 + (% class=~"pagingLinks~" ~%)(((
12854 + #getRequestedMonth($monthDate)
12855 + $monthDate.addMonths(-1)##
12856 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
12857 + #sep()
12858 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
12859 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
12860 + )))
12861 + #elseif($displayType == 'all')
12862 + #else
12863 + ## Paginated
12864 + #if(($totalPages > 1))
12865 + #set($queryString = '')
12866 + #foreach($p in $request.getParameterNames())
12867 + #if($p != 'page' && $p != 'ipp')
12868 + #foreach($v in $request.getParameterValues($p))
12869 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
12870 + #end
12871 + #end
12872 + #end
12873 + (% class=~"pagingLinks~" ~%)(((
12874 + #if ($currentPageNumber < $totalPages)
12875 + #set($currentPageNumber = $currentPageNumber + 1)
12876 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
12877 + #set($currentPageNumber = $currentPageNumber - 1)
12878 + #end
12879 + #if ($currentPageNumber > 1)
12880 + #if ($currentPageNumber < $totalPages)
12881 + #sep()
12882 + #end
12883 + #set($currentPageNumber = $currentPageNumber - 1)
12884 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
12885 + #set($currentPageNumber = $currentPageNumber + 1)
12886 + #end
12887 + (% class=~"clear~" ~%)(%~%)
12888 + )))## pagingLinks
12889 + #end
12890 + #end
12891 +#end
12892 +##
12893 +##
12894 +##
12895 +#**
12896 + * Displays a message box with ~"publish~" icon.
12897 + *
12898 + * @param message A text message concerning blog article publishing
12899 + *###
12900 +#macro(publishMessageBox $message)
12901 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
12902 +#end
12903 +#**
12904 + * Displays a message box with ~"show/hide~" icon.
12905 + *
12906 + * @param message A text message concerning blog article hiding
12907 + *###
12908 +#macro(hideMessageBox $message)
12909 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
12910 +#end
12911 +##
12912 +##
12913 +##
12914 +#**
12915 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
12916 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
12917 + *
12918 + * @param monthDate The resulting week, a JODATime MutableDateTime.
12919 + *###
12920 +#macro(getRequestedWeek $weekDate)
12921 + #set ($weekDate = $NULL)
12922 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
12923 + #if(~"$!\{request.year}~" != '')
12924 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
12925 + #end
12926 + #if(~"$!\{request.week}~" != '')
12927 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
12928 + #end
12929 +#end
12930 +##
12931 +##
12932 +##
12933 +#**
12934 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
12935 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
12936 + *
12937 + * @param monthDate The resulting month, a JODATime MutableDateTime.
12938 + *###
12939 +#macro(getRequestedMonth $monthDate)
12940 + #set ($monthDate = $NULL)
12941 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
12942 + #if(~"$!\{request.year}~" != '')
12943 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
12944 + #end
12945 + #if(~"$!\{request.month}~" != '')
12946 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
12947 + #end
12948 +#end
12949 +##
12950 +##
12951 +##
12952 +#**
12953 + * Retrieve a blog property (title, display type, etc).
12954 + *
12955 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12956 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
12957 + * @param defaultValue The default value to use in case the blog object does not define one.
12958 + * @param propertyValue The resulting value.
12959 + *###
12960 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
12961 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
12962 + #if($result == '')
12963 + #set($result = $defaultValue)
12964 + #end
12965 + #set ($propertyValue = $NULL)
12966 + #setVariable (~"$propertyValue~" $result)
12967 +#end
12968 +
12969 +#**
12970 + * If an error occurs when executing an action, set a specific response status and display an error message.
12971 + *
12972 + * @param status The response status.
12973 + * @param text The user readable error to be displayed. Can be a translation key.
12974 + * @param parameters The parameters to use when decoding the translation key.
12975 + *###
12976 +#macro(blog__actionResponseError $status $text $parameters)
12977 + $response.setStatus($status)
12978 + #if($request.ajax)
12979 + $services.localization.render($text, $!parameters)
12980 + #else
12981 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
12982 + #end
12983 +#end
12984 +##
12985 +##
12986 +##
12987 +#**
12988 + * Check if a blog is the Default blog (The one in the 'Blog' space).
12989 + *
12990 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
12991 + * @param isDefault The resulting boolean.
12992 + *###
12993 +#macro(isDefaultBlog $blogDoc $isDefault)
12994 + #set ($result = false)
12995 + #if ($blogDoc.space == 'Blog')
12996 + #set ($result = true)
12997 + #end
12998 + #setVariable(~"$isDefault~" $result)
12999 +#end
13000 +##
13001 +##
13002 +##
13003 +#**
13004 + * Retrieve the blog posts location (space).
13005 + *
13006 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
13007 + * @param postsLocation The resulting location.
13008 + *###
13009 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
13010 + #getBlogDocument($blogSpace $blogDoc)
13011 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
13012 + #set ($postsLocation = $NULL)
13013 + #setVariable (~"$postsLocation~" $result)
13014 +#end
13015 +##
13016 +##
13017 +##
13018 +#**
13019 + * Retrieve the blog categories location (space).
13020 + *
13021 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
13022 + * @param categoriesLocation The resulting location.
13023 + *###
13024 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
13025 + #getBlogDocument($blogSpace $blogDoc)
13026 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
13027 + #set ($postsLocation = $NULL)
13028 + #setVariable (~"$categoriesLocation~" $result)
13029 +#end
13030 +###**
13031 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
13032 + * for example there is 4 different panel contexts:
13033 + * aBlog.aPost or aBlog.WebHome
13034 + * aCategorySpace.aCategory
13035 + * aCategorySpace.WebHome
13036 + * Blog.aPost or Blog.WebHome
13037 + *
13038 + * @param query The query for selecting blog entries.
13039 + * @param queryParams The parameters to bind with the generated query.
13040 + * @param targetDoc The document in which the articles will be displayed.
13041 + *###
13042 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
13043 + #set ($query = $NULL)
13044 + #set ($queryParams = $NULL)
13045 + #getCategoryAllBlogPostsQuery($resultQuery)
13046 + #set ($resultQueryParams = \{})
13047 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
13048 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
13049 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
13050 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
13051 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
13052 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
13053 + #elseif($targetDoc.getObject($blogCategoryClassname))
13054 + ## Get all posts that are in a category aCategorySpace.aCategory
13055 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
13056 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
13057 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
13058 + ## Get all posts that are in a category aCategorySpace.%
13059 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
13060 + ## Exclude incategorized posts
13061 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
13062 + #if ($targetDoc.space == $defaultBlogSpace)
13063 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
13064 + #end
13065 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
13066 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
13067 + #else
13068 + ## Get all posts in blog space aBlog
13069 + #getAllBlogPostsQuery($resultQuery)
13070 + #getBlogPostsLocation($targetDoc.space $postsLocation)
13071 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
13072 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
13073 + #end
13074 + #setVariable(~"$query~" $resultQuery)
13075 + #setVariable(~"$queryParams~" $resultQueryParams)
13076 +#end
13077 +##
13078 +##
13079 +##
13080 +###**
13081 + * Display blog posts based on the context where the posts are displayed.
13082 + * for example there is 4 different panel contexts:
13083 + * aBlog.aPost or aBlog.WebHome
13084 + * aCategorySpace.aCategory
13085 + * aCategorySpace.WebHome
13086 + * Blog.aPost or Blog.WebHome
13087 + *
13088 + * @param targetDoc The document in which the articles will be displayed.
13089 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
13090 + * @param layout Layout of the the posts to display
13091 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
13092 + * @param limit the number of posts to display
13093 + *###
13094 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
13095 + #if ($postLayout == 'full')
13096 + #set ($macro.paginated = 'yes')
13097 + #end
13098 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
13099 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
13100 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
13101 + #if (~"$!layout~" == '')
13102 + #set ($layout = $postsLayout)
13103 + #end
13104 + #if ($postsVisiblity == 'recent')
13105 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
13106 + #elseif($postsVisiblity == 'unpublished')
13107 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
13108 + #end
13109 + #elseif($targetDoc.getObject($blogCategoryClassname))
13110 + ## Display all posts that are in a category aCategorySpace.aCategory
13111 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
13112 + #getBlogPostsLayout($blogDoc $postsLayout)
13113 + #if (~"$!layout~" == '')
13114 + #set ($layout = $postsLayout)
13115 + #end
13116 + #if ($postsVisiblity == 'recent')
13117 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
13118 + #elseif($postsVisiblity == 'unpublished')
13119 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
13120 + #end
13121 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
13122 + ## Display all posts that are in a category aCategorySpace.%
13123 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
13124 + #getBlogPostsLayout($blogDoc $postsLayout)
13125 + #if (~"$!layout~" == '')
13126 + #set ($layout = $postsLayout)
13127 + #end
13128 + #if ($postsVisiblity == 'recent')
13129 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
13130 + #elseif($postsVisiblity == 'unpublished')
13131 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
13132 + #end
13133 + #else
13134 + ## Display all posts in blog space aBlog
13135 + #getBlogDocument($targetDoc.space $blogDoc)
13136 + #getBlogPostsLayout($blogDoc $postsLayout)
13137 + #if (~"$!layout~" == '')
13138 + #set ($layout = $postsLayout)
13139 + #end
13140 + #if ($postsVisiblity == 'recent')
13141 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
13142 + #elseif($postsVisiblity == 'unpublished')
13143 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
13144 + #end
13145 + #end
13146 +#end
13147 +##
13148 +##
13149 +##
13150 +#**
13151 + * Bind parameters to a query object.
13152 + *
13153 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
13154 + * @param queryParams the query parameters.
13155 + *###
13156 +#macro(bindQueryParameters $queryObj $queryParams)
13157 + #set ($output = $queryObj)
13158 + #foreach( $key in $queryParams.keySet() )
13159 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
13160 + #end
13161 + #setVariable(~"$queryObj~" $output)
13162 +#end
13163 +##
13164 +##
13165 +##
13166 +#**
13167 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
13168 + *
13169 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
13170 + * property set.
13171 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
13172 + *###
13173 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
13174 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
13175 + #set ($postsLayout = $NULL)
13176 + #setVariable (~"$postsLayout~" $res)
13177 +#end
13178 +##
13179 +##
13180 +##
13181 +#**
13182 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
13183 + *
13184 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
13185 + * @param blogDoc The resulting XDocument.
13186 + *###
13187 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
13188 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
13189 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
13190 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
13191 + #else
13192 + ## Fallback to Blog.WebHome, the default blog
13193 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
13194 + #end
13195 + #set ($blogDoc = $NULL)
13196 + #setVariable (~"$blogDoc~" $macro.result)
13197 +#end" %)
13198 +(((
13199 +(% class="macro-placeholder hidden" %)
13200 +(((
13201 +macro:velocity
13202 +)))
13203 +)))
13204 +)))
13205 +
13206 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
13207 +(((
13208 +(% class="macro-placeholder hidden" %)
13209 +(((
13210 +macro:include
13211 +)))
13212 +
13213 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
13214 + * Extract the layout parameters from a string.
13215 + *
13216 + * @param layoutParamsString The string representation of the layout parameters.
13217 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
13218 + * @param layoutsParameters The resulting layout parameters Map.
13219 + *###
13220 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
13221 + #set ($layoutsParameters = $NULL)
13222 + #set ($macro.layoutParams = \{})
13223 + #if (~"$!layoutParamsString~" != '')
13224 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
13225 + #foreach ($item in $macro.paramsArr)
13226 + #set ($itemSplit = $item.split('='))
13227 + #if ($itemSplit.size() == 2)
13228 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
13229 + #end
13230 + #end
13231 + #end
13232 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
13233 +#end" %)
13234 +(((
13235 +(% class="macro-placeholder hidden" %)
13236 +(((
13237 +macro:velocity
13238 +)))
13239 +)))
13240 +)))
13241 +
13242 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
13243 + #initLayoutVars($pDoc $pObj)
13244 + <div class=~"col-xs-12 col-sm-6 next_blog~">
13245 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
13246 + <div class=~"row~">
13247 + <div class=~"col-xs-4~">
13248 + #if ($imageAtt)
13249 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
13250 + #end
13251 + </div>
13252 + <div class=~"col-xs-8 art_det~">
13253 + <p class=~"text-left~">
13254 + #if($displayTitle)$!postTitle #end
13255 + <br/><span class=~"date_info~"> $!dateStr </span>
13256 + </p>
13257 + #displayPostDetails($pDoc)
13258 + </div>
13259 + </div>
13260 + </a>
13261 + </div>
13262 + #end
13263 + ##
13264 + ##
13265 + ##
13266 + #macro(displayPinnedPost $pDoc $pObj)
13267 + #initLayoutVars($pDoc $pObj)
13268 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
13269 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
13270 + <div class=~"thumbnail~">
13271 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
13272 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
13273 + #end
13274 + #if ($imageAtt)
13275 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
13276 + #end
13277 + <div class=~"caption~">
13278 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
13279 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
13280 + #end
13281 + #if ($displaySummaryOnPinnedPosts)
13282 + <div class=~"text-left post-summary~">
13283 + #set ($postContent = $pObj.getProperty('extract').value)
13284 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
13285 + </div>
13286 + #end
13287 + #displayPostDetails($pDoc)
13288 + </div>
13289 + </div>
13290 + </a>
13291 + </div>
13292 + #end
13293 + ##
13294 + ##
13295 + ##
13296 + #macro(formatPostDate $pDoc $pObj)
13297 + #set ($formattedDate = $NULL)
13298 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
13299 + #if (~"$!dateStr~" != '')
13300 + #set ($dateArr = $dateStr.split(' '))
13301 + #if ($dateArr.size() > 3)
13302 + #set ($dateStr = ~"~")
13303 + #foreach($s in $dateArr.subList(0, 3))
13304 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
13305 + #end
13306 + #end
13307 + #end
13308 + #setVariable(~"$formattedDate~" $dateStr)
13309 + #end
13310 + ##
13311 + ##
13312 + ##
13313 + #macro(displayPostDetails $pDoc)
13314 + <div class=~"row post-details~">
13315 + <div class=~"col-xs-8 detail~">
13316 + #if ($services.like.displayButton($pDoc.documentReference))
13317 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
13318 + ## Retrieve the likes number in XWiki 12.9+
13319 + #set ($likeNumber = $optLikeRecord.get())
13320 + #if (!$stringtool.isNumeric($likeNumber.toString()))
13321 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
13322 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
13323 + #end
13324 + #if ($stringtool.isNumeric($likeNumber.toString()))
13325 + <div class=~"post-likes btn btn-default disabled badge~"
13326 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
13327 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
13328 + </div>
13329 + #end
13330 + #elseif ($services.ratings)
13331 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
13332 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
13333 + <ul class=~"pull-left note list-inline~">
13334 + #foreach ($x in [1..5])
13335 + #set ($cls = ~"~")
13336 + #if ($x > $averageVote)
13337 + #set ($cls = ~"-o~")
13338 + #end
13339 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
13340 + #end
13341 + </ul>
13342 + #end
13343 + #end
13344 + </div>
13345 + #if ($showPostComments)
13346 + <div class=~"col-xs-4 com_det~">
13347 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
13348 + </div>
13349 + #end
13350 + </div>
13351 + #end
13352 + ##
13353 + ##
13354 + ##
13355 + #macro(initLayoutVars $pDoc $pObj)
13356 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
13357 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
13358 + #isPublished($pObj $isPublished)
13359 + #isHidden($pObj $isHidden)
13360 + #getEntryDate($pDoc $pObj $postDate)
13361 + #formatPostDate($postDate $dateStr)
13362 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
13363 + #set ($nbComments = $pDoc.getComments().size())
13364 + #set ($showPostComments = true)
13365 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
13366 + #set ($showPostComments = false)
13367 + #end
13368 + #end
13369 + ##
13370 + ##
13371 + ##
13372 + #macro(displayEditPinnedPostsButton)
13373 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
13374 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
13375 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
13376 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
13377 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
13378 + <div class=~"edit-pinned-posts-container~">
13379 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
13380 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
13381 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
13382 + </a>
13383 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
13384 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
13385 + </div>
13386 + </div>
13387 + #if (~"$!pinnedPostsObj~" == '')
13388 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
13389 + #end
13390 + #end
13391 + #end" %)
13392 +(((
13393 +(% class="macro-placeholder hidden" %)
13394 +(((
13395 +macro:velocity
13396 +)))
13397 +)))
13398 +
13399 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
13400 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
13401 + #getEntryObject($postDoc $postObj)
13402 + #if (~"$!postObj~" != '')
13403 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
13404 + ##
13405 + #set ($displayTitle = true)
13406 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
13407 + #set ($displayTitle = false)
13408 + #end
13409 + ##
13410 + #set ($displayTitleFirstOnPinnedPosts = false)
13411 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
13412 + #set ($displayTitleFirstOnPinnedPosts = true)
13413 + #end
13414 + ##
13415 + #set ($displaySummaryOnPinnedPosts = true)
13416 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
13417 + #set ($displaySummaryOnPinnedPosts = false)
13418 + #end
13419 + ##
13420 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
13421 + #if ($postIndex == 0)
13422 + #set ($stopBlogPostsDisplay = false)
13423 + #end
13424 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
13425 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
13426 + #set($scaleWidth = 600)
13427 + #set($imgQs=~"width=$scaleWidth~")
13428 + ## Display pinned posts
13429 + ## Get the list of pinned posts
13430 + #set ($pinnedPosts = [])
13431 + #set ($pinnedPostsSourceDoc = $NULL)
13432 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
13433 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
13434 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
13435 + #end
13436 + #if (~"$!pinnedPostsSourceDoc~" != '')
13437 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
13438 + #if (~"$!pinnedPostsObj~" != '')
13439 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
13440 + #if (~"$!orderedPinnedPostsJSON~" != '')
13441 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
13442 + #else
13443 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
13444 + #end
13445 + #end
13446 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
13447 + \{\{html clean=~"false~"}}
13448 + #set ($x = 0)
13449 + #set ($showPinnedPostsButton = true)
13450 + #foreach ($pinnedPost in $pinnedPosts)
13451 + #if ($x == 0)
13452 + <div class=~"row flex-container~">
13453 + #if ($showPinnedPostsButton)
13454 + #displayEditPinnedPostsButton()
13455 + #set($showPinnedPostsButton = false)
13456 + #end
13457 + #end
13458 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
13459 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
13460 + #if (~"$!pinnedPostObj~" != '')
13461 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
13462 + #end
13463 + #set ($x = $mathtool.add($x, 1))
13464 + #if ($x == 3)
13465 + #set ($x = 0)
13466 + </div>
13467 + #end
13468 + #end
13469 + #if ($mathtool.mod($x, 3) != 0)
13470 + </div>
13471 + #end
13472 + \{\{/html}}
13473 +
13474 + ## If the first post is a pinned post : this means that all the posts are pinned
13475 + ## In this case, avoid displaying the posts again after the pinned posts section.
13476 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
13477 + #set ($stopBlogPostsDisplay = true)
13478 + #end
13479 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
13480 +
13481 + \{\{html}}
13482 + <div class=~"row no-pinnded-posts~">
13483 + #displayEditPinnedPostsButton()
13484 + </div>
13485 + \{\{/html}}
13486 +
13487 + #end
13488 + #end
13489 + #if (!$stopBlogPostsDisplay)
13490 + \{\{html clean=~"false~"}}
13491 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
13492 + #set ($nbDisplayedPosts = 0)
13493 + #end
13494 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
13495 + #if ($nbDisplayedPosts != 0)
13496 + </div>
13497 + #set ($lastHtmlTag = 'c')
13498 + #end
13499 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
13500 + <div class=~"row~">
13501 + #set ($lastHtmlTag = 'o')
13502 + #set ($lastRowClass = ~"~")
13503 + #else
13504 + <div class=~"row flex-container~">
13505 + #set ($lastHtmlTag = 'o')
13506 + #set ($lastRowClass = ~"flex~")
13507 + #end
13508 + #end
13509 + #displaySmallPost($postDoc $postObj)
13510 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
13511 + </div>
13512 + #set ($lastHtmlTag = 'c')
13513 + #end
13514 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
13515 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
13516 + #if (~"$!lastHtmlTag~" == 'o')
13517 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
13518 + <div class=~"col-xs-12 col-sm-6~"></div>
13519 + #end
13520 + </div>
13521 + #end
13522 + #end
13523 + \{\{/html}}
13524 + #end
13525 + #else
13526 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
13527 + #end
13528 + #else
13529 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
13530 + #end" %)
13531 +(((
13532 +(% class="macro-placeholder hidden" %)
13533 +(((
13534 +macro:velocity
13535 +)))
13536 +
13537 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"col-xs-12 col-sm-6 next_blog~">
13538 +<a href=~"/Nieuws/Nieuwsbrief%20oktober%202023~" class=~"thumbnail~">
13539 +<div class=~"row~">
13540 +<div class=~"col-xs-4~">
13541 +<img src=~"/download/Nieuws/Nieuwsbrief%20oktober%202023/fall-flower-orange-food-harvest-produce-858531-pxhere.com.jpg?width=600&rev=1.1~" />
13542 +</div>
13543 +<div class=~"col-xs-8 art_det~">
13544 +<p class=~"text-left~">
13545 +Nieuwsbrief oktober 2023 <br/><span class=~"date_info~"> Nov 28, 2023, </span>
13546 +</p>
13547 +<div class=~"row post-details~">
13548 +<div class=~"col-xs-8 detail~">
13549 +<div class=~"post-likes btn btn-default disabled badge~"
13550 +title=~"Number of likes on this page: 1~">
13551 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">1</span>
13552 +</div>
13553 +</div>
13554 +<div class=~"col-xs-4 com_det~">
13555 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
13556 +</div>
13557 +</div>
13558 +</div>
13559 +</div>
13560 +</a>
13561 +</div>" %)
13562 +(((
13563 +(% class="macro-placeholder hidden" %)
13564 +(((
13565 +macro:html
13566 +)))
13567 +
13568 +(% class="col-xs-12 col-sm-6 next_blog" %)
13569 +(((
13570 +(% class="row" %)
13571 +(((
13572 +(% class="col-xs-4" %)
13573 +(((
13574 +[[~[~[image:/download/Nieuws/Nieuwsbrief%20oktober%202023/fall-flower-orange-food-harvest-produce-858531-pxhere.com.jpg?width=600&rev=1.1~]~]>>path:/Nieuws/Nieuwsbrief%20oktober%202023||class="thumbnail"]]
13575 +)))
13576 +
13577 +(% class="col-xs-8 art_det" %)
13578 +(((
13579 +(% class="text-left" %)
13580 +[[Nieuwsbrief oktober 2023
13581 +(% class="date_info" %) Nov 28, 2023,>>path:/Nieuws/Nieuwsbrief%20oktober%202023||class="thumbnail"]]
13582 +
13583 +(% class="row post-details" %)
13584 +(((
13585 +(% class="col-xs-8 detail" %)
13586 +(((
13587 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 1" %)
13588 +(((
13589 +[[(% class="like-number" %)1>>path:/Nieuws/Nieuwsbrief%20oktober%202023||class="thumbnail"]]
13590 +)))
13591 +)))
13592 +
13593 +(% class="col-xs-4 com_det" %)
13594 +(((
13595 +(% class="text-right" %)
13596 +[[(0)>>path:/Nieuws/Nieuwsbrief%20oktober%202023||class="thumbnail"]]
13597 +)))
13598 +)))
13599 +)))
13600 +)))
13601 +)))
13602 +)))
13603 +)))
13604 +)))
13605 +
13606 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Nieuw beveiligingspaneel Axon van Aritech~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG|postIndex=3|previousPostReference=Nieuws.Nieuwsbrief december 2023|postIndex=4|previousPostReference=Nieuws.Nieuwsbrief november 2023|postIndex=5|previousPostReference=Nieuws.Feestelijke afsluiting, keuring materieel en tellen voorraden|postIndex=6|previousPostReference=Nieuws.RI&E 2023|postIndex=7|previousPostReference=Nieuws.Aankondiging update Syntess 6\\\\.9\\\\.0181|postIndex=8|previousPostReference=Nieuws.Nieuwsbrief oktober 2023~"" %)
13607 +(((
13608 +(% class="macro-placeholder hidden" %)
13609 +(((
13610 +macro:blogPostLayoutCards
13611 +)))
13612 +
13613 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
13614 +(((
13615 +(% class="macro-placeholder hidden" %)
13616 +(((
13617 +macro:include
13618 +)))
13619 +
13620 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
13621 +(((
13622 +(% class="macro-placeholder hidden" %)
13623 +(((
13624 +macro:include
13625 +)))
13626 +
13627 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
13628 +#set($blogClassname = 'Blog.BlogClass')
13629 +#set($blogTemplate = 'Blog.BlogTemplate')
13630 +#set($blogSheet = 'Blog.BlogSheet')
13631 +## Blog entries
13632 +#set($blogPostClassname = 'Blog.BlogPostClass')
13633 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
13634 +#set($blogPostSheet = 'Blog.BlogPostSheet')
13635 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
13636 +#set($oldArticleClassname = 'XWiki.ArticleClass')
13637 +## Categories
13638 +#set($blogCategoryClassname = 'Blog.CategoryClass')
13639 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
13640 +#set($blogCategorySheet = 'Blog.CategorySheet')
13641 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
13642 +#set($oldBlogCategoryClassname = 'Blog.Categories')
13643 +#set($defaultCategoryParent = 'Blog.Categories')
13644 +## Style
13645 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
13646 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
13647 +## Clientside scripts
13648 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
13649 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
13650 +## Misc
13651 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
13652 +#set($isBlogPost = $doc.getObject($blogPostClassname))
13653 +#set($defaultBlogSpace = 'Blog')
13654 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
13655 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
13656 +##
13657 +##
13658 +##
13659 +#**
13660 + * Displays an image, taken from the blog style document.
13661 + *
13662 + * @param $imgName The name of the icon from icons set to use.
13663 + *#
13664 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
13665 +(((
13666 +(% class="macro-placeholder hidden" %)
13667 +(((
13668 +macro:velocity
13669 +)))
13670 +)))
13671 +)))
13672 +
13673 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
13674 +##
13675 +##
13676 +## Import the blog skin and javascripts.
13677 +$!xwiki.ssx.use($blogStyleDocumentName)##
13678 +$!xwiki.jsx.use($blogScriptsDocumentName)##
13679 +##
13680 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
13681 +#template('hierarchy_macros.vm')##
13682 +##
13683 +##
13684 +#**
13685 + * Prints a blog. This is the main macro used in the BlogSheet.
13686 + *
13687 + * @param blogDoc the XDocument holding the blog definition object.
13688 + *###
13689 +#macro(printBlog $blogDoc)
13690 + \{\{include reference='Blog.CreatePost'/}}
13691 +
13692 + ## Use the blogPostList macro to display the blogposts
13693 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
13694 + ## do not support FTM the monthly and weekly blog display types
13695 + #getBlogDisplayType($blogDoc $displayType)
13696 + #if ($displayType == 'weekly' || $displayType == 'monthly')
13697 + #getBlogEntries($blogDoc $entries)
13698 + #displayBlog($entries 'index' true true)
13699 + #displayNavigationLinks($blogDoc)
13700 + #else
13701 + #getBlogDisplayType($blogDoc $displayType)
13702 + #set ($paginated = 'no')
13703 + #if ($displayType == 'paginated')
13704 + #set ($paginated = 'yes')
13705 + #end
13706 + #getBlogPostsLayout($blogDoc $postsLayout)
13707 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
13708 + #end
13709 +#end
13710 +##
13711 +##
13712 +##
13713 +#**
13714 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
13715 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
13716 + * all entries).
13717 + *
13718 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
13719 + *###
13720 +#macro(showBlogInfo $blogDoc)
13721 + #if($blogDoc.getObject($blogClassname))
13722 + ## Keep testing for inline action for backward compatibility with older blogs.
13723 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
13724 + #macro(displayProperty $blogDoc $propname)
13725 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
13726 + : $blogDoc.display($propname)
13727 + #end
13728 + #displayProperty($blogDoc 'title')
13729 + #displayProperty($blogDoc 'description')
13730 + #displayProperty($blogDoc 'displayType')
13731 + #displayProperty($blogDoc 'itemsPerPage')
13732 + #displayProperty($blogDoc 'postsLayout')
13733 + #displayProperty($blogDoc 'postsLayoutParameters')
13734 + #else
13735 + $blogDoc.display('description')
13736 + #end
13737 + #elseif($doc.fullName == $blogSheet)
13738 += $services.localization.render('blog.code.blogsheet') =
13739 + \{\{translation key='blog.code.sheetexplanation'/}}
13740 + #else
13741 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
13742 + #end
13743 +#end
13744 +##
13745 +##
13746 +##
13747 +#**
13748 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
13749 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
13750 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
13751 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
13752 + *
13753 + * @param space A <tt>String</tt>, the name of the space where to search.
13754 + * @param blogDoc The resulting XDocument.
13755 + *###
13756 +#macro(getBlogDocument $space $blogDoc)
13757 + #set ($result = $NULL)
13758 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
13759 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
13760 + ## identify the right blog based on a configuration object in a WebPreferences page.
13761 + #set ($spaceReference = $services.model.resolveSpace($space))
13762 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
13763 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
13764 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
13765 + #if ($preferencesObj)
13766 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
13767 + #end
13768 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
13769 + #if (~"$!result~" == '')
13770 + ## First, try the Space.WebHome, for a whole-space blog
13771 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
13772 + #if(!$result.getObject($blogClassname))
13773 + ## Second, try the Space.Blog document
13774 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
13775 + #if(!$result.getObject($blogClassname))
13776 + ## Third, try searching for a blog document in the current space
13777 + ## Prevent the query fail when the space contains dots '.'
13778 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
13779 + #if($blogDocs.size() > 0)
13780 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
13781 + #else
13782 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
13783 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
13784 + #if($blogDocs.size() > 0)
13785 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
13786 + #else
13787 + ## Last, fallback to Blog.WebHome, the default blog
13788 + #set($result = $xwiki.getDocument('Blog.WebHome'))
13789 + #end
13790 + #end
13791 + #end
13792 + #end
13793 + #end
13794 + #set ($blogDoc = $NULL)
13795 + #setVariable (~"$blogDoc~" $result)
13796 +#end
13797 +##
13798 +##
13799 +##
13800 +#**
13801 + * Retrieve the blog title.
13802 + *
13803 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
13804 + * @param title The resulting title.
13805 + *###
13806 +#macro(getBlogTitle $blogDoc $title)
13807 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
13808 + #set ($title = $NULL)
13809 + #setVariable (~"$title~" $!blogDoc.displayTitle)
13810 +#end
13811 +##
13812 +##
13813 +##
13814 +#**
13815 + * Retrieve the blog description.
13816 + *
13817 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
13818 + * property set.
13819 + * @param description The resulting description.
13820 + *###
13821 +#macro(getBlogDescription $blogDoc $description)
13822 + #getBlogProperty($blogDoc 'description' '' $result)
13823 + #set ($description = $NULL)
13824 + #setVariable (~"$description~" $result)
13825 +#end
13826 +##
13827 +##
13828 +##
13829 +#**
13830 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
13831 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
13832 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
13833 + * month), or all.
13834 + *
13835 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
13836 + * @param entries The resulting list of entries to display, a list of XDocument names.
13837 + *###
13838 +#macro(getBlogEntries $blogDoc $entries)
13839 + #if (!$entries)
13840 + #setVariable (~"$entries~" [])
13841 + #end
13842 + #getAllBlogPostsQuery($query)
13843 + #isDefaultBlog($blogDoc $isDefault)
13844 + #set($queryParams = \{})
13845 + #if ($isDefault)
13846 + #getCategoryAllBlogPostsQuery($query)
13847 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
13848 + #set($discard = $queryParams.put('creator', $xcontext.user))
13849 + #set($discard = $queryParams.put('space', $blogDoc.space))
13850 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
13851 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
13852 + #else
13853 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
13854 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
13855 + #set($discard = $queryParams.put('space', $blogPostsLocation))
13856 + #set($discard = $queryParams.put('parent', $blogDoc.space))
13857 + #end
13858 + #getBlogDisplayType($blogDoc $displayType)
13859 + #if($displayType == 'weekly')
13860 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
13861 + #elseif($displayType == 'monthly')
13862 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
13863 + #elseif($displayType == 'all')
13864 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
13865 + #else
13866 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
13867 + #end
13868 +#end
13869 +##
13870 +##
13871 +##
13872 +#**
13873 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
13874 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
13875 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
13876 + * (10 if not defined).
13877 + *
13878 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
13879 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
13880 + * refined to restrict to a given space, or to a given search criteria, etc.
13881 + * @param entries The resulting list of entries to display, a list of XDocument names.
13882 + * @param queryParams The parameters to bind with the query.
13883 + *###
13884 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
13885 + #if (!$entries)
13886 + #setVariable (~"$entries~" [])
13887 + #end
13888 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
13889 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
13890 + #bindQueryParameters($countQueryObj $queryParams)
13891 + #bindQueryParameters($queryObj $queryParams)
13892 + #set($totalEntries = $countQueryObj.count())
13893 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
13894 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
13895 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
13896 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
13897 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
13898 +#end
13899 +##
13900 +##
13901 +##
13902 +#**
13903 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
13904 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
13905 + * digit year). Initially the current week is displayed.
13906 + *
13907 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
13908 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
13909 + * refined to restrict to a given space, or to a given search criteria, etc.
13910 + * @param entries The resulting list of entries to display, a list of XDocument names.
13911 + * @param queryParams The parameters to bind with the query.
13912 + *###
13913 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
13914 + #if (!$entries)
13915 + #setVariable (~"$entries~" [])
13916 + #end
13917 + #getRequestedWeek($weekDate)
13918 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
13919 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
13920 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
13921 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
13922 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
13923 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
13924 + #bindQueryParameters($countQueryObj $queryParams)
13925 + #bindQueryParameters($queryObj $queryParams)
13926 + #set($totalEntries = $countQueryObj.count())
13927 + #set($discard = $entries.addAll($queryObj.execute()))
13928 +#end
13929 +##
13930 +##
13931 +##
13932 +#**
13933 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
13934 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
13935 + * digit year). Initially the current month is displayed.
13936 + *
13937 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
13938 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
13939 + * refined to restrict to a given space, or to a given search criteria, etc.
13940 + * @param entries The resulting list of entries to display, a list of XDocument names.
13941 + * @param queryParams The parameters to bind with the query.
13942 + *###
13943 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
13944 + #if (!$entries)
13945 + #setVariable (~"$entries~" [])
13946 + #end
13947 + #getRequestedMonth($monthDate)
13948 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
13949 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
13950 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
13951 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
13952 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
13953 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
13954 + #bindQueryParameters($countQueryObj $queryParams)
13955 + #bindQueryParameters($queryObj $queryParams)
13956 + #set($totalEntries = $countQueryObj.count())
13957 + #set($discard = $entries.addAll($queryObj.execute()))
13958 +#end
13959 +##
13960 +##
13961 +##
13962 +#**
13963 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
13964 + *
13965 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
13966 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
13967 + * refined to restrict to a given space, or to a given search criteria, etc.
13968 + * @param entries The resulting list of entries to display, a list of XDocument names.
13969 + * @param queryParams The parameters to bind with the query.
13970 + *###
13971 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
13972 + #if (!$entries)
13973 + #setVariable (~"$entries~" [])
13974 + #end
13975 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
13976 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
13977 + #bindQueryParameters($countQueryObj $queryParams)
13978 + #bindQueryParameters($queryObj $queryParams)
13979 + #set($totalEntries = $countQueryObj.count())
13980 + #set($discard = $entries.addAll($queryObj.execute()))
13981 +#end
13982 +##
13983 +##
13984 +##
13985 +#**
13986 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
13987 + *
13988 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
13989 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
13990 + * refined to restrict to a given space, or to a given search criteria, etc.
13991 + * @param queryParams The parameters to bind with the query.
13992 + * @param entries The resulting list of entries to display, a list of XDocument names.
13993 + *###
13994 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
13995 + #if (!$entries)
13996 + #setVariable (~"$entries~" [])
13997 + #end
13998 + #set($query = ~"$\{query} and isPublished.value = 0~")
13999 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
14000 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
14001 + #bindQueryParameters($countQueryObj $queryParams)
14002 + #bindQueryParameters($queryObj $queryParams)
14003 + #set($totalEntries = $countQueryObj.count())
14004 + #set($discard = $entries.addAll($queryObj.execute()))
14005 +#end
14006 +##
14007 +##
14008 +##
14009 +#**
14010 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
14011 + *
14012 + * @param entries The resulting list of entries to display, a list of XDocument names.
14013 + *###
14014 +#macro(getGlobalBlogEntries $entries)
14015 + #if (!$entries)
14016 + #setVariable (~"$entries~" [])
14017 + #end
14018 + #getAllBlogPostsQuery($query)
14019 + #set($totalEntries = $services.query.hql($query).count())
14020 + #set($defaultItemsPerPage = 20)
14021 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
14022 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
14023 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
14024 +#end
14025 +#**
14026 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
14027 + * blog, nor specify a range or an ordering criteria.
14028 + *
14029 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
14030 + *
14031 + * @param query The basic query for selecting blog entries.
14032 + *#
14033 +#macro(getBlogEntriesBaseQuery $query)
14034 + #getAllBlogPostsQuery($query)
14035 +#end
14036 +#**
14037 + * Return the Query for selecting the all wiki blog posts without filtering
14038 + *
14039 + * @param query The basic query for selecting blog entries.
14040 + *#
14041 +#macro(getAllBlogPostsQuery $query)
14042 + #set ($query = $NULL)
14043 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
14044 + IntegerProperty hidden, DateProperty publishDate
14045 + where doc.fullName <> '$blogPostTemplate' and
14046 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
14047 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
14048 + hidden.id.id = obj.id and hidden.id.name='hidden' and
14049 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
14050 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
14051 +#end
14052 +##
14053 +##
14054 +##
14055 +###**
14056 + * Return the Query for selecting the all wiki blog posts with categories filtering
14057 + *
14058 + * @param query The basic query for selecting blog entries.
14059 + *###
14060 +#macro(getCategoryAllBlogPostsQuery $query)
14061 + #set ($query = $NULL)
14062 + #getAllBlogPostsQuery($baseQuery)
14063 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
14064 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
14065 +#end
14066 +##
14067 +##
14068 +##
14069 +#**
14070 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
14071 + * week), monthly (all entries in a month), or all.
14072 + *
14073 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
14074 + * property set.
14075 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
14076 + *###
14077 +#macro(getBlogDisplayType $blogDoc $displayType)
14078 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
14079 + #set ($displayType = $NULL)
14080 + #setVariable (~"$displayType~" $result)
14081 +#end
14082 +##
14083 +##
14084 +##
14085 +#**
14086 + * Displays a list of entries.
14087 + *
14088 + * @param entries The entries to display, a list of XDocument names.
14089 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
14090 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
14091 + * used values: index, single, category, search, unpublished, hidden.
14092 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
14093 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
14094 + * displayed alone on their page since it's the page title which is used in this case)
14095 + *###
14096 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
14097 + #set($blogDay = '')
14098 + (% class=~"hfeed $!\{displaying}~" ~%)(((
14099 + (% class=~"blogDay~" ~%)(((
14100 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
14101 + #getEntryObject($entryDoc $entryObj)
14102 + ## Although all entries should have one of the two objects, better check to be sure.
14103 + #if(~"$!\{entryObj}~" != '')
14104 + #getEntryDate($entryDoc $entryObj $entryDate)
14105 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
14106 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
14107 + #if($blogDay != $entryDateStr)
14108 + #if($blogDay != '')
14109 + )))
14110 + (% class=~"blogDay~" ~%)(((
14111 + #end
14112 + #displayBlogDate($entryDate)
14113 + #set ($blogDay = $entryDateStr)
14114 + #end
14115 + ## Finally, display the entry.
14116 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
14117 + #end
14118 + #end
14119 + )))## blogDay
14120 + )))## hfeed
14121 +#end
14122 +##
14123 +##
14124 +##
14125 +#**
14126 + * Get the entry object, either a new BlogPost or an old Article.
14127 + *
14128 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14129 + * @param entryObj The resulting xobject of the blog post.
14130 + *###
14131 +#macro(getEntryObject $entryDoc $__entryObj)
14132 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
14133 + #if(!$result)
14134 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
14135 + #end
14136 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
14137 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
14138 + ## overwritten in this case but it's less likely to have such a variable defined before.
14139 + #set ($__entryObj = $NULL)
14140 + #setVariable (~"$__entryObj~" $result)
14141 +#end
14142 +##
14143 +##
14144 +##
14145 +#**
14146 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
14147 + * the document creation date, but can be edited by the user.
14148 + *
14149 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14150 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14151 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
14152 + *###
14153 +#macro(getEntryDate $entryDoc $entryObj $result)
14154 + #set ($result = $NULL)
14155 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
14156 +#end
14157 +##
14158 +##
14159 +##
14160 +#**
14161 + * Displays a date, nicely formatted as a calendar page.
14162 + *
14163 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
14164 + *###
14165 +#macro(displayBlogDate $date)
14166 + #set($year = $xwiki.formatDate($date, 'yyyy'))
14167 + ## 3 letter month name, like Jan, Dec.
14168 + #set($month = $xwiki.formatDate($date, 'MMM'))
14169 + ## Uncomment to get a full length month name, like January, December.
14170 + ## TODO: this could be defined somewhere in the blog style.
14171 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
14172 + #set($day = $xwiki.formatDate($date, 'dd'))
14173 + (% class=~"blogdate~" ~%)
14174 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
14175 +#end
14176 +##
14177 +##
14178 +##
14179 +#**
14180 + * Displays a blog article: management tools, header, content, footer.
14181 + *
14182 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14183 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14184 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
14185 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
14186 + * when they're displayed alone on their page since it's the page title which is used in this case)
14187 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
14188 + *###
14189 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
14190 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
14191 + #isPublished($entryObj $isPublished)
14192 + #isHidden($entryObj $isHidden)
14193 + #if($doc.fullName == $entryDoc.fullName)
14194 + (% class=~"hentry single-article~" ~%)(((
14195 + #else
14196 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
14197 + #end
14198 + #if ($shouldDisplayActions)
14199 + #displayEntryTools($entryDoc $entryObj)
14200 + #end
14201 + #if($shouldDisplayTitle)
14202 + #displayEntryTitle($entryDoc $entryObj)
14203 + #end
14204 + #if($doc.fullName == $entryDoc.fullName)
14205 + #if(!$isPublished)
14206 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
14207 + #elseif($isHidden)
14208 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
14209 + #end
14210 + #end
14211 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
14212 + #displayEntryFooter($entryDoc $entryObj)
14213 + )))## hentry
14214 +#end
14215 +##
14216 +##
14217 +##
14218 +#**
14219 + * Checks if the provided blog is published or not.
14220 + *
14221 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14222 + * @param isPublished The resulting boolean, true if the entry is considered published.
14223 + *###
14224 +#macro(isPublished $entryObj $isPublished)
14225 + #set ($isPublished = $NULL)
14226 + ## This should work for both old articles, which don't have the 'published' property at all, and
14227 + ## are considered published by default, and new entries, that should have 1 if published.
14228 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
14229 + #setVariable (~"$isPublished~" true)
14230 + #else
14231 + #setVariable (~"$isPublished~" false)
14232 + #end
14233 +#end
14234 +##
14235 +##
14236 +##
14237 +#**
14238 + * Checks if the provided blog is hidden or not.
14239 + *
14240 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
14241 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
14242 + *###
14243 +#macro(isHidden $entryObj $isHidden)
14244 + #set ($isHidden = $NULL)
14245 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
14246 + ## are considered visible by default, and new entries, that should have 1 if hidden.
14247 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
14248 + #setVariable (~"$isHidden~" true)
14249 + #else
14250 + #setVariable (~"$isHidden~" false)
14251 + #end
14252 +#end
14253 +##
14254 +##
14255 +##
14256 +#**
14257 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
14258 + *
14259 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14260 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14261 + *###
14262 +#macro(displayEntryTools $entryDoc $entryObj)
14263 + #if($xcontext.action == 'view')
14264 + (% class=~"blog-entry-toolbox~" ~%)(((
14265 + #displayPublishButton($entryDoc $entryObj)
14266 + #displayHideShowButton($entryDoc $entryObj)
14267 + #displayEditButton($entryDoc $entryObj)
14268 + #displayDeleteButton($entryDoc $entryObj)
14269 + )))
14270 + #end
14271 +#end
14272 +##
14273 +##
14274 +##
14275 +#**
14276 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
14277 + *
14278 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14279 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14280 + * @todo AJAX calls.
14281 + *###
14282 +#macro(displayPublishButton $entryDoc $entryObj)
14283 + #isPublished($entryObj $isPublished)
14284 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
14285 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
14286 + #end
14287 +#end
14288 +##
14289 +##
14290 +##
14291 +#**
14292 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
14293 + *
14294 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14295 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14296 + *###
14297 +#macro(displayHideShowButton $entryDoc $entryObj)
14298 + #isPublished($entryObj $isPublished)
14299 + #isHidden($entryObj $isHidden)
14300 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
14301 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
14302 + #set ($queryString = \{
14303 + 'xredirect' : $thisURL,
14304 + 'form_token' : $services.csrf.getToken()
14305 + })
14306 + #if ($isHidden)
14307 + #set ($discard = $queryString.putAll(\{
14308 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
14309 + 'comment' : $services.localization.render('blog.code.madevisible')
14310 + }))
14311 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
14312 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
14313 + #else
14314 + #set ($discard = $queryString.putAll(\{
14315 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
14316 + 'comment' : $services.localization.render('blog.code.hid')
14317 + }))
14318 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
14319 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
14320 + #end
14321 + #end
14322 +#end
14323 +##
14324 +##
14325 +##
14326 +#**
14327 + * Displays the edit button to those that can edit the article.
14328 + *
14329 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14330 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14331 + *###
14332 +#macro(displayEditButton $entryDoc $entryObj)
14333 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
14334 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
14335 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
14336 + #end
14337 +#end
14338 +##
14339 +##
14340 +##
14341 +#**
14342 + * Displays the delete button to those that can edit the article.
14343 + *
14344 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14345 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14346 + * @todo AJAX calls.
14347 + *###
14348 +#macro(displayDeleteButton $entryDoc $entryObj)
14349 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
14350 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
14351 + #end
14352 +#end
14353 +##
14354 +##
14355 +##
14356 +#**
14357 + * Displays the title of the entry.
14358 + *
14359 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14360 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14361 + *###
14362 +#macro(displayEntryTitle $entryDoc $entryObj)
14363 + #if($doc.fullName == $entryDoc.fullName)
14364 + (% class=~"entry-title~" ~%)
14365 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
14366 + #else
14367 + (% class=~"entry-title~" ~%)
14368 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
14369 + #end
14370 +#end
14371 +##
14372 +##
14373 +##
14374 +#**
14375 + * Displays the body of the entry.
14376 + *
14377 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14378 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14379 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
14380 + *###
14381 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
14382 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
14383 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
14384 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
14385 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
14386 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
14387 + ))) ## entry-content
14388 + (% class=~"clearfloats~" ~%)((()))
14389 +#end
14390 +##
14391 +##
14392 +##
14393 +#**
14394 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
14395 + * of the <tt>extract</tt> field (if not empty).
14396 + *
14397 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14398 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14399 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
14400 + * @param entryContent The resulting content.
14401 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
14402 + * <tt>onlyExtract</tt> is <tt>true</tt>)
14403 + *###
14404 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
14405 + #if ($onlyExtract)
14406 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
14407 + ## of the content.
14408 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
14409 + #end
14410 + #if(~"$!macro.result~" == '')
14411 + #set($macro.result = $entryObj.getProperty('content').value)
14412 +#* Disabled until the content can be cleanly cut.
14413 +* #if($onlyExtract && $result.length()>$maxchars)
14414 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
14415 +* #set($i = $i + 1)
14416 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
14417 +* #end
14418 +## *###
14419 + #elseif (!$removeEllipsis)
14420 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
14421 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
14422 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
14423 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
14424 + #end
14425 + #end
14426 + #set ($entryContent = $NULL)
14427 + #setVariable (~"$entryContent~" $macro.result)
14428 +#end
14429 +##
14430 +##
14431 +##
14432 +#**
14433 + * Displays the footer of the entry.
14434 + *
14435 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14436 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14437 + *###
14438 +#macro(displayEntryFooter $entryDoc $entryObj)
14439 + (% class=~"entry-footer~" ~%)(((
14440 + #isPublished($entryObj $isPublished)
14441 + (% class='entry-author-label' ~%)
14442 + #if($isPublished)
14443 + \{\{translation key='blog.code.postedby'/}} ##
14444 + #else
14445 + \{\{translation key='blog.code.createdby'/}} ##
14446 + #end
14447 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
14448 + #getEntryDate($entryDoc $entryObj $entryDate)
14449 + #listCategories($entryObj) #*
14450 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
14451 + ## we assume cannot be more than 3 seconds.
14452 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
14453 + #if ($showcomments)
14454 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
14455 + #end ##
14456 + #if($entryDoc != $doc) ##
14457 + #displayEntryBlogLocation($entryDoc $entryObj) ##
14458 + #end
14459 + )))## entry-footer
14460 +#end
14461 +##
14462 +##
14463 +#**
14464 + * Display the blog for the entry (if it is not the currently displayed blog)
14465 + *
14466 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
14467 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14468 + *###
14469 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
14470 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
14471 + #if(~"$!blogPostsLocation~" != ~"~") ##
14472 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
14473 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
14474 + #if($doc.documentReference != $blogDocRef) ##
14475 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
14476 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
14477 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
14478 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
14479 + )))(%~%)##
14480 + #end
14481 + #end
14482 + #end
14483 +#end
14484 +##
14485 +##
14486 +##
14487 +##
14488 +#**
14489 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
14490 + *
14491 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
14492 + *###
14493 +#macro(listCategories $entryObj)
14494 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
14495 + #set($categories = $entryObj.getProperty('category').value)
14496 + #set($first = true)
14497 + #if($categories.size() > 0)
14498 + #foreach($category in $categories)
14499 + #set($categoryDoc = $!xwiki.getDocument($category))
14500 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
14501 + #if($foreach.count == 1)
14502 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
14503 + #else
14504 + , ##
14505 + #end##
14506 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
14507 + #end##
14508 + #end##
14509 + #end
14510 + #end
14511 +#end
14512 +##
14513 +##
14514 +##
14515 +#**
14516 + * Displays blog pagination links (older and newer entries).
14517 + *
14518 + * @param blogDoc the XDocument holding the blog definition object.
14519 + *###
14520 +#macro(displayNavigationLinks $blogDoc)
14521 + (% class=~"clearfloats~" ~%)((()))
14522 + #getBlogDisplayType($blogDoc $displayType)
14523 + #if($displayType == 'weekly')
14524 + (% class=~"pagingLinks~" ~%)(((
14525 + #getRequestedWeek($weekDate)
14526 + $weekDate.addWeeks(-1)##
14527 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
14528 + #sep()
14529 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
14530 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
14531 + )))
14532 + #elseif($displayType == 'monthly')
14533 + (% class=~"pagingLinks~" ~%)(((
14534 + #getRequestedMonth($monthDate)
14535 + $monthDate.addMonths(-1)##
14536 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
14537 + #sep()
14538 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
14539 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
14540 + )))
14541 + #elseif($displayType == 'all')
14542 + #else
14543 + ## Paginated
14544 + #if(($totalPages > 1))
14545 + #set($queryString = '')
14546 + #foreach($p in $request.getParameterNames())
14547 + #if($p != 'page' && $p != 'ipp')
14548 + #foreach($v in $request.getParameterValues($p))
14549 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
14550 + #end
14551 + #end
14552 + #end
14553 + (% class=~"pagingLinks~" ~%)(((
14554 + #if ($currentPageNumber < $totalPages)
14555 + #set($currentPageNumber = $currentPageNumber + 1)
14556 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
14557 + #set($currentPageNumber = $currentPageNumber - 1)
14558 + #end
14559 + #if ($currentPageNumber > 1)
14560 + #if ($currentPageNumber < $totalPages)
14561 + #sep()
14562 + #end
14563 + #set($currentPageNumber = $currentPageNumber - 1)
14564 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
14565 + #set($currentPageNumber = $currentPageNumber + 1)
14566 + #end
14567 + (% class=~"clear~" ~%)(%~%)
14568 + )))## pagingLinks
14569 + #end
14570 + #end
14571 +#end
14572 +##
14573 +##
14574 +##
14575 +#**
14576 + * Displays a message box with ~"publish~" icon.
14577 + *
14578 + * @param message A text message concerning blog article publishing
14579 + *###
14580 +#macro(publishMessageBox $message)
14581 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
14582 +#end
14583 +#**
14584 + * Displays a message box with ~"show/hide~" icon.
14585 + *
14586 + * @param message A text message concerning blog article hiding
14587 + *###
14588 +#macro(hideMessageBox $message)
14589 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
14590 +#end
14591 +##
14592 +##
14593 +##
14594 +#**
14595 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
14596 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
14597 + *
14598 + * @param monthDate The resulting week, a JODATime MutableDateTime.
14599 + *###
14600 +#macro(getRequestedWeek $weekDate)
14601 + #set ($weekDate = $NULL)
14602 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
14603 + #if(~"$!\{request.year}~" != '')
14604 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
14605 + #end
14606 + #if(~"$!\{request.week}~" != '')
14607 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
14608 + #end
14609 +#end
14610 +##
14611 +##
14612 +##
14613 +#**
14614 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
14615 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
14616 + *
14617 + * @param monthDate The resulting month, a JODATime MutableDateTime.
14618 + *###
14619 +#macro(getRequestedMonth $monthDate)
14620 + #set ($monthDate = $NULL)
14621 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
14622 + #if(~"$!\{request.year}~" != '')
14623 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
14624 + #end
14625 + #if(~"$!\{request.month}~" != '')
14626 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
14627 + #end
14628 +#end
14629 +##
14630 +##
14631 +##
14632 +#**
14633 + * Retrieve a blog property (title, display type, etc).
14634 + *
14635 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
14636 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
14637 + * @param defaultValue The default value to use in case the blog object does not define one.
14638 + * @param propertyValue The resulting value.
14639 + *###
14640 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
14641 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
14642 + #if($result == '')
14643 + #set($result = $defaultValue)
14644 + #end
14645 + #set ($propertyValue = $NULL)
14646 + #setVariable (~"$propertyValue~" $result)
14647 +#end
14648 +
14649 +#**
14650 + * If an error occurs when executing an action, set a specific response status and display an error message.
14651 + *
14652 + * @param status The response status.
14653 + * @param text The user readable error to be displayed. Can be a translation key.
14654 + * @param parameters The parameters to use when decoding the translation key.
14655 + *###
14656 +#macro(blog__actionResponseError $status $text $parameters)
14657 + $response.setStatus($status)
14658 + #if($request.ajax)
14659 + $services.localization.render($text, $!parameters)
14660 + #else
14661 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
14662 + #end
14663 +#end
14664 +##
14665 +##
14666 +##
14667 +#**
14668 + * Check if a blog is the Default blog (The one in the 'Blog' space).
14669 + *
14670 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
14671 + * @param isDefault The resulting boolean.
14672 + *###
14673 +#macro(isDefaultBlog $blogDoc $isDefault)
14674 + #set ($result = false)
14675 + #if ($blogDoc.space == 'Blog')
14676 + #set ($result = true)
14677 + #end
14678 + #setVariable(~"$isDefault~" $result)
14679 +#end
14680 +##
14681 +##
14682 +##
14683 +#**
14684 + * Retrieve the blog posts location (space).
14685 + *
14686 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
14687 + * @param postsLocation The resulting location.
14688 + *###
14689 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
14690 + #getBlogDocument($blogSpace $blogDoc)
14691 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
14692 + #set ($postsLocation = $NULL)
14693 + #setVariable (~"$postsLocation~" $result)
14694 +#end
14695 +##
14696 +##
14697 +##
14698 +#**
14699 + * Retrieve the blog categories location (space).
14700 + *
14701 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
14702 + * @param categoriesLocation The resulting location.
14703 + *###
14704 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
14705 + #getBlogDocument($blogSpace $blogDoc)
14706 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
14707 + #set ($postsLocation = $NULL)
14708 + #setVariable (~"$categoriesLocation~" $result)
14709 +#end
14710 +###**
14711 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
14712 + * for example there is 4 different panel contexts:
14713 + * aBlog.aPost or aBlog.WebHome
14714 + * aCategorySpace.aCategory
14715 + * aCategorySpace.WebHome
14716 + * Blog.aPost or Blog.WebHome
14717 + *
14718 + * @param query The query for selecting blog entries.
14719 + * @param queryParams The parameters to bind with the generated query.
14720 + * @param targetDoc The document in which the articles will be displayed.
14721 + *###
14722 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
14723 + #set ($query = $NULL)
14724 + #set ($queryParams = $NULL)
14725 + #getCategoryAllBlogPostsQuery($resultQuery)
14726 + #set ($resultQueryParams = \{})
14727 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
14728 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
14729 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
14730 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
14731 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
14732 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
14733 + #elseif($targetDoc.getObject($blogCategoryClassname))
14734 + ## Get all posts that are in a category aCategorySpace.aCategory
14735 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
14736 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
14737 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
14738 + ## Get all posts that are in a category aCategorySpace.%
14739 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
14740 + ## Exclude incategorized posts
14741 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
14742 + #if ($targetDoc.space == $defaultBlogSpace)
14743 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
14744 + #end
14745 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
14746 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
14747 + #else
14748 + ## Get all posts in blog space aBlog
14749 + #getAllBlogPostsQuery($resultQuery)
14750 + #getBlogPostsLocation($targetDoc.space $postsLocation)
14751 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
14752 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
14753 + #end
14754 + #setVariable(~"$query~" $resultQuery)
14755 + #setVariable(~"$queryParams~" $resultQueryParams)
14756 +#end
14757 +##
14758 +##
14759 +##
14760 +###**
14761 + * Display blog posts based on the context where the posts are displayed.
14762 + * for example there is 4 different panel contexts:
14763 + * aBlog.aPost or aBlog.WebHome
14764 + * aCategorySpace.aCategory
14765 + * aCategorySpace.WebHome
14766 + * Blog.aPost or Blog.WebHome
14767 + *
14768 + * @param targetDoc The document in which the articles will be displayed.
14769 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
14770 + * @param layout Layout of the the posts to display
14771 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
14772 + * @param limit the number of posts to display
14773 + *###
14774 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
14775 + #if ($postLayout == 'full')
14776 + #set ($macro.paginated = 'yes')
14777 + #end
14778 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
14779 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
14780 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
14781 + #if (~"$!layout~" == '')
14782 + #set ($layout = $postsLayout)
14783 + #end
14784 + #if ($postsVisiblity == 'recent')
14785 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
14786 + #elseif($postsVisiblity == 'unpublished')
14787 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
14788 + #end
14789 + #elseif($targetDoc.getObject($blogCategoryClassname))
14790 + ## Display all posts that are in a category aCategorySpace.aCategory
14791 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
14792 + #getBlogPostsLayout($blogDoc $postsLayout)
14793 + #if (~"$!layout~" == '')
14794 + #set ($layout = $postsLayout)
14795 + #end
14796 + #if ($postsVisiblity == 'recent')
14797 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
14798 + #elseif($postsVisiblity == 'unpublished')
14799 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
14800 + #end
14801 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
14802 + ## Display all posts that are in a category aCategorySpace.%
14803 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
14804 + #getBlogPostsLayout($blogDoc $postsLayout)
14805 + #if (~"$!layout~" == '')
14806 + #set ($layout = $postsLayout)
14807 + #end
14808 + #if ($postsVisiblity == 'recent')
14809 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
14810 + #elseif($postsVisiblity == 'unpublished')
14811 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
14812 + #end
14813 + #else
14814 + ## Display all posts in blog space aBlog
14815 + #getBlogDocument($targetDoc.space $blogDoc)
14816 + #getBlogPostsLayout($blogDoc $postsLayout)
14817 + #if (~"$!layout~" == '')
14818 + #set ($layout = $postsLayout)
14819 + #end
14820 + #if ($postsVisiblity == 'recent')
14821 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
14822 + #elseif($postsVisiblity == 'unpublished')
14823 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
14824 + #end
14825 + #end
14826 +#end
14827 +##
14828 +##
14829 +##
14830 +#**
14831 + * Bind parameters to a query object.
14832 + *
14833 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
14834 + * @param queryParams the query parameters.
14835 + *###
14836 +#macro(bindQueryParameters $queryObj $queryParams)
14837 + #set ($output = $queryObj)
14838 + #foreach( $key in $queryParams.keySet() )
14839 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
14840 + #end
14841 + #setVariable(~"$queryObj~" $output)
14842 +#end
14843 +##
14844 +##
14845 +##
14846 +#**
14847 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
14848 + *
14849 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
14850 + * property set.
14851 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
14852 + *###
14853 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
14854 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
14855 + #set ($postsLayout = $NULL)
14856 + #setVariable (~"$postsLayout~" $res)
14857 +#end
14858 +##
14859 +##
14860 +##
14861 +#**
14862 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
14863 + *
14864 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
14865 + * @param blogDoc The resulting XDocument.
14866 + *###
14867 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
14868 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
14869 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
14870 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
14871 + #else
14872 + ## Fallback to Blog.WebHome, the default blog
14873 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
14874 + #end
14875 + #set ($blogDoc = $NULL)
14876 + #setVariable (~"$blogDoc~" $macro.result)
14877 +#end" %)
14878 +(((
14879 +(% class="macro-placeholder hidden" %)
14880 +(((
14881 +macro:velocity
14882 +)))
14883 +)))
14884 +)))
14885 +
14886 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
14887 +(((
14888 +(% class="macro-placeholder hidden" %)
14889 +(((
14890 +macro:include
14891 +)))
14892 +
14893 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
14894 + * Extract the layout parameters from a string.
14895 + *
14896 + * @param layoutParamsString The string representation of the layout parameters.
14897 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
14898 + * @param layoutsParameters The resulting layout parameters Map.
14899 + *###
14900 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
14901 + #set ($layoutsParameters = $NULL)
14902 + #set ($macro.layoutParams = \{})
14903 + #if (~"$!layoutParamsString~" != '')
14904 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
14905 + #foreach ($item in $macro.paramsArr)
14906 + #set ($itemSplit = $item.split('='))
14907 + #if ($itemSplit.size() == 2)
14908 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
14909 + #end
14910 + #end
14911 + #end
14912 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
14913 +#end" %)
14914 +(((
14915 +(% class="macro-placeholder hidden" %)
14916 +(((
14917 +macro:velocity
14918 +)))
14919 +)))
14920 +)))
14921 +
14922 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
14923 + #initLayoutVars($pDoc $pObj)
14924 + <div class=~"col-xs-12 col-sm-6 next_blog~">
14925 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
14926 + <div class=~"row~">
14927 + <div class=~"col-xs-4~">
14928 + #if ($imageAtt)
14929 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
14930 + #end
14931 + </div>
14932 + <div class=~"col-xs-8 art_det~">
14933 + <p class=~"text-left~">
14934 + #if($displayTitle)$!postTitle #end
14935 + <br/><span class=~"date_info~"> $!dateStr </span>
14936 + </p>
14937 + #displayPostDetails($pDoc)
14938 + </div>
14939 + </div>
14940 + </a>
14941 + </div>
14942 + #end
14943 + ##
14944 + ##
14945 + ##
14946 + #macro(displayPinnedPost $pDoc $pObj)
14947 + #initLayoutVars($pDoc $pObj)
14948 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
14949 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
14950 + <div class=~"thumbnail~">
14951 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
14952 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
14953 + #end
14954 + #if ($imageAtt)
14955 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
14956 + #end
14957 + <div class=~"caption~">
14958 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
14959 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
14960 + #end
14961 + #if ($displaySummaryOnPinnedPosts)
14962 + <div class=~"text-left post-summary~">
14963 + #set ($postContent = $pObj.getProperty('extract').value)
14964 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
14965 + </div>
14966 + #end
14967 + #displayPostDetails($pDoc)
14968 + </div>
14969 + </div>
14970 + </a>
14971 + </div>
14972 + #end
14973 + ##
14974 + ##
14975 + ##
14976 + #macro(formatPostDate $pDoc $pObj)
14977 + #set ($formattedDate = $NULL)
14978 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
14979 + #if (~"$!dateStr~" != '')
14980 + #set ($dateArr = $dateStr.split(' '))
14981 + #if ($dateArr.size() > 3)
14982 + #set ($dateStr = ~"~")
14983 + #foreach($s in $dateArr.subList(0, 3))
14984 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
14985 + #end
14986 + #end
14987 + #end
14988 + #setVariable(~"$formattedDate~" $dateStr)
14989 + #end
14990 + ##
14991 + ##
14992 + ##
14993 + #macro(displayPostDetails $pDoc)
14994 + <div class=~"row post-details~">
14995 + <div class=~"col-xs-8 detail~">
14996 + #if ($services.like.displayButton($pDoc.documentReference))
14997 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
14998 + ## Retrieve the likes number in XWiki 12.9+
14999 + #set ($likeNumber = $optLikeRecord.get())
15000 + #if (!$stringtool.isNumeric($likeNumber.toString()))
15001 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
15002 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
15003 + #end
15004 + #if ($stringtool.isNumeric($likeNumber.toString()))
15005 + <div class=~"post-likes btn btn-default disabled badge~"
15006 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
15007 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
15008 + </div>
15009 + #end
15010 + #elseif ($services.ratings)
15011 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
15012 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
15013 + <ul class=~"pull-left note list-inline~">
15014 + #foreach ($x in [1..5])
15015 + #set ($cls = ~"~")
15016 + #if ($x > $averageVote)
15017 + #set ($cls = ~"-o~")
15018 + #end
15019 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
15020 + #end
15021 + </ul>
15022 + #end
15023 + #end
15024 + </div>
15025 + #if ($showPostComments)
15026 + <div class=~"col-xs-4 com_det~">
15027 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
15028 + </div>
15029 + #end
15030 + </div>
15031 + #end
15032 + ##
15033 + ##
15034 + ##
15035 + #macro(initLayoutVars $pDoc $pObj)
15036 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
15037 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
15038 + #isPublished($pObj $isPublished)
15039 + #isHidden($pObj $isHidden)
15040 + #getEntryDate($pDoc $pObj $postDate)
15041 + #formatPostDate($postDate $dateStr)
15042 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
15043 + #set ($nbComments = $pDoc.getComments().size())
15044 + #set ($showPostComments = true)
15045 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
15046 + #set ($showPostComments = false)
15047 + #end
15048 + #end
15049 + ##
15050 + ##
15051 + ##
15052 + #macro(displayEditPinnedPostsButton)
15053 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
15054 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
15055 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
15056 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
15057 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
15058 + <div class=~"edit-pinned-posts-container~">
15059 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
15060 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
15061 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
15062 + </a>
15063 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
15064 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
15065 + </div>
15066 + </div>
15067 + #if (~"$!pinnedPostsObj~" == '')
15068 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
15069 + #end
15070 + #end
15071 + #end" %)
15072 +(((
15073 +(% class="macro-placeholder hidden" %)
15074 +(((
15075 +macro:velocity
15076 +)))
15077 +)))
15078 +
15079 +(% data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
15080 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
15081 + #getEntryObject($postDoc $postObj)
15082 + #if (~"$!postObj~" != '')
15083 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
15084 + ##
15085 + #set ($displayTitle = true)
15086 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
15087 + #set ($displayTitle = false)
15088 + #end
15089 + ##
15090 + #set ($displayTitleFirstOnPinnedPosts = false)
15091 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
15092 + #set ($displayTitleFirstOnPinnedPosts = true)
15093 + #end
15094 + ##
15095 + #set ($displaySummaryOnPinnedPosts = true)
15096 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
15097 + #set ($displaySummaryOnPinnedPosts = false)
15098 + #end
15099 + ##
15100 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
15101 + #if ($postIndex == 0)
15102 + #set ($stopBlogPostsDisplay = false)
15103 + #end
15104 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
15105 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
15106 + #set($scaleWidth = 600)
15107 + #set($imgQs=~"width=$scaleWidth~")
15108 + ## Display pinned posts
15109 + ## Get the list of pinned posts
15110 + #set ($pinnedPosts = [])
15111 + #set ($pinnedPostsSourceDoc = $NULL)
15112 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
15113 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
15114 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
15115 + #end
15116 + #if (~"$!pinnedPostsSourceDoc~" != '')
15117 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
15118 + #if (~"$!pinnedPostsObj~" != '')
15119 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
15120 + #if (~"$!orderedPinnedPostsJSON~" != '')
15121 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
15122 + #else
15123 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
15124 + #end
15125 + #end
15126 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
15127 + \{\{html clean=~"false~"}}
15128 + #set ($x = 0)
15129 + #set ($showPinnedPostsButton = true)
15130 + #foreach ($pinnedPost in $pinnedPosts)
15131 + #if ($x == 0)
15132 + <div class=~"row flex-container~">
15133 + #if ($showPinnedPostsButton)
15134 + #displayEditPinnedPostsButton()
15135 + #set($showPinnedPostsButton = false)
15136 + #end
15137 + #end
15138 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
15139 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
15140 + #if (~"$!pinnedPostObj~" != '')
15141 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
15142 + #end
15143 + #set ($x = $mathtool.add($x, 1))
15144 + #if ($x == 3)
15145 + #set ($x = 0)
15146 + </div>
15147 + #end
15148 + #end
15149 + #if ($mathtool.mod($x, 3) != 0)
15150 + </div>
15151 + #end
15152 + \{\{/html}}
15153 +
15154 + ## If the first post is a pinned post : this means that all the posts are pinned
15155 + ## In this case, avoid displaying the posts again after the pinned posts section.
15156 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
15157 + #set ($stopBlogPostsDisplay = true)
15158 + #end
15159 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
15160 +
15161 + \{\{html}}
15162 + <div class=~"row no-pinnded-posts~">
15163 + #displayEditPinnedPostsButton()
15164 + </div>
15165 + \{\{/html}}
15166 +
15167 + #end
15168 + #end
15169 + #if (!$stopBlogPostsDisplay)
15170 + \{\{html clean=~"false~"}}
15171 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
15172 + #set ($nbDisplayedPosts = 0)
15173 + #end
15174 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
15175 + #if ($nbDisplayedPosts != 0)
15176 + </div>
15177 + #set ($lastHtmlTag = 'c')
15178 + #end
15179 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
15180 + <div class=~"row~">
15181 + #set ($lastHtmlTag = 'o')
15182 + #set ($lastRowClass = ~"~")
15183 + #else
15184 + <div class=~"row flex-container~">
15185 + #set ($lastHtmlTag = 'o')
15186 + #set ($lastRowClass = ~"flex~")
15187 + #end
15188 + #end
15189 + #displaySmallPost($postDoc $postObj)
15190 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
15191 + </div>
15192 + #set ($lastHtmlTag = 'c')
15193 + #end
15194 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
15195 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
15196 + #if (~"$!lastHtmlTag~" == 'o')
15197 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
15198 + <div class=~"col-xs-12 col-sm-6~"></div>
15199 + #end
15200 + </div>
15201 + #end
15202 + #end
15203 + \{\{/html}}
15204 + #end
15205 + #else
15206 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
15207 + #end
15208 + #else
15209 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
15210 + #end" class="macro hidden macro-placeholder" %)macro:velocity(% data-macro="startmacro:html|-|clean=~"false~"|-|</div>
15211 +<div class=~"row flex-container~">
15212 +<div class=~"col-xs-12 col-sm-6 next_blog~">
15213 +<a href=~"/Nieuws/Nieuw%20beveiligingspaneel%20Axon%20van%20Aritech~" class=~"thumbnail~">
15214 +<div class=~"row~">
15215 +<div class=~"col-xs-4~">
15216 +<img src=~"/download/Nieuws/Nieuw%20beveiligingspaneel%20Axon%20van%20Aritech/axon.png?width=600&rev=1.1~" />
15217 +</div>
15218 +<div class=~"col-xs-8 art_det~">
15219 +<p class=~"text-left~">
15220 +Nieuw beveiligingspaneel Axon van Aritech <br/><span class=~"date_info~"> Nov 22, 2023, </span>
15221 +</p>
15222 +<div class=~"row post-details~">
15223 +<div class=~"col-xs-8 detail~">
15224 +<div class=~"post-likes btn btn-default disabled badge~"
15225 +title=~"Number of likes on this page: 1~">
15226 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">1</span>
15227 +</div>
15228 +</div>
15229 +<div class=~"col-xs-4 com_det~">
15230 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (1)</p>
15231 +</div>
15232 +</div>
15233 +</div>
15234 +</div>
15235 +</a>
15236 +</div>" class="macro macro hidden macro-placeholder" %)macro:html
15237 +)))
15238 +)))
15239 +
15240 +(% class="row flex-container" %)
15241 +(((
15242 +(% class="col-xs-12 col-sm-6 next_blog" %)
15243 +(((
15244 +(% class="row" %)
15245 +(((
15246 +(% class="col-xs-4" %)
15247 +(((
15248 +[[~[~[image:/download/Nieuws/Nieuw%20beveiligingspaneel%20Axon%20van%20Aritech/axon.png?width=600&rev=1.1~]~]>>path:/Nieuws/Nieuw%20beveiligingspaneel%20Axon%20van%20Aritech||class="thumbnail"]]
15249 +)))
15250 +
15251 +(% class="col-xs-8 art_det" %)
15252 +(((
15253 +(% class="text-left" %)
15254 +[[Nieuw beveiligingspaneel Axon van Aritech
15255 +(% class="date_info" %) Nov 22, 2023,>>path:/Nieuws/Nieuw%20beveiligingspaneel%20Axon%20van%20Aritech||class="thumbnail"]]
15256 +
15257 +(% class="row post-details" %)
15258 +(((
15259 +(% class="col-xs-8 detail" %)
15260 +(((
15261 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 1" %)
15262 +(((
15263 +[[(% class="like-number" %)1>>path:/Nieuws/Nieuw%20beveiligingspaneel%20Axon%20van%20Aritech||class="thumbnail"]]
15264 +)))
15265 +)))
15266 +
15267 +(% class="col-xs-4 com_det" %)
15268 +(((
15269 +(% class="text-right" %)
15270 +[[(1)>>path:/Nieuws/Nieuw%20beveiligingspaneel%20Axon%20van%20Aritech||class="thumbnail"]]
15271 +)))
15272 +)))
15273 +)))
15274 +)))
15275 +)))
15276 +
15277 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Aankondiging update Syntess 6\\\\.9\\\\.0\\\\.0166~" params=~"displayTitle=true|useSummary=true|list-limit=10|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=10|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG|postIndex=3|previousPostReference=Nieuws.Nieuwsbrief december 2023|postIndex=4|previousPostReference=Nieuws.Nieuwsbrief november 2023|postIndex=5|previousPostReference=Nieuws.Feestelijke afsluiting, keuring materieel en tellen voorraden|postIndex=6|previousPostReference=Nieuws.RI&E 2023|postIndex=7|previousPostReference=Nieuws.Aankondiging update Syntess 6\\\\.9\\\\.0181|postIndex=8|previousPostReference=Nieuws.Nieuwsbrief oktober 2023|postIndex=9|previousPostReference=Nieuws.Nieuw beveiligingspaneel Axon van Aritech~"" %)
15278 +(((
15279 +(% class="macro-placeholder hidden" %)
15280 +(((
15281 +macro:blogPostLayoutCards
15282 +)))
15283 +
15284 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %)
15285 +(((
15286 +(% class="macro-placeholder hidden" %)
15287 +(((
15288 +macro:include
15289 +)))
15290 +
15291 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %)
15292 +(((
15293 +(% class="macro-placeholder hidden" %)
15294 +(((
15295 +macro:include
15296 +)))
15297 +
15298 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog
15299 +#set($blogClassname = 'Blog.BlogClass')
15300 +#set($blogTemplate = 'Blog.BlogTemplate')
15301 +#set($blogSheet = 'Blog.BlogSheet')
15302 +## Blog entries
15303 +#set($blogPostClassname = 'Blog.BlogPostClass')
15304 +#set($blogPostTemplate = 'Blog.BlogPostTemplate')
15305 +#set($blogPostSheet = 'Blog.BlogPostSheet')
15306 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number)
15307 +#set($oldArticleClassname = 'XWiki.ArticleClass')
15308 +## Categories
15309 +#set($blogCategoryClassname = 'Blog.CategoryClass')
15310 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate')
15311 +#set($blogCategorySheet = 'Blog.CategorySheet')
15312 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet')
15313 +#set($oldBlogCategoryClassname = 'Blog.Categories')
15314 +#set($defaultCategoryParent = 'Blog.Categories')
15315 +## Style
15316 +#set($blogStyleDocumentName = 'Blog.BlogStyle')
15317 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName))
15318 +## Clientside scripts
15319 +#set($blogScriptsDocumentName = 'Blog.BlogScripts')
15320 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher'))
15321 +## Misc
15322 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString))
15323 +#set($isBlogPost = $doc.getObject($blogPostClassname))
15324 +#set($defaultBlogSpace = 'Blog')
15325 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname))
15326 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
15327 +##
15328 +##
15329 +##
15330 +#**
15331 + * Displays an image, taken from the blog style document.
15332 + *
15333 + * @param $imgName The name of the icon from icons set to use.
15334 + *#
15335 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %)
15336 +(((
15337 +(% class="macro-placeholder hidden" %)
15338 +(((
15339 +macro:velocity
15340 +)))
15341 +)))
15342 +)))
15343 +
15344 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|##
15345 +##
15346 +##
15347 +## Import the blog skin and javascripts.
15348 +$!xwiki.ssx.use($blogStyleDocumentName)##
15349 +$!xwiki.jsx.use($blogScriptsDocumentName)##
15350 +##
15351 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
15352 +#template('hierarchy_macros.vm')##
15353 +##
15354 +##
15355 +#**
15356 + * Prints a blog. This is the main macro used in the BlogSheet.
15357 + *
15358 + * @param blogDoc the XDocument holding the blog definition object.
15359 + *###
15360 +#macro(printBlog $blogDoc)
15361 + \{\{include reference='Blog.CreatePost'/}}
15362 +
15363 + ## Use the blogPostList macro to display the blogposts
15364 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
15365 + ## do not support FTM the monthly and weekly blog display types
15366 + #getBlogDisplayType($blogDoc $displayType)
15367 + #if ($displayType == 'weekly' || $displayType == 'monthly')
15368 + #getBlogEntries($blogDoc $entries)
15369 + #displayBlog($entries 'index' true true)
15370 + #displayNavigationLinks($blogDoc)
15371 + #else
15372 + #getBlogDisplayType($blogDoc $displayType)
15373 + #set ($paginated = 'no')
15374 + #if ($displayType == 'paginated')
15375 + #set ($paginated = 'yes')
15376 + #end
15377 + #getBlogPostsLayout($blogDoc $postsLayout)
15378 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}})))
15379 + #end
15380 +#end
15381 +##
15382 +##
15383 +##
15384 +#**
15385 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
15386 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
15387 + * all entries).
15388 + *
15389 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
15390 + *###
15391 +#macro(showBlogInfo $blogDoc)
15392 + #if($blogDoc.getObject($blogClassname))
15393 + ## Keep testing for inline action for backward compatibility with older blogs.
15394 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
15395 + #macro(displayProperty $blogDoc $propname)
15396 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
15397 + : $blogDoc.display($propname)
15398 + #end
15399 + #displayProperty($blogDoc 'title')
15400 + #displayProperty($blogDoc 'description')
15401 + #displayProperty($blogDoc 'displayType')
15402 + #displayProperty($blogDoc 'itemsPerPage')
15403 + #displayProperty($blogDoc 'postsLayout')
15404 + #displayProperty($blogDoc 'postsLayoutParameters')
15405 + #else
15406 + $blogDoc.display('description')
15407 + #end
15408 + #elseif($doc.fullName == $blogSheet)
15409 += $services.localization.render('blog.code.blogsheet') =
15410 + \{\{translation key='blog.code.sheetexplanation'/}}
15411 + #else
15412 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}}
15413 + #end
15414 +#end
15415 +##
15416 +##
15417 +##
15418 +#**
15419 + * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
15420 + * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
15421 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
15422 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
15423 + *
15424 + * @param space A <tt>String</tt>, the name of the space where to search.
15425 + * @param blogDoc The resulting XDocument.
15426 + *###
15427 +#macro(getBlogDocument $space $blogDoc)
15428 + #set ($result = $NULL)
15429 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
15430 + ## It is possible to display a blog's panels info in a page that is not inside a blog and in that case we need to
15431 + ## identify the right blog based on a configuration object in a WebPreferences page.
15432 + #set ($spaceReference = $services.model.resolveSpace($space))
15433 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
15434 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
15435 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
15436 + #if ($preferencesObj)
15437 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
15438 + #end
15439 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
15440 + #if (~"$!result~" == '')
15441 + ## First, try the Space.WebHome, for a whole-space blog
15442 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~"))
15443 + #if(!$result.getObject($blogClassname))
15444 + ## Second, try the Space.Blog document
15445 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~"))
15446 + #if(!$result.getObject($blogClassname))
15447 + ## Third, try searching for a blog document in the current space
15448 + ## Prevent the query fail when the space contains dots '.'
15449 + #set($blogDocs = $services.query.hql(~", BaseObject obj where doc.space = :space and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name~").setLimit(1).setOffset(0).bindValue('space', $space).execute())
15450 + #if($blogDocs.size() > 0)
15451 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
15452 + #else
15453 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
15454 + #set($blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as postsLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=postsLocationProp.id.id and postsLocationProp.id.name='postsLocation' and postsLocationProp.value=:postsLocation order by doc.name~").setLimit(1).setOffset(0).bindValue('postsLocation', $space).execute())
15455 + #if($blogDocs.size() > 0)
15456 + #set($result = $xwiki.getDocument($blogDocs.get(0)))
15457 + #else
15458 + ## Last, fallback to Blog.WebHome, the default blog
15459 + #set($result = $xwiki.getDocument('Blog.WebHome'))
15460 + #end
15461 + #end
15462 + #end
15463 + #end
15464 + #end
15465 + #set ($blogDoc = $NULL)
15466 + #setVariable (~"$blogDoc~" $result)
15467 +#end
15468 +##
15469 +##
15470 +##
15471 +#**
15472 + * Retrieve the blog title.
15473 + *
15474 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
15475 + * @param title The resulting title.
15476 + *###
15477 +#macro(getBlogTitle $blogDoc $title)
15478 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
15479 + #set ($title = $NULL)
15480 + #setVariable (~"$title~" $!blogDoc.displayTitle)
15481 +#end
15482 +##
15483 +##
15484 +##
15485 +#**
15486 + * Retrieve the blog description.
15487 + *
15488 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
15489 + * property set.
15490 + * @param description The resulting description.
15491 + *###
15492 +#macro(getBlogDescription $blogDoc $description)
15493 + #getBlogProperty($blogDoc 'description' '' $result)
15494 + #set ($description = $NULL)
15495 + #setVariable (~"$description~" $result)
15496 +#end
15497 +##
15498 +##
15499 +##
15500 +#**
15501 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
15502 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
15503 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
15504 + * month), or all.
15505 + *
15506 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
15507 + * @param entries The resulting list of entries to display, a list of XDocument names.
15508 + *###
15509 +#macro(getBlogEntries $blogDoc $entries)
15510 + #if (!$entries)
15511 + #setVariable (~"$entries~" [])
15512 + #end
15513 + #getAllBlogPostsQuery($query)
15514 + #isDefaultBlog($blogDoc $isDefault)
15515 + #set($queryParams = \{})
15516 + #if ($isDefault)
15517 + #getCategoryAllBlogPostsQuery($query)
15518 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~")
15519 + #set($discard = $queryParams.put('creator', $xcontext.user))
15520 + #set($discard = $queryParams.put('space', $blogDoc.space))
15521 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
15522 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
15523 + #else
15524 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~")
15525 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
15526 + #set($discard = $queryParams.put('space', $blogPostsLocation))
15527 + #set($discard = $queryParams.put('parent', $blogDoc.space))
15528 + #end
15529 + #getBlogDisplayType($blogDoc $displayType)
15530 + #if($displayType == 'weekly')
15531 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
15532 + #elseif($displayType == 'monthly')
15533 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
15534 + #elseif($displayType == 'all')
15535 + #getAllBlogEntries($blogDoc $query $entries $queryParams)
15536 + #else
15537 + #getPagedBlogEntries($blogDoc $query $entries $queryParams)
15538 + #end
15539 +#end
15540 +##
15541 +##
15542 +##
15543 +#**
15544 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents
15545 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
15546 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
15547 + * (10 if not defined).
15548 + *
15549 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
15550 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
15551 + * refined to restrict to a given space, or to a given search criteria, etc.
15552 + * @param entries The resulting list of entries to display, a list of XDocument names.
15553 + * @param queryParams The parameters to bind with the query.
15554 + *###
15555 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
15556 + #if (!$entries)
15557 + #setVariable (~"$entries~" [])
15558 + #end
15559 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
15560 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~"))
15561 + #bindQueryParameters($countQueryObj $queryParams)
15562 + #bindQueryParameters($queryObj $queryParams)
15563 + #set($totalEntries = $countQueryObj.count())
15564 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
15565 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
15566 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
15567 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
15568 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute()))
15569 +#end
15570 +##
15571 +##
15572 +##
15573 +#**
15574 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
15575 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
15576 + * digit year). Initially the current week is displayed.
15577 + *
15578 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
15579 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
15580 + * refined to restrict to a given space, or to a given search criteria, etc.
15581 + * @param entries The resulting list of entries to display, a list of XDocument names.
15582 + * @param queryParams The parameters to bind with the query.
15583 + *###
15584 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
15585 + #if (!$entries)
15586 + #setVariable (~"$entries~" [])
15587 + #end
15588 + #getRequestedWeek($weekDate)
15589 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
15590 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
15591 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
15592 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
15593 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
15594 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
15595 + #bindQueryParameters($countQueryObj $queryParams)
15596 + #bindQueryParameters($queryObj $queryParams)
15597 + #set($totalEntries = $countQueryObj.count())
15598 + #set($discard = $entries.addAll($queryObj.execute()))
15599 +#end
15600 +##
15601 +##
15602 +##
15603 +#**
15604 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
15605 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
15606 + * digit year). Initially the current month is displayed.
15607 + *
15608 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
15609 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
15610 + * refined to restrict to a given space, or to a given search criteria, etc.
15611 + * @param entries The resulting list of entries to display, a list of XDocument names.
15612 + * @param queryParams The parameters to bind with the query.
15613 + *###
15614 +#macro(getMonthlyBlogEntries $blogDoc $query $entries)
15615 + #if (!$entries)
15616 + #setVariable (~"$entries~" [])
15617 + #end
15618 + #getRequestedMonth($monthDate)
15619 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
15620 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
15621 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
15622 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~")
15623 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
15624 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
15625 + #bindQueryParameters($countQueryObj $queryParams)
15626 + #bindQueryParameters($queryObj $queryParams)
15627 + #set($totalEntries = $countQueryObj.count())
15628 + #set($discard = $entries.addAll($queryObj.execute()))
15629 +#end
15630 +##
15631 +##
15632 +##
15633 +#**
15634 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
15635 + *
15636 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
15637 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
15638 + * refined to restrict to a given space, or to a given search criteria, etc.
15639 + * @param entries The resulting list of entries to display, a list of XDocument names.
15640 + * @param queryParams The parameters to bind with the query.
15641 + *###
15642 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
15643 + #if (!$entries)
15644 + #setVariable (~"$entries~" [])
15645 + #end
15646 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
15647 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
15648 + #bindQueryParameters($countQueryObj $queryParams)
15649 + #bindQueryParameters($queryObj $queryParams)
15650 + #set($totalEntries = $countQueryObj.count())
15651 + #set($discard = $entries.addAll($queryObj.execute()))
15652 +#end
15653 +##
15654 +##
15655 +##
15656 +#**
15657 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
15658 + *
15659 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
15660 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
15661 + * refined to restrict to a given space, or to a given search criteria, etc.
15662 + * @param queryParams The parameters to bind with the query.
15663 + * @param entries The resulting list of entries to display, a list of XDocument names.
15664 + *###
15665 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
15666 + #if (!$entries)
15667 + #setVariable (~"$entries~" [])
15668 + #end
15669 + #set($query = ~"$\{query} and isPublished.value = 0~")
15670 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~"))
15671 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~"))
15672 + #bindQueryParameters($countQueryObj $queryParams)
15673 + #bindQueryParameters($queryObj $queryParams)
15674 + #set($totalEntries = $countQueryObj.count())
15675 + #set($discard = $entries.addAll($queryObj.execute()))
15676 +#end
15677 +##
15678 +##
15679 +##
15680 +#**
15681 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
15682 + *
15683 + * @param entries The resulting list of entries to display, a list of XDocument names.
15684 + *###
15685 +#macro(getGlobalBlogEntries $entries)
15686 + #if (!$entries)
15687 + #setVariable (~"$entries~" [])
15688 + #end
15689 + #getAllBlogPostsQuery($query)
15690 + #set($totalEntries = $services.query.hql($query).count())
15691 + #set($defaultItemsPerPage = 20)
15692 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
15693 + #preparePagedViewParams($totalEntries $defaultItemsPerPage)
15694 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute()))
15695 +#end
15696 +#**
15697 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
15698 + * blog, nor specify a range or an ordering criteria.
15699 + *
15700 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
15701 + *
15702 + * @param query The basic query for selecting blog entries.
15703 + *#
15704 +#macro(getBlogEntriesBaseQuery $query)
15705 + #getAllBlogPostsQuery($query)
15706 +#end
15707 +#**
15708 + * Return the Query for selecting the all wiki blog posts without filtering
15709 + *
15710 + * @param query The basic query for selecting blog entries.
15711 + *#
15712 +#macro(getAllBlogPostsQuery $query)
15713 + #set ($query = $NULL)
15714 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished,
15715 + IntegerProperty hidden, DateProperty publishDate
15716 + where doc.fullName <> '$blogPostTemplate' and
15717 + obj.name=doc.fullName and obj.className='$blogPostClassname' and
15718 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and
15719 + hidden.id.id = obj.id and hidden.id.name='hidden' and
15720 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
15721 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~")
15722 +#end
15723 +##
15724 +##
15725 +##
15726 +###**
15727 + * Return the Query for selecting the all wiki blog posts with categories filtering
15728 + *
15729 + * @param query The basic query for selecting blog entries.
15730 + *###
15731 +#macro(getCategoryAllBlogPostsQuery $query)
15732 + #set ($query = $NULL)
15733 + #getAllBlogPostsQuery($baseQuery)
15734 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
15735 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~")
15736 +#end
15737 +##
15738 +##
15739 +##
15740 +#**
15741 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
15742 + * week), monthly (all entries in a month), or all.
15743 + *
15744 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
15745 + * property set.
15746 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
15747 + *###
15748 +#macro(getBlogDisplayType $blogDoc $displayType)
15749 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
15750 + #set ($displayType = $NULL)
15751 + #setVariable (~"$displayType~" $result)
15752 +#end
15753 +##
15754 +##
15755 +##
15756 +#**
15757 + * Displays a list of entries.
15758 + *
15759 + * @param entries The entries to display, a list of XDocument names.
15760 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
15761 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
15762 + * used values: index, single, category, search, unpublished, hidden.
15763 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
15764 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
15765 + * displayed alone on their page since it's the page title which is used in this case)
15766 + *###
15767 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
15768 + #set($blogDay = '')
15769 + (% class=~"hfeed $!\{displaying}~" ~%)(((
15770 + (% class=~"blogDay~" ~%)(((
15771 + #foreach ($entryDoc in $xwiki.wrapDocs($entries))
15772 + #getEntryObject($entryDoc $entryObj)
15773 + ## Although all entries should have one of the two objects, better check to be sure.
15774 + #if(~"$!\{entryObj}~" != '')
15775 + #getEntryDate($entryDoc $entryObj $entryDate)
15776 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet.
15777 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
15778 + #if($blogDay != $entryDateStr)
15779 + #if($blogDay != '')
15780 + )))
15781 + (% class=~"blogDay~" ~%)(((
15782 + #end
15783 + #displayBlogDate($entryDate)
15784 + #set ($blogDay = $entryDateStr)
15785 + #end
15786 + ## Finally, display the entry.
15787 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
15788 + #end
15789 + #end
15790 + )))## blogDay
15791 + )))## hfeed
15792 +#end
15793 +##
15794 +##
15795 +##
15796 +#**
15797 + * Get the entry object, either a new BlogPost or an old Article.
15798 + *
15799 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
15800 + * @param entryObj The resulting xobject of the blog post.
15801 + *###
15802 +#macro(getEntryObject $entryDoc $__entryObj)
15803 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~"))
15804 + #if(!$result)
15805 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~"))
15806 + #end
15807 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
15808 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
15809 + ## overwritten in this case but it's less likely to have such a variable defined before.
15810 + #set ($__entryObj = $NULL)
15811 + #setVariable (~"$__entryObj~" $result)
15812 +#end
15813 +##
15814 +##
15815 +##
15816 +#**
15817 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
15818 + * the document creation date, but can be edited by the user.
15819 + *
15820 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
15821 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
15822 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
15823 + *###
15824 +#macro(getEntryDate $entryDoc $entryObj $result)
15825 + #set ($result = $NULL)
15826 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value)
15827 +#end
15828 +##
15829 +##
15830 +##
15831 +#**
15832 + * Displays a date, nicely formatted as a calendar page.
15833 + *
15834 + * @param date The date to display, an instance of <tt>java.util.Date</tt>.
15835 + *###
15836 +#macro(displayBlogDate $date)
15837 + #set($year = $xwiki.formatDate($date, 'yyyy'))
15838 + ## 3 letter month name, like Jan, Dec.
15839 + #set($month = $xwiki.formatDate($date, 'MMM'))
15840 + ## Uncomment to get a full length month name, like January, December.
15841 + ## TODO: this could be defined somewhere in the blog style.
15842 + ## #set($month = $xwiki.formatDate($date, 'MMMM'))
15843 + #set($day = $xwiki.formatDate($date, 'dd'))
15844 + (% class=~"blogdate~" ~%)
15845 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) ==
15846 +#end
15847 +##
15848 +##
15849 +##
15850 +#**
15851 + * Displays a blog article: management tools, header, content, footer.
15852 + *
15853 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
15854 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
15855 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
15856 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
15857 + * when they're displayed alone on their page since it's the page title which is used in this case)
15858 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
15859 + *###
15860 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
15861 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
15862 + #isPublished($entryObj $isPublished)
15863 + #isHidden($entryObj $isHidden)
15864 + #if($doc.fullName == $entryDoc.fullName)
15865 + (% class=~"hentry single-article~" ~%)(((
15866 + #else
15867 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)(((
15868 + #end
15869 + #if ($shouldDisplayActions)
15870 + #displayEntryTools($entryDoc $entryObj)
15871 + #end
15872 + #if($shouldDisplayTitle)
15873 + #displayEntryTitle($entryDoc $entryObj)
15874 + #end
15875 + #if($doc.fullName == $entryDoc.fullName)
15876 + #if(!$isPublished)
15877 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}}
15878 + #elseif($isHidden)
15879 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}}
15880 + #end
15881 + #end
15882 + #displayEntryContent($entryDoc $entryObj $onlyExtract)
15883 + #displayEntryFooter($entryDoc $entryObj)
15884 + )))## hentry
15885 +#end
15886 +##
15887 +##
15888 +##
15889 +#**
15890 + * Checks if the provided blog is published or not.
15891 + *
15892 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
15893 + * @param isPublished The resulting boolean, true if the entry is considered published.
15894 + *###
15895 +#macro(isPublished $entryObj $isPublished)
15896 + #set ($isPublished = $NULL)
15897 + ## This should work for both old articles, which don't have the 'published' property at all, and
15898 + ## are considered published by default, and new entries, that should have 1 if published.
15899 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0')
15900 + #setVariable (~"$isPublished~" true)
15901 + #else
15902 + #setVariable (~"$isPublished~" false)
15903 + #end
15904 +#end
15905 +##
15906 +##
15907 +##
15908 +#**
15909 + * Checks if the provided blog is hidden or not.
15910 + *
15911 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
15912 + * @param isHiddel The resulting boolean, true if the entry is considered hidden.
15913 + *###
15914 +#macro(isHidden $entryObj $isHidden)
15915 + #set ($isHidden = $NULL)
15916 + ## This should work for both old articles, which don't have the 'hidden' property at all, and
15917 + ## are considered visible by default, and new entries, that should have 1 if hidden.
15918 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1')
15919 + #setVariable (~"$isHidden~" true)
15920 + #else
15921 + #setVariable (~"$isHidden~" false)
15922 + #end
15923 +#end
15924 +##
15925 +##
15926 +##
15927 +#**
15928 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit.
15929 + *
15930 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
15931 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
15932 + *###
15933 +#macro(displayEntryTools $entryDoc $entryObj)
15934 + #if($xcontext.action == 'view')
15935 + (% class=~"blog-entry-toolbox~" ~%)(((
15936 + #displayPublishButton($entryDoc $entryObj)
15937 + #displayHideShowButton($entryDoc $entryObj)
15938 + #displayEditButton($entryDoc $entryObj)
15939 + #displayDeleteButton($entryDoc $entryObj)
15940 + )))
15941 + #end
15942 +#end
15943 +##
15944 +##
15945 +##
15946 +#**
15947 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
15948 + *
15949 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
15950 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
15951 + * @todo AJAX calls.
15952 + *###
15953 +#macro(displayPublishButton $entryDoc $entryObj)
15954 + #isPublished($entryObj $isPublished)
15955 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
15956 + [[#toolImage('world')>>path:$blogPublisher.getURL('view', ~"entryName=$\{escapetool.url($entryDoc.fullName)}&xredirect=$\{escapetool.url($thisURL)}&form_token=$!\{services.csrf.getToken()}~")||title=~"$services.localization.render('blog.code.notpublished')~"]]##
15957 + #end
15958 +#end
15959 +##
15960 +##
15961 +##
15962 +#**
15963 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
15964 + *
15965 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
15966 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
15967 + *###
15968 +#macro(displayHideShowButton $entryDoc $entryObj)
15969 + #isPublished($entryObj $isPublished)
15970 + #isHidden($entryObj $isHidden)
15971 + ## Only published articles can be hidden. Unpublished articles are considered already hidden.
15972 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
15973 + #set ($queryString = \{
15974 + 'xredirect' : $thisURL,
15975 + 'form_token' : $services.csrf.getToken()
15976 + })
15977 + #if ($isHidden)
15978 + #set ($discard = $queryString.putAll(\{
15979 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0,
15980 + 'comment' : $services.localization.render('blog.code.madevisible')
15981 + }))
15982 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
15983 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]##
15984 + #else
15985 + #set ($discard = $queryString.putAll(\{
15986 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1,
15987 + 'comment' : $services.localization.render('blog.code.hid')
15988 + }))
15989 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
15990 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]##
15991 + #end
15992 + #end
15993 +#end
15994 +##
15995 +##
15996 +##
15997 +#**
15998 + * Displays the edit button to those that can edit the article.
15999 + *
16000 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
16001 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
16002 + *###
16003 +#macro(displayEditButton $entryDoc $entryObj)
16004 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
16005 + ## Call getDefaultEditMode() for backward compatibility with older blog posts.
16006 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]##
16007 + #end
16008 +#end
16009 +##
16010 +##
16011 +##
16012 +#**
16013 + * Displays the delete button to those that can edit the article.
16014 + *
16015 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
16016 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
16017 + * @todo AJAX calls.
16018 + *###
16019 +#macro(displayDeleteButton $entryDoc $entryObj)
16020 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
16021 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]##
16022 + #end
16023 +#end
16024 +##
16025 +##
16026 +##
16027 +#**
16028 + * Displays the title of the entry.
16029 + *
16030 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
16031 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
16032 + *###
16033 +#macro(displayEntryTitle $entryDoc $entryObj)
16034 + #if($doc.fullName == $entryDoc.fullName)
16035 + (% class=~"entry-title~" ~%)
16036 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
16037 + #else
16038 + (% class=~"entry-title~" ~%)
16039 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
16040 + #end
16041 +#end
16042 +##
16043 +##
16044 +##
16045 +#**
16046 + * Displays the body of the entry.
16047 + *
16048 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
16049 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
16050 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
16051 + *###
16052 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
16053 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)(((
16054 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
16055 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
16056 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
16057 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}}
16058 + ))) ## entry-content
16059 + (% class=~"clearfloats~" ~%)((()))
16060 +#end
16061 +##
16062 +##
16063 +##
16064 +#**
16065 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
16066 + * of the <tt>extract</tt> field (if not empty).
16067 + *
16068 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
16069 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
16070 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
16071 + * @param entryContent The resulting content.
16072 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
16073 + * <tt>onlyExtract</tt> is <tt>true</tt>)
16074 + *###
16075 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
16076 + #if ($onlyExtract)
16077 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
16078 + ## of the content.
16079 + #set ($macro.result = $entryObj.getProperty('extract').value.trim())
16080 + #end
16081 + #if(~"$!macro.result~" == '')
16082 + #set($macro.result = $entryObj.getProperty('content').value)
16083 +#* Disabled until the content can be cleanly cut.
16084 +* #if($onlyExtract && $result.length()>$maxchars)
16085 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars))
16086 +* #set($i = $i + 1)
16087 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~")
16088 +* #end
16089 +## *###
16090 + #elseif (!$removeEllipsis)
16091 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
16092 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~")
16093 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
16094 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~")
16095 + #end
16096 + #end
16097 + #set ($entryContent = $NULL)
16098 + #setVariable (~"$entryContent~" $macro.result)
16099 +#end
16100 +##
16101 +##
16102 +##
16103 +#**
16104 + * Displays the footer of the entry.
16105 + *
16106 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
16107 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
16108 + *###
16109 +#macro(displayEntryFooter $entryDoc $entryObj)
16110 + (% class=~"entry-footer~" ~%)(((
16111 + #isPublished($entryObj $isPublished)
16112 + (% class='entry-author-label' ~%)
16113 + #if($isPublished)
16114 + \{\{translation key='blog.code.postedby'/}} ##
16115 + #else
16116 + \{\{translation key='blog.code.createdby'/}} ##
16117 + #end
16118 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ##
16119 + #getEntryDate($entryDoc $entryObj $entryDate)
16120 + #listCategories($entryObj) #*
16121 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
16122 + ## we assume cannot be more than 3 seconds.
16123 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ##
16124 + #if ($showcomments)
16125 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ##
16126 + #end ##
16127 + #if($entryDoc != $doc) ##
16128 + #displayEntryBlogLocation($entryDoc $entryObj) ##
16129 + #end
16130 + )))## entry-footer
16131 +#end
16132 +##
16133 +##
16134 +#**
16135 + * Display the blog for the entry (if it is not the currently displayed blog)
16136 + *
16137 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
16138 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
16139 + *###
16140 +#macro(displayEntryBlogLocation $entryDoc $entryObj)
16141 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
16142 + #if(~"$!blogPostsLocation~" != ~"~") ##
16143 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
16144 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
16145 + #if($doc.documentReference != $blogDocRef) ##
16146 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
16147 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
16148 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ##
16149 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ##
16150 + )))(%~%)##
16151 + #end
16152 + #end
16153 + #end
16154 +#end
16155 +##
16156 +##
16157 +##
16158 +##
16159 +#**
16160 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
16161 + *
16162 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
16163 + *###
16164 +#macro(listCategories $entryObj)
16165 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
16166 + #set($categories = $entryObj.getProperty('category').value)
16167 + #set($first = true)
16168 + #if($categories.size() > 0)
16169 + #foreach($category in $categories)
16170 + #set($categoryDoc = $!xwiki.getDocument($category))
16171 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname}))
16172 + #if($foreach.count == 1)
16173 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ##
16174 + #else
16175 + , ##
16176 + #end##
16177 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]##
16178 + #end##
16179 + #end##
16180 + #end
16181 + #end
16182 +#end
16183 +##
16184 +##
16185 +##
16186 +#**
16187 + * Displays blog pagination links (older and newer entries).
16188 + *
16189 + * @param blogDoc the XDocument holding the blog definition object.
16190 + *###
16191 +#macro(displayNavigationLinks $blogDoc)
16192 + (% class=~"clearfloats~" ~%)((()))
16193 + #getBlogDisplayType($blogDoc $displayType)
16194 + #if($displayType == 'weekly')
16195 + (% class=~"pagingLinks~" ~%)(((
16196 + #getRequestedWeek($weekDate)
16197 + $weekDate.addWeeks(-1)##
16198 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
16199 + #sep()
16200 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
16201 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%)
16202 + )))
16203 + #elseif($displayType == 'monthly')
16204 + (% class=~"pagingLinks~" ~%)(((
16205 + #getRequestedMonth($monthDate)
16206 + $monthDate.addMonths(-1)##
16207 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
16208 + #sep()
16209 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above
16210 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%)
16211 + )))
16212 + #elseif($displayType == 'all')
16213 + #else
16214 + ## Paginated
16215 + #if(($totalPages > 1))
16216 + #set($queryString = '')
16217 + #foreach($p in $request.getParameterNames())
16218 + #if($p != 'page' && $p != 'ipp')
16219 + #foreach($v in $request.getParameterValues($p))
16220 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~")
16221 + #end
16222 + #end
16223 + #end
16224 + (% class=~"pagingLinks~" ~%)(((
16225 + #if ($currentPageNumber < $totalPages)
16226 + #set($currentPageNumber = $currentPageNumber + 1)
16227 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
16228 + #set($currentPageNumber = $currentPageNumber - 1)
16229 + #end
16230 + #if ($currentPageNumber > 1)
16231 + #if ($currentPageNumber < $totalPages)
16232 + #sep()
16233 + #end
16234 + #set($currentPageNumber = $currentPageNumber - 1)
16235 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%)
16236 + #set($currentPageNumber = $currentPageNumber + 1)
16237 + #end
16238 + (% class=~"clear~" ~%)(%~%)
16239 + )))## pagingLinks
16240 + #end
16241 + #end
16242 +#end
16243 +##
16244 +##
16245 +##
16246 +#**
16247 + * Displays a message box with ~"publish~" icon.
16248 + *
16249 + * @param message A text message concerning blog article publishing
16250 + *###
16251 +#macro(publishMessageBox $message)
16252 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message)))
16253 +#end
16254 +#**
16255 + * Displays a message box with ~"show/hide~" icon.
16256 + *
16257 + * @param message A text message concerning blog article hiding
16258 + *###
16259 +#macro(hideMessageBox $message)
16260 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message)))
16261 +#end
16262 +##
16263 +##
16264 +##
16265 +#**
16266 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
16267 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
16268 + *
16269 + * @param monthDate The resulting week, a JODATime MutableDateTime.
16270 + *###
16271 +#macro(getRequestedWeek $weekDate)
16272 + #set ($weekDate = $NULL)
16273 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime)
16274 + #if(~"$!\{request.year}~" != '')
16275 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
16276 + #end
16277 + #if(~"$!\{request.week}~" != '')
16278 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
16279 + #end
16280 +#end
16281 +##
16282 +##
16283 +##
16284 +#**
16285 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
16286 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
16287 + *
16288 + * @param monthDate The resulting month, a JODATime MutableDateTime.
16289 + *###
16290 +#macro(getRequestedMonth $monthDate)
16291 + #set ($monthDate = $NULL)
16292 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime)
16293 + #if(~"$!\{request.year}~" != '')
16294 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
16295 + #end
16296 + #if(~"$!\{request.month}~" != '')
16297 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
16298 + #end
16299 +#end
16300 +##
16301 +##
16302 +##
16303 +#**
16304 + * Retrieve a blog property (title, display type, etc).
16305 + *
16306 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
16307 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
16308 + * @param defaultValue The default value to use in case the blog object does not define one.
16309 + * @param propertyValue The resulting value.
16310 + *###
16311 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
16312 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~")
16313 + #if($result == '')
16314 + #set($result = $defaultValue)
16315 + #end
16316 + #set ($propertyValue = $NULL)
16317 + #setVariable (~"$propertyValue~" $result)
16318 +#end
16319 +
16320 +#**
16321 + * If an error occurs when executing an action, set a specific response status and display an error message.
16322 + *
16323 + * @param status The response status.
16324 + * @param text The user readable error to be displayed. Can be a translation key.
16325 + * @param parameters The parameters to use when decoding the translation key.
16326 + *###
16327 +#macro(blog__actionResponseError $status $text $parameters)
16328 + $response.setStatus($status)
16329 + #if($request.ajax)
16330 + $services.localization.render($text, $!parameters)
16331 + #else
16332 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}}
16333 + #end
16334 +#end
16335 +##
16336 +##
16337 +##
16338 +#**
16339 + * Check if a blog is the Default blog (The one in the 'Blog' space).
16340 + *
16341 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
16342 + * @param isDefault The resulting boolean.
16343 + *###
16344 +#macro(isDefaultBlog $blogDoc $isDefault)
16345 + #set ($result = false)
16346 + #if ($blogDoc.space == 'Blog')
16347 + #set ($result = true)
16348 + #end
16349 + #setVariable(~"$isDefault~" $result)
16350 +#end
16351 +##
16352 +##
16353 +##
16354 +#**
16355 + * Retrieve the blog posts location (space).
16356 + *
16357 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
16358 + * @param postsLocation The resulting location.
16359 + *###
16360 +#macro(getBlogPostsLocation $blogSpace $postsLocation)
16361 + #getBlogDocument($blogSpace $blogDoc)
16362 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
16363 + #set ($postsLocation = $NULL)
16364 + #setVariable (~"$postsLocation~" $result)
16365 +#end
16366 +##
16367 +##
16368 +##
16369 +#**
16370 + * Retrieve the blog categories location (space).
16371 + *
16372 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
16373 + * @param categoriesLocation The resulting location.
16374 + *###
16375 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
16376 + #getBlogDocument($blogSpace $blogDoc)
16377 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
16378 + #set ($postsLocation = $NULL)
16379 + #setVariable (~"$categoriesLocation~" $result)
16380 +#end
16381 +###**
16382 + * Return the Query for selecting the blog posts based on the context where the posts are displayed.
16383 + * for example there is 4 different panel contexts:
16384 + * aBlog.aPost or aBlog.WebHome
16385 + * aCategorySpace.aCategory
16386 + * aCategorySpace.WebHome
16387 + * Blog.aPost or Blog.WebHome
16388 + *
16389 + * @param query The query for selecting blog entries.
16390 + * @param queryParams The parameters to bind with the generated query.
16391 + * @param targetDoc The document in which the articles will be displayed.
16392 + *###
16393 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
16394 + #set ($query = $NULL)
16395 + #set ($queryParams = $NULL)
16396 + #getCategoryAllBlogPostsQuery($resultQuery)
16397 + #set ($resultQueryParams = \{})
16398 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
16399 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
16400 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
16401 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
16402 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
16403 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~")
16404 + #elseif($targetDoc.getObject($blogCategoryClassname))
16405 + ## Get all posts that are in a category aCategorySpace.aCategory
16406 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
16407 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~")
16408 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
16409 + ## Get all posts that are in a category aCategorySpace.%
16410 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
16411 + ## Exclude incategorized posts
16412 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~")
16413 + #if ($targetDoc.space == $defaultBlogSpace)
16414 + #set ($excludedCategory = ~"Blog.Categories.WebHome~")
16415 + #end
16416 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
16417 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~")
16418 + #else
16419 + ## Get all posts in blog space aBlog
16420 + #getAllBlogPostsQuery($resultQuery)
16421 + #getBlogPostsLocation($targetDoc.space $postsLocation)
16422 + #set ($discard = $resultQueryParams.put('space', $postsLocation))
16423 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~")
16424 + #end
16425 + #setVariable(~"$query~" $resultQuery)
16426 + #setVariable(~"$queryParams~" $resultQueryParams)
16427 +#end
16428 +##
16429 +##
16430 +##
16431 +###**
16432 + * Display blog posts based on the context where the posts are displayed.
16433 + * for example there is 4 different panel contexts:
16434 + * aBlog.aPost or aBlog.WebHome
16435 + * aCategorySpace.aCategory
16436 + * aCategorySpace.WebHome
16437 + * Blog.aPost or Blog.WebHome
16438 + *
16439 + * @param targetDoc The document in which the articles will be displayed.
16440 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
16441 + * @param layout Layout of the the posts to display
16442 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
16443 + * @param limit the number of posts to display
16444 + *###
16445 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
16446 + #if ($postLayout == 'full')
16447 + #set ($macro.paginated = 'yes')
16448 + #end
16449 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
16450 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
16451 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout)
16452 + #if (~"$!layout~" == '')
16453 + #set ($layout = $postsLayout)
16454 + #end
16455 + #if ($postsVisiblity == 'recent')
16456 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
16457 + #elseif($postsVisiblity == 'unpublished')
16458 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
16459 + #end
16460 + #elseif($targetDoc.getObject($blogCategoryClassname))
16461 + ## Display all posts that are in a category aCategorySpace.aCategory
16462 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
16463 + #getBlogPostsLayout($blogDoc $postsLayout)
16464 + #if (~"$!layout~" == '')
16465 + #set ($layout = $postsLayout)
16466 + #end
16467 + #if ($postsVisiblity == 'recent')
16468 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
16469 + #elseif($postsVisiblity == 'unpublished')
16470 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
16471 + #end
16472 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
16473 + ## Display all posts that are in a category aCategorySpace.%
16474 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
16475 + #getBlogPostsLayout($blogDoc $postsLayout)
16476 + #if (~"$!layout~" == '')
16477 + #set ($layout = $postsLayout)
16478 + #end
16479 + #if ($postsVisiblity == 'recent')
16480 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
16481 + #elseif($postsVisiblity == 'unpublished')
16482 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
16483 + #end
16484 + #else
16485 + ## Display all posts in blog space aBlog
16486 + #getBlogDocument($targetDoc.space $blogDoc)
16487 + #getBlogPostsLayout($blogDoc $postsLayout)
16488 + #if (~"$!layout~" == '')
16489 + #set ($layout = $postsLayout)
16490 + #end
16491 + #if ($postsVisiblity == 'recent')
16492 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}}
16493 + #elseif($postsVisiblity == 'unpublished')
16494 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}}
16495 + #end
16496 + #end
16497 +#end
16498 +##
16499 +##
16500 +##
16501 +#**
16502 + * Bind parameters to a query object.
16503 + *
16504 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
16505 + * @param queryParams the query parameters.
16506 + *###
16507 +#macro(bindQueryParameters $queryObj $queryParams)
16508 + #set ($output = $queryObj)
16509 + #foreach( $key in $queryParams.keySet() )
16510 + #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
16511 + #end
16512 + #setVariable(~"$queryObj~" $output)
16513 +#end
16514 +##
16515 +##
16516 +##
16517 +#**
16518 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
16519 + *
16520 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
16521 + * property set.
16522 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
16523 + *###
16524 +#macro(getBlogPostsLayout $blogDoc $postsLayout)
16525 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
16526 + #set ($postsLayout = $NULL)
16527 + #setVariable (~"$postsLayout~" $res)
16528 +#end
16529 +##
16530 +##
16531 +##
16532 +#**
16533 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
16534 + *
16535 + * @param categoriesSpace A <tt>String</tt>, the name of the space.
16536 + * @param blogDoc The resulting XDocument.
16537 + *###
16538 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
16539 + #set($macro.blogDocs = $services.query.hql(~", BaseObject obj, StringProperty as categoriesLocationProp where obj.name = doc.fullName and obj.className = '$blogClassname' and obj.id=categoriesLocationProp.id.id and categoriesLocationProp.id.name='categoriesLocation' and categoriesLocationProp.value=:categoriesLocation order by doc.creationDate~").setLimit(1).setOffset(0).bindValue('categoriesLocation', $categoriesSpace).execute())
16540 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
16541 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
16542 + #else
16543 + ## Fallback to Blog.WebHome, the default blog
16544 + #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
16545 + #end
16546 + #set ($blogDoc = $NULL)
16547 + #setVariable (~"$blogDoc~" $macro.result)
16548 +#end" %)
16549 +(((
16550 +(% class="macro-placeholder hidden" %)
16551 +(((
16552 +macro:velocity
16553 +)))
16554 +)))
16555 +)))
16556 +
16557 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %)
16558 +(((
16559 +(% class="macro-placeholder hidden" %)
16560 +(((
16561 +macro:include
16562 +)))
16563 +
16564 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#**
16565 + * Extract the layout parameters from a string.
16566 + *
16567 + * @param layoutParamsString The string representation of the layout parameters.
16568 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~"
16569 + * @param layoutsParameters The resulting layout parameters Map.
16570 + *###
16571 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters)
16572 + #set ($layoutsParameters = $NULL)
16573 + #set ($macro.layoutParams = \{})
16574 + #if (~"$!layoutParamsString~" != '')
16575 + #set ($macro.paramsArr = $layoutParamsString.split('\\|'))
16576 + #foreach ($item in $macro.paramsArr)
16577 + #set ($itemSplit = $item.split('='))
16578 + #if ($itemSplit.size() == 2)
16579 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim()))
16580 + #end
16581 + #end
16582 + #end
16583 + #setVariable(~"$layoutsParameters~" $macro.layoutParams)
16584 +#end" %)
16585 +(((
16586 +(% class="macro-placeholder hidden" %)
16587 +(((
16588 +macro:velocity
16589 +)))
16590 +)))
16591 +)))
16592 +
16593 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj)
16594 + #initLayoutVars($pDoc $pObj)
16595 + <div class=~"col-xs-12 col-sm-6 next_blog~">
16596 + <a href=~"$pDoc.uRL~" class=~"thumbnail~">
16597 + <div class=~"row~">
16598 + <div class=~"col-xs-4~">
16599 + #if ($imageAtt)
16600 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
16601 + #end
16602 + </div>
16603 + <div class=~"col-xs-8 art_det~">
16604 + <p class=~"text-left~">
16605 + #if($displayTitle)$!postTitle #end
16606 + <br/><span class=~"date_info~"> $!dateStr </span>
16607 + </p>
16608 + #displayPostDetails($pDoc)
16609 + </div>
16610 + </div>
16611 + </a>
16612 + </div>
16613 + #end
16614 + ##
16615 + ##
16616 + ##
16617 + #macro(displayPinnedPost $pDoc $pObj)
16618 + #initLayoutVars($pDoc $pObj)
16619 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~">
16620 + <a href=~"$pDoc.uRL~" class=~"all-post-link~">
16621 + <div class=~"thumbnail~">
16622 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts)
16623 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
16624 + #end
16625 + #if ($imageAtt)
16626 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" />
16627 + #end
16628 + <div class=~"caption~">
16629 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts)
16630 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5>
16631 + #end
16632 + #if ($displaySummaryOnPinnedPosts)
16633 + <div class=~"text-left post-summary~">
16634 + #set ($postContent = $pObj.getProperty('extract').value)
16635 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString())
16636 + </div>
16637 + #end
16638 + #displayPostDetails($pDoc)
16639 + </div>
16640 + </div>
16641 + </a>
16642 + </div>
16643 + #end
16644 + ##
16645 + ##
16646 + ##
16647 + #macro(formatPostDate $pDoc $pObj)
16648 + #set ($formattedDate = $NULL)
16649 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale))
16650 + #if (~"$!dateStr~" != '')
16651 + #set ($dateArr = $dateStr.split(' '))
16652 + #if ($dateArr.size() > 3)
16653 + #set ($dateStr = ~"~")
16654 + #foreach($s in $dateArr.subList(0, 3))
16655 + #set ($dateStr = ~"$\{dateStr}$\{s} ~")
16656 + #end
16657 + #end
16658 + #end
16659 + #setVariable(~"$formattedDate~" $dateStr)
16660 + #end
16661 + ##
16662 + ##
16663 + ##
16664 + #macro(displayPostDetails $pDoc)
16665 + <div class=~"row post-details~">
16666 + <div class=~"col-xs-8 detail~">
16667 + #if ($services.like.displayButton($pDoc.documentReference))
16668 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference))
16669 + ## Retrieve the likes number in XWiki 12.9+
16670 + #set ($likeNumber = $optLikeRecord.get())
16671 + #if (!$stringtool.isNumeric($likeNumber.toString()))
16672 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9.
16673 + #set ($likeNumber = $optLikeRecord.get().likeNumber)
16674 + #end
16675 + #if ($stringtool.isNumeric($likeNumber.toString()))
16676 + <div class=~"post-likes btn btn-default disabled badge~"
16677 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~">
16678 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span>
16679 + </div>
16680 + #end
16681 + #elseif ($services.ratings)
16682 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference))
16683 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1)
16684 + <ul class=~"pull-left note list-inline~">
16685 + #foreach ($x in [1..5])
16686 + #set ($cls = ~"~")
16687 + #if ($x > $averageVote)
16688 + #set ($cls = ~"-o~")
16689 + #end
16690 + <li><span class=~"fa fa-star$\{cls}~"></span></li>
16691 + #end
16692 + </ul>
16693 + #end
16694 + #end
16695 + </div>
16696 + #if ($showPostComments)
16697 + <div class=~"col-xs-4 com_det~">
16698 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p>
16699 + </div>
16700 + #end
16701 + </div>
16702 + #end
16703 + ##
16704 + ##
16705 + ##
16706 + #macro(initLayoutVars $pDoc $pObj)
16707 + #set ($postTitle = $pDoc.display('title', 'view', $pObj))
16708 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image')))
16709 + #isPublished($pObj $isPublished)
16710 + #isHidden($pObj $isHidden)
16711 + #getEntryDate($pDoc $pObj $postDate)
16712 + #formatPostDate($postDate $dateStr)
16713 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote()))
16714 + #set ($nbComments = $pDoc.getComments().size())
16715 + #set ($showPostComments = true)
16716 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0')
16717 + #set ($showPostComments = false)
16718 + #end
16719 + #end
16720 + ##
16721 + ##
16722 + ##
16723 + #macro(displayEditPinnedPostsButton)
16724 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName))
16725 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet'))
16726 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet'))
16727 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet'))
16728 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~"))
16729 + <div class=~"edit-pinned-posts-container~">
16730 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~">
16731 + <a href=~"javascript:;~" class=~"editPinnedPosts~">
16732 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit')
16733 + </a>
16734 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/>
16735 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/>
16736 + </div>
16737 + </div>
16738 + #if (~"$!pinnedPostsObj~" == '')
16739 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/>
16740 + #end
16741 + #end
16742 + #end" %)
16743 +(((
16744 +(% class="macro-placeholder hidden" %)
16745 +(((
16746 +macro:velocity
16747 +)))
16748 +)))
16749 +
16750 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference))
16751 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference))
16752 + #getEntryObject($postDoc $postObj)
16753 + #if (~"$!postObj~" != '')
16754 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams)
16755 + ##
16756 + #set ($displayTitle = true)
16757 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false')
16758 + #set ($displayTitle = false)
16759 + #end
16760 + ##
16761 + #set ($displayTitleFirstOnPinnedPosts = false)
16762 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true')
16763 + #set ($displayTitleFirstOnPinnedPosts = true)
16764 + #end
16765 + ##
16766 + #set ($displaySummaryOnPinnedPosts = true)
16767 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false')
16768 + #set ($displaySummaryOnPinnedPosts = false)
16769 + #end
16770 + ##
16771 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue())
16772 + #if ($postIndex == 0)
16773 + #set ($stopBlogPostsDisplay = false)
16774 + #end
16775 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue())
16776 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards'))
16777 + #set($scaleWidth = 600)
16778 + #set($imgQs=~"width=$scaleWidth~")
16779 + ## Display pinned posts
16780 + ## Get the list of pinned posts
16781 + #set ($pinnedPosts = [])
16782 + #set ($pinnedPostsSourceDoc = $NULL)
16783 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '')
16784 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog')))
16785 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro
16786 + #end
16787 + #if (~"$!pinnedPostsSourceDoc~" != '')
16788 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass'))
16789 + #if (~"$!pinnedPostsObj~" != '')
16790 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value)
16791 + #if (~"$!orderedPinnedPostsJSON~" != '')
16792 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON))
16793 + #else
16794 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value)
16795 + #end
16796 + #end
16797 + #if ($postIndex == 0 && $pinnedPosts.size() > 0)
16798 + \{\{html clean=~"false~"}}
16799 + #set ($x = 0)
16800 + #set ($showPinnedPostsButton = true)
16801 + #foreach ($pinnedPost in $pinnedPosts)
16802 + #if ($x == 0)
16803 + <div class=~"row flex-container~">
16804 + #if ($showPinnedPostsButton)
16805 + #displayEditPinnedPostsButton()
16806 + #set($showPinnedPostsButton = false)
16807 + #end
16808 + #end
16809 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost))
16810 + #getEntryObject($pinnedPostDoc $pinnedPostObj)
16811 + #if (~"$!pinnedPostObj~" != '')
16812 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj)
16813 + #end
16814 + #set ($x = $mathtool.add($x, 1))
16815 + #if ($x == 3)
16816 + #set ($x = 0)
16817 + </div>
16818 + #end
16819 + #end
16820 + #if ($mathtool.mod($x, 3) != 0)
16821 + </div>
16822 + #end
16823 + \{\{/html}}
16824 +
16825 + ## If the first post is a pinned post : this means that all the posts are pinned
16826 + ## In this case, avoid displaying the posts again after the pinned posts section.
16827 + #if ($pinnedPosts.contains($xcontext.macro.params.reference))
16828 + #set ($stopBlogPostsDisplay = true)
16829 + #end
16830 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0)
16831 +
16832 + \{\{html}}
16833 + <div class=~"row no-pinnded-posts~">
16834 + #displayEditPinnedPostsButton()
16835 + </div>
16836 + \{\{/html}}
16837 +
16838 + #end
16839 + #end
16840 + #if (!$stopBlogPostsDisplay)
16841 + \{\{html clean=~"false~"}}
16842 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0)
16843 + #set ($nbDisplayedPosts = 0)
16844 + #end
16845 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0)
16846 + #if ($nbDisplayedPosts != 0)
16847 + </div>
16848 + #set ($lastHtmlTag = 'c')
16849 + #end
16850 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
16851 + <div class=~"row~">
16852 + #set ($lastHtmlTag = 'o')
16853 + #set ($lastRowClass = ~"~")
16854 + #else
16855 + <div class=~"row flex-container~">
16856 + #set ($lastHtmlTag = 'o')
16857 + #set ($lastRowClass = ~"flex~")
16858 + #end
16859 + #end
16860 + #displaySmallPost($postDoc $postObj)
16861 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1))
16862 + </div>
16863 + #set ($lastHtmlTag = 'c')
16864 + #end
16865 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1))
16866 + #if ($postIndex == $mathtool.sub($listResultsCount, 1))
16867 + #if (~"$!lastHtmlTag~" == 'o')
16868 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~")
16869 + <div class=~"col-xs-12 col-sm-6~"></div>
16870 + #end
16871 + </div>
16872 + #end
16873 + #end
16874 + \{\{/html}}
16875 + #end
16876 + #else
16877 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}}
16878 + #end
16879 + #else
16880 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}}
16881 + #end" %)
16882 +(((
16883 +(% class="macro-placeholder hidden" %)
16884 +(((
16885 +macro:velocity
16886 +)))
16887 +
16888 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"col-xs-12 col-sm-6 next_blog~">
16889 +<a href=~"/Nieuws/Aankondiging%20update%20Syntess%206.9.0.0166~" class=~"thumbnail~">
16890 +<div class=~"row~">
16891 +<div class=~"col-xs-4~">
16892 +<img src=~"/download/Nieuws/Aankondiging%20update%20Syntess%206.9.0.0166/giphy9.gif?width=600&rev=1.1~" />
16893 +</div>
16894 +<div class=~"col-xs-8 art_det~">
16895 +<p class=~"text-left~">
16896 +Aankondiging update Syntess 6.9.0.0166 <br/><span class=~"date_info~"> Nov 21, 2023, </span>
16897 +</p>
16898 +<div class=~"row post-details~">
16899 +<div class=~"col-xs-8 detail~">
16900 +<div class=~"post-likes btn btn-default disabled badge~"
16901 +title=~"Number of likes on this page: 0~">
16902 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">0</span>
16903 +</div>
16904 +</div>
16905 +<div class=~"col-xs-4 com_det~">
16906 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p>
16907 +</div>
16908 +</div>
16909 +</div>
16910 +</div>
16911 +</a>
16912 +</div>
16913 +</div>" %)
16914 +(((
16915 +(% class="macro-placeholder hidden" %)
16916 +(((
16917 +macro:html
16918 +)))
16919 +
16920 +(% class="col-xs-12 col-sm-6 next_blog" %)
16921 +(((
16922 +(% class="row" %)
16923 +(((
16924 +(% class="col-xs-4" %)
16925 +(((
16926 +[[~[~[image:/download/Nieuws/Aankondiging%20update%20Syntess%206.9.0.0166/giphy9.gif?width=600&rev=1.1~]~]>>path:/Nieuws/Aankondiging%20update%20Syntess%206.9.0.0166||class="thumbnail"]]
16927 +)))
16928 +
16929 +(% class="col-xs-8 art_det" %)
16930 +(((
16931 +(% class="text-left" %)
16932 +[[Aankondiging update Syntess 6.9.0.0166
16933 +(% class="date_info" %) Nov 21, 2023,>>path:/Nieuws/Aankondiging%20update%20Syntess%206.9.0.0166||class="thumbnail"]]
16934 +
16935 +(% class="row post-details" %)
16936 +(((
16937 +(% class="col-xs-8 detail" %)
16938 +(((
16939 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 0" %)
16940 +(((
16941 +[[(% class="like-number" %)0>>path:/Nieuws/Aankondiging%20update%20Syntess%206.9.0.0166||class="thumbnail"]]
16942 +)))
16943 +)))
16944 +
16945 +(% class="col-xs-4 com_det" %)
16946 +(((
16947 +(% class="text-right" %)
16948 +[[(0)>>path:/Nieuws/Aankondiging%20update%20Syntess%206.9.0.0166||class="thumbnail"]]
16949 +)))
16950 +)))
16951 +)))
16952 +)))
16953 +)))
16954 +)))
16955 +)))
16956 +)))
16957 +)))
16958 +)))
16959 +)))
16960 +)))
16961 +)))
16962 +)))
16963 +)))
16964 +
16965 +(% style="background:url(~"https://kennis.wardenburg.nl/webjars/wiki%3Axwiki/xwiki-platform-ckeditor-webjar/15.8/plugins/widget/images/handle.png~") rgba(220, 220, 220, 0.5); left:0px; top:-15px" %)[[image:data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==||height="15" role="presentation" title="Click and drag to move" width="15"]]
16966 +)))
16967 +
16968 +
16969 +
16970 +)))
16971 +
16972 +(% aria-label="macro:velocity widget" contenteditable="false" role="region" tabindex="-1" %)
16973 +(((
16974 +(% class="macro" data-macro="startmacro:velocity|-||-|#if (!$hasEdit)
49 49   ## Verstop tabs
50 50   #set($displayDocExtra = false)
51 51   ## En de balken onderin
52 52   #set ($displayShortcuts = false)
53 -#end
54 -{{/velocity}}
16979 +#end" data-widget="xwiki-macro" data-xwiki-dom-updated="true" %)
16980 +(((
16981 +(% class="macro-placeholder" %)
16982 +(((
16983 +macro:velocity
16984 +)))
16985 +)))
16986 +
16987 +(% style="background-color:rgba(220,220,220,0.5)" %)[[image:data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==||height="15" role="presentation" title="Click and drag to move" width="15"]]
16988 +)))
Preloader_oranje.gif
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.Jesse
Size
... ... @@ -1,1 +1,0 @@
1 -2.0 MB
Content