Wijzigen voor document Home
Laatst gewijzigd door Jesse Veentjer op 13-11-2025 04:39
Van versie 10.12
gewijzigd door Jesse Veentjer
op 15-2-2024 05:47
op 15-2-2024 05:47
Opmerking bij wijziging:
Er is geen opmerking bij deze versie
Naar versie 11.1
gewijzigd door Jesse Veentjer
op 15-2-2024 05:53
op 15-2-2024 05:53
Opmerking bij wijziging:
Er is geen opmerking bij deze versie
Samenvatting
-
Paginaeigenschappen (1 gewijzigd, 0 toegevoegd, 0 verwijderd)
Details
- Paginaeigenschappen
-
- Inhoud
-
... ... @@ -1,24 +1,148 @@ 1 +(% class="floatinginfobox wbrechts" %) 2 +((( 3 +(% class="wbrb" %) 4 +(% aria-label="aanhetwerk.gif afbeelding widget" contenteditable="false" data-xwiki-image-style-alignment="center" role="region" tabindex="-1" data-widget="image" %)[[image:aanhetwerk.gif||data-xwiki-image-style-alignment="center"]](% title="Klik en sleep om te herschalen" %)(% aria-label="aanhetwerk.gif afbeelding 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="Klik en sleep om te verplaatsen" 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 +* [[Nieuws>>doc:null||anchor="HNieuws"]] 21 +))) 22 + 23 +(% style="background-color:rgba(220,220,220,0.5)" %)[[image:data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==||height="15" role="presentation" title="Klik en sleep om te verplaatsen" width="15"]] 24 +))) 25 +))) 26 +))) 27 + 1 1 (% class="wblinks" %) 2 2 ((( 3 -{{velocity}} 30 +(% aria-label="macro:velocity widget" contenteditable="false" role="region" tabindex="-1" %) 31 +((( 32 +(% class="macro" data-macro="startmacro:velocity|-||-|Welkom op de Kennisbank! 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 33 + 34 +\{\{showhide showmessage=~"We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:~" hidemessage=~"Verstop voorbeelden~" effectduration=~"1~"}} 35 +✅ Toegang tot informatie , verbreed je kennis naar nieuwe onderwerpen. 36 +* Gedeelde kennis is makkelijk doorzoekbaar, je kan naar specifieke delen van pagina’s linken met een weblink! 37 +* 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. 38 +* //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/]] 39 + 40 +✅ Dankzij de nieuwssectie kunnen ook de laatste ontwikkelingen per 'nieuwsonderwerp' op de kennisbank geplaatst worden. 41 + 42 +✅ Deel je kennis door het vast te leggen in de kennisbank 43 + 44 +* 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. 45 + 46 +✅ Zorgt voor transparantie en duidelijkheid op kennisgebied 47 + 48 +* Uitleg en handleidingen van installaties maar ook onze werkprocessen kunnen vastgelegd en gedeeld worden met de kennisbank. 49 +* Ervaringen en discussies kunnen per onderwerp geplaatst en besproken worden. 50 +\{\{/showhide}} 51 +-\-\-\- 52 +* [[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. // 53 +* [[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~"]]. 54 + 55 + 56 + 4 4 #if($isGuest) 5 5 #set($loginscherm = 'https://kennis.wardenburg.nl/login/XWiki/XWikiLogin') 6 -{{html}} 7 -<a href=$loginscherm> 8 -<button class="login-btn" onclick="this.classList.add('clicked')"><span>Login</span></button> 9 -</a> 10 -{{/html}} 11 -Door in te loggen krijg je meer functies op de kennisbank, log in met je voornaam.achternaam (het wachtwoord is dezelfde als bij je e-mail). 59 +\{\{html}} 60 +<button class=~"login-btn~" onclick=~"this.classList.add('clicked')~"><span>Login</span></button> 61 +\{\{/html}} 62 +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). 12 12 #else 64 += Nieuws = 65 +\{\{blogpostlist blog=~"Nieuws.WebHome~" limit=~"6~" layout=~"cards~" layoutParams=~"displayTitle=true|useSummary=true~"/}} 66 +#end" data-widget="xwiki-macro" data-xwiki-dom-updated="true" %) 67 +((( 68 +(% class="macro-placeholder hidden" %) 69 +((( 70 +macro:velocity 71 +))) 13 13 14 - #end73 +Welkom op de Kennisbank! 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 15 15 16 -=Welkom op onze Kennisbank= 75 +(% 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. 76 +* Gedeelde kennis is makkelijk doorzoekbaar, je kan naar specifieke delen van pagina’s linken met een weblink! 77 +* 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. 78 +* //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/]] 17 17 18 - Toegang tot (kwalitatief)goedeinformatieis eenuitdagingwaar iedereen mee worstelt, methet lancerenvan dit digitalearchief waarinwekennis,de laatste ontwikkelingen(nieuws),bestanden enideeën kunnen plaatsenendelen gaanwehet vinden van informatieeenvoudigermaken. Inde kernmaakt kennisbankhet mogelijk om informatietegenererenorganiseren endelen80 +✅ Dankzij de nieuwssectie kunnen ook de laatste ontwikkelingen per 'nieuwsonderwerp' op de kennisbank geplaatst worden. 19 19 20 -{{showhide showmessage="We kunnen dit op vele manieren gebruiken, klik hier om enkele voorbeelden te zien:" hidemessage="Verstop voorbeelden" effectduration="1"}} 82 +✅ Deel je kennis door het vast te leggen in de kennisbank 83 + 84 +* 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. 85 + 86 +✅ Zorgt voor transparantie en duidelijkheid op kennisgebied 87 + 88 +* Uitleg en handleidingen van installaties maar ook onze werkprocessen kunnen vastgelegd en gedeeld worden met de kennisbank. 89 +* Ervaringen en discussies kunnen per onderwerp geplaatst en besproken worden." %) 90 +((( 91 +(% class="macro-placeholder hidden" %) 92 +((( 93 +macro:showhide 94 +))) 95 + 96 +(% class="macro" data-macro="startmacro:velocity|-||-|#set($discard = $xwiki.jsx.use(~"Macros.ShowHideMacro~")) 97 +#set($mparams = $wikimacro.parameters) 98 +#if(!$mparams) 99 + #set($mparams = $xcontext.macro.params) 100 +#end 101 +#if($mparams.id) 102 + #set($id = $util.convertToAlphaNumeric($mparams.id)) 103 +#end 104 +#set($showmessage = $escapetool.xml($mparams.showmessage)) 105 +#set($hidemessage = $escapetool.xml($mparams.hidemessage)) 106 +#set($divstyle = $escapetool.xml($mparams.style)) 107 +#set($effect = $escapetool.xml($mparams.effect)) 108 +#if($effect == ~"appear~" || $effect == ~"fade~") 109 + #set($effect = ~"fadeToggle~") 110 +#elseif ($effect == ~"blind~" || $effect == ~"slide~") 111 + #set($effect = ~"slideToggle~") 112 +#end 113 +#set($effectduration = $mathtool.mul(1000,$mparams.effectduration)) 114 +(% #if($divstyle && $divstyle!=~"~") style=~"$\{divstyle}~" #end ~%) 115 +((( 116 +(% class=~"showhidebutton~" ~%) 117 +((( 118 +\{\{html clean=false}} 119 +<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> 120 +\{\{/html}} 121 +))) 122 +(% class=~"showhidecontent~" #if($id && $id!=~"~")id=~"showhidecontent$\{id}~" #end style=~"display: none;~" ~%) 123 +((( 124 +((( 125 +$xcontext.macro.content 126 +))) 127 +))) 128 +)))" %) 129 +((( 130 +(% class="macro-placeholder hidden" %) 131 +((( 132 +macro:velocity 133 +))) 134 + 135 +((( 136 +(% class="showhidebutton" %) 137 +((( 138 +(% 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:"]] 139 +))) 140 + 141 +(% class="showhidecontent" style="display: none;" %) 142 +((( 143 +((( 21 21 ✅ Toegang tot informatie , verbreed je kennis naar nieuwe onderwerpen. 145 + 22 22 * Gedeelde kennis is makkelijk doorzoekbaar, je kan naar specifieke delen van pagina’s linken met een weblink! 23 23 * 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. 24 24 * //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/]] ... ... @@ -33,28 +33,10117 @@ 33 33 34 34 * Uitleg en handleidingen van installaties maar ook onze werkprocessen kunnen vastgelegd en gedeeld worden met de kennisbank. 35 35 * Ervaringen en discussies kunnen per onderwerp geplaatst en besproken worden. 36 -{{/showhide}} 160 +))) 161 +))) 162 +))) 163 +))) 164 +))) 165 + 37 37 ---- 38 -* [[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. // 167 + 168 +* [[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. // 39 39 * [[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"]]. 40 40 41 41 42 - 43 -#if(!$isGuest) 44 -(% style="clear:right" %) 45 45 = Nieuws = 46 -{{blogpostlist blog="Nieuws.WebHome" limit="6" layout="cards" layoutParams="displayTitle=true|useSummary=true"/}} 47 47 174 +(% class="macro" data-macro="startmacro:blogpostlist|-|blog=~"Nieuws.WebHome~" limit=~"6~" layout=~"cards~" layoutParams=~"displayTitle=true|useSummary=true~"" %) 175 +((( 176 +(% class="macro-placeholder hidden" %) 177 +((( 178 +macro:blogpostlist 179 +))) 180 + 181 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Nieuwsbrief januari 2024~" params=~"displayTitle=true|useSummary=true|list-limit=6|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=6|postIndex=0|previousPostReference=~"" %) 182 +((( 183 +(% class="macro-placeholder hidden" %) 184 +((( 185 +macro:blogPostLayoutCards 186 +))) 187 + 188 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %) 189 +((( 190 +(% class="macro-placeholder hidden" %) 191 +((( 192 +macro:include 193 +))) 194 + 195 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %) 196 +((( 197 +(% class="macro-placeholder hidden" %) 198 +((( 199 +macro:include 200 +))) 201 + 202 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog 203 +#set($blogClassname = 'Blog.BlogClass') 204 +#set($blogTemplate = 'Blog.BlogTemplate') 205 +#set($blogSheet = 'Blog.BlogSheet') 206 +## Blog entries 207 +#set($blogPostClassname = 'Blog.BlogPostClass') 208 +#set($blogPostTemplate = 'Blog.BlogPostTemplate') 209 +#set($blogPostSheet = 'Blog.BlogPostSheet') 210 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number) 211 +#set($oldArticleClassname = 'XWiki.ArticleClass') 212 +## Categories 213 +#set($blogCategoryClassname = 'Blog.CategoryClass') 214 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate') 215 +#set($blogCategorySheet = 'Blog.CategorySheet') 216 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet') 217 +#set($oldBlogCategoryClassname = 'Blog.Categories') 218 +#set($defaultCategoryParent = 'Blog.Categories') 219 +## Style 220 +#set($blogStyleDocumentName = 'Blog.BlogStyle') 221 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName)) 222 +## Clientside scripts 223 +#set($blogScriptsDocumentName = 'Blog.BlogScripts') 224 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher')) 225 +## Misc 226 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString)) 227 +#set($isBlogPost = $doc.getObject($blogPostClassname)) 228 +#set($defaultBlogSpace = 'Blog') 229 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname)) 230 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 231 +## 232 +## 233 +## 234 +#** 235 + * Displays an image, taken from the blog style document. 236 + * 237 + * @param $imgName The name of the icon from icons set to use. 238 + *# 239 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %) 240 +((( 241 +(% class="macro-placeholder hidden" %) 242 +((( 243 +macro:velocity 244 +))) 245 +))) 246 +))) 247 + 248 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## 249 +## 250 +## 251 +## Import the blog skin and javascripts. 252 +$!xwiki.ssx.use($blogStyleDocumentName)## 253 +$!xwiki.jsx.use($blogScriptsDocumentName)## 254 +## 255 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation) 256 +#template('hierarchy_macros.vm')## 257 +## 258 +## 259 +#** 260 + * Prints a blog. This is the main macro used in the BlogSheet. 261 + * 262 + * @param blogDoc the XDocument holding the blog definition object. 263 + *### 264 +#macro(printBlog $blogDoc) 265 + \{\{include reference='Blog.CreatePost'/}} 266 + 267 + ## Use the blogPostList macro to display the blogposts 268 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro 269 + ## do not support FTM the monthly and weekly blog display types 270 + #getBlogDisplayType($blogDoc $displayType) 271 + #if ($displayType == 'weekly' || $displayType == 'monthly') 272 + #getBlogEntries($blogDoc $entries) 273 + #displayBlog($entries 'index' true true) 274 + #displayNavigationLinks($blogDoc) 275 + #else 276 + #getBlogDisplayType($blogDoc $displayType) 277 + #set ($paginated = 'no') 278 + #if ($displayType == 'paginated') 279 + #set ($paginated = 'yes') 280 + #end 281 + #getBlogPostsLayout($blogDoc $postsLayout) 282 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}}))) 283 + #end 48 48 #end 285 +## 286 +## 287 +## 288 +#** 289 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title, 290 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index, 291 + * all entries). 292 + * 293 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 294 + *### 295 +#macro(showBlogInfo $blogDoc) 296 + #if($blogDoc.getObject($blogClassname)) 297 + ## Keep testing for inline action for backward compatibility with older blogs. 298 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline') 299 + #macro(displayProperty $blogDoc $propname) 300 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)): 301 + : $blogDoc.display($propname) 302 + #end 303 + #displayProperty($blogDoc 'title') 304 + #displayProperty($blogDoc 'description') 305 + #displayProperty($blogDoc 'displayType') 306 + #displayProperty($blogDoc 'itemsPerPage') 307 + #displayProperty($blogDoc 'postsLayout') 308 + #displayProperty($blogDoc 'postsLayoutParameters') 309 + #else 310 + $blogDoc.display('description') 311 + #end 312 + #elseif($doc.fullName == $blogSheet) 313 += $services.localization.render('blog.code.blogsheet') = 314 + \{\{translation key='blog.code.sheetexplanation'/}} 315 + #else 316 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}} 317 + #end 318 +#end 319 +## 320 +## 321 +## 322 +#** 323 + * Retrieve the blog document, which usually is either <tt><Space>.WebHome</tt> for whole-spaces blogs, or 324 + * <tt><Space>.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first 325 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current 326 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog. 327 + * 328 + * @param space A <tt>String</tt>, the name of the space where to search. 329 + * @param blogDoc The resulting XDocument. 330 + *### 331 +#macro(getBlogDocument $space $blogDoc) 332 + #set ($result = $NULL) 333 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object. 334 + ## 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 335 + ## identify the right blog based on a configuration object in a WebPreferences page. 336 + #set ($spaceReference = $services.model.resolveSpace($space)) 337 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference)) 338 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef)) 339 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass')) 340 + #if ($preferencesObj) 341 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog'))) 342 + #end 343 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy. 344 + #if (~"$!result~" == '') 345 + ## First, try the Space.WebHome, for a whole-space blog 346 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~")) 347 + #if(!$result.getObject($blogClassname)) 348 + ## Second, try the Space.Blog document 349 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~")) 350 + #if(!$result.getObject($blogClassname)) 351 + ## Third, try searching for a blog document in the current space 352 + ## Prevent the query fail when the space contains dots '.' 353 + #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()) 354 + #if($blogDocs.size() > 0) 355 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 356 + #else 357 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space 358 + #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()) 359 + #if($blogDocs.size() > 0) 360 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 361 + #else 362 + ## Last, fallback to Blog.WebHome, the default blog 363 + #set($result = $xwiki.getDocument('Blog.WebHome')) 364 + #end 365 + #end 366 + #end 367 + #end 368 + #end 369 + #set ($blogDoc = $NULL) 370 + #setVariable (~"$blogDoc~" $result) 371 +#end 372 +## 373 +## 374 +## 375 +#** 376 + * Retrieve the blog title. 377 + * 378 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set. 379 + * @param title The resulting title. 380 + *### 381 +#macro(getBlogTitle $blogDoc $title) 382 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them. 383 + #set ($title = $NULL) 384 + #setVariable (~"$title~" $!blogDoc.displayTitle) 385 +#end 386 +## 387 +## 388 +## 389 +#** 390 + * Retrieve the blog description. 391 + * 392 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt> 393 + * property set. 394 + * @param description The resulting description. 395 + *### 396 +#macro(getBlogDescription $blogDoc $description) 397 + #getBlogProperty($blogDoc 'description' '' $result) 398 + #set ($description = $NULL) 399 + #setVariable (~"$description~" $result) 400 +#end 401 +## 402 +## 403 +## 404 +#** 405 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog 406 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on 407 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a 408 + * month), or all. 409 + * 410 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 411 + * @param entries The resulting list of entries to display, a list of XDocument names. 412 + *### 413 +#macro(getBlogEntries $blogDoc $entries) 414 + #if (!$entries) 415 + #setVariable (~"$entries~" []) 416 + #end 417 + #getAllBlogPostsQuery($query) 418 + #isDefaultBlog($blogDoc $isDefault) 419 + #set($queryParams = \{}) 420 + #if ($isDefault) 421 + #getCategoryAllBlogPostsQuery($query) 422 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~") 423 + #set($discard = $queryParams.put('creator', $xcontext.user)) 424 + #set($discard = $queryParams.put('space', $blogDoc.space)) 425 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 426 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace)) 427 + #else 428 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~") 429 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation) 430 + #set($discard = $queryParams.put('space', $blogPostsLocation)) 431 + #set($discard = $queryParams.put('parent', $blogDoc.space)) 432 + #end 433 + #getBlogDisplayType($blogDoc $displayType) 434 + #if($displayType == 'weekly') 435 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams) 436 + #elseif($displayType == 'monthly') 437 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams) 438 + #elseif($displayType == 'all') 439 + #getAllBlogEntries($blogDoc $query $entries $queryParams) 440 + #else 441 + #getPagedBlogEntries($blogDoc $query $entries $queryParams) 442 + #end 443 +#end 444 +## 445 +## 446 +## 447 +#** 448 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents 449 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the 450 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property 451 + * (10 if not defined). 452 + * 453 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 454 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 455 + * refined to restrict to a given space, or to a given search criteria, etc. 456 + * @param entries The resulting list of entries to display, a list of XDocument names. 457 + * @param queryParams The parameters to bind with the query. 458 + *### 459 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams) 460 + #if (!$entries) 461 + #setVariable (~"$entries~" []) 462 + #end 463 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 464 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~")) 465 + #bindQueryParameters($countQueryObj $queryParams) 466 + #bindQueryParameters($queryObj $queryParams) 467 + #set($totalEntries = $countQueryObj.count()) 468 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage) 469 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue()) 470 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 471 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 472 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute())) 473 +#end 474 +## 475 +## 476 +## 477 +#** 478 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is 479 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4 480 + * digit year). Initially the current week is displayed. 481 + * 482 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 483 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 484 + * refined to restrict to a given space, or to a given search criteria, etc. 485 + * @param entries The resulting list of entries to display, a list of XDocument names. 486 + * @param queryParams The parameters to bind with the query. 487 + *### 488 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams) 489 + #if (!$entries) 490 + #setVariable (~"$entries~" []) 491 + #end 492 + #getRequestedWeek($weekDate) 493 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 494 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor())) 495 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling())) 496 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 497 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 498 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 499 + #bindQueryParameters($countQueryObj $queryParams) 500 + #bindQueryParameters($queryObj $queryParams) 501 + #set($totalEntries = $countQueryObj.count()) 502 + #set($discard = $entries.addAll($queryObj.execute())) 503 +#end 504 +## 505 +## 506 +## 507 +#** 508 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is 509 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4 510 + * digit year). Initially the current month is displayed. 511 + * 512 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 513 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 514 + * refined to restrict to a given space, or to a given search criteria, etc. 515 + * @param entries The resulting list of entries to display, a list of XDocument names. 516 + * @param queryParams The parameters to bind with the query. 517 + *### 518 +#macro(getMonthlyBlogEntries $blogDoc $query $entries) 519 + #if (!$entries) 520 + #setVariable (~"$entries~" []) 521 + #end 522 + #getRequestedMonth($monthDate) 523 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 524 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor())) 525 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling())) 526 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 527 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 528 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 529 + #bindQueryParameters($countQueryObj $queryParams) 530 + #bindQueryParameters($queryObj $queryParams) 531 + #set($totalEntries = $countQueryObj.count()) 532 + #set($discard = $entries.addAll($queryObj.execute())) 533 +#end 534 +## 535 +## 536 +## 537 +#** 538 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned. 539 + * 540 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 541 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 542 + * refined to restrict to a given space, or to a given search criteria, etc. 543 + * @param entries The resulting list of entries to display, a list of XDocument names. 544 + * @param queryParams The parameters to bind with the query. 545 + *### 546 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams) 547 + #if (!$entries) 548 + #setVariable (~"$entries~" []) 549 + #end 550 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 551 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 552 + #bindQueryParameters($countQueryObj $queryParams) 553 + #bindQueryParameters($queryObj $queryParams) 554 + #set($totalEntries = $countQueryObj.count()) 555 + #set($discard = $entries.addAll($queryObj.execute())) 556 +#end 557 +## 558 +## 559 +## 560 +#** 561 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned. 562 + * 563 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 564 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 565 + * refined to restrict to a given space, or to a given search criteria, etc. 566 + * @param queryParams The parameters to bind with the query. 567 + * @param entries The resulting list of entries to display, a list of XDocument names. 568 + *### 569 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries) 570 + #if (!$entries) 571 + #setVariable (~"$entries~" []) 572 + #end 573 + #set($query = ~"$\{query} and isPublished.value = 0~") 574 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 575 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 576 + #bindQueryParameters($countQueryObj $queryParams) 577 + #bindQueryParameters($queryObj $queryParams) 578 + #set($totalEntries = $countQueryObj.count()) 579 + #set($discard = $entries.addAll($queryObj.execute())) 580 +#end 581 +## 582 +## 583 +## 584 +#** 585 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog. 586 + * 587 + * @param entries The resulting list of entries to display, a list of XDocument names. 588 + *### 589 +#macro(getGlobalBlogEntries $entries) 590 + #if (!$entries) 591 + #setVariable (~"$entries~" []) 592 + #end 593 + #getAllBlogPostsQuery($query) 594 + #set($totalEntries = $services.query.hql($query).count()) 595 + #set($defaultItemsPerPage = 20) 596 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 597 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 598 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute())) 599 +#end 600 +#** 601 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific 602 + * blog, nor specify a range or an ordering criteria. 603 + * 604 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code. 605 + * 606 + * @param query The basic query for selecting blog entries. 607 + *# 608 +#macro(getBlogEntriesBaseQuery $query) 609 + #getAllBlogPostsQuery($query) 610 +#end 611 +#** 612 + * Return the Query for selecting the all wiki blog posts without filtering 613 + * 614 + * @param query The basic query for selecting blog entries. 615 + *# 616 +#macro(getAllBlogPostsQuery $query) 617 + #set ($query = $NULL) 618 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished, 619 + IntegerProperty hidden, DateProperty publishDate 620 + where doc.fullName <> '$blogPostTemplate' and 621 + obj.name=doc.fullName and obj.className='$blogPostClassname' and 622 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and 623 + hidden.id.id = obj.id and hidden.id.name='hidden' and 624 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and 625 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~") 626 +#end 627 +## 628 +## 629 +## 630 +###** 631 + * Return the Query for selecting the all wiki blog posts with categories filtering 632 + * 633 + * @param query The basic query for selecting blog entries. 634 + *### 635 +#macro(getCategoryAllBlogPostsQuery $query) 636 + #set ($query = $NULL) 637 + #getAllBlogPostsQuery($baseQuery) 638 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList')) 639 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~") 640 +#end 641 +## 642 +## 643 +## 644 +#** 645 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a 646 + * week), monthly (all entries in a month), or all. 647 + * 648 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt> 649 + * property set. 650 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated. 651 + *### 652 +#macro(getBlogDisplayType $blogDoc $displayType) 653 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result) 654 + #set ($displayType = $NULL) 655 + #setVariable (~"$displayType~" $result) 656 +#end 657 +## 658 +## 659 +## 660 +#** 661 + * Displays a list of entries. 662 + * 663 + * @param entries The entries to display, a list of XDocument names. 664 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results, 665 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently 666 + * used values: index, single, category, search, unpublished, hidden. 667 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content. 668 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're 669 + * displayed alone on their page since it's the page title which is used in this case) 670 + *### 671 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles) 672 + #set($blogDay = '') 673 + (% class=~"hfeed $!\{displaying}~" ~%)((( 674 + (% class=~"blogDay~" ~%)((( 675 + #foreach ($entryDoc in $xwiki.wrapDocs($entries)) 676 + #getEntryObject($entryDoc $entryObj) 677 + ## Although all entries should have one of the two objects, better check to be sure. 678 + #if(~"$!\{entryObj}~" != '') 679 + #getEntryDate($entryDoc $entryObj $entryDate) 680 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet. 681 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd')) 682 + #if($blogDay != $entryDateStr) 683 + #if($blogDay != '') 684 + ))) 685 + (% class=~"blogDay~" ~%)((( 686 + #end 687 + #displayBlogDate($entryDate) 688 + #set ($blogDay = $entryDateStr) 689 + #end 690 + ## Finally, display the entry. 691 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true) 692 + #end 693 + #end 694 + )))## blogDay 695 + )))## hfeed 696 +#end 697 +## 698 +## 699 +## 700 +#** 701 + * Get the entry object, either a new BlogPost or an old Article. 702 + * 703 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 704 + * @param entryObj The resulting xobject of the blog post. 705 + *### 706 +#macro(getEntryObject $entryDoc $__entryObj) 707 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~")) 708 + #if(!$result) 709 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~")) 710 + #end 711 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from 712 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be 713 + ## overwritten in this case but it's less likely to have such a variable defined before. 714 + #set ($__entryObj = $NULL) 715 + #setVariable (~"$__entryObj~" $result) 716 +#end 717 +## 718 +## 719 +## 720 +#** 721 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is 722 + * the document creation date, but can be edited by the user. 723 + * 724 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 725 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 726 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>. 727 + *### 728 +#macro(getEntryDate $entryDoc $entryObj $result) 729 + #set ($result = $NULL) 730 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value) 731 +#end 732 +## 733 +## 734 +## 735 +#** 736 + * Displays a date, nicely formatted as a calendar page. 737 + * 738 + * @param date The date to display, an instance of <tt>java.util.Date</tt>. 739 + *### 740 +#macro(displayBlogDate $date) 741 + #set($year = $xwiki.formatDate($date, 'yyyy')) 742 + ## 3 letter month name, like Jan, Dec. 743 + #set($month = $xwiki.formatDate($date, 'MMM')) 744 + ## Uncomment to get a full length month name, like January, December. 745 + ## TODO: this could be defined somewhere in the blog style. 746 + ## #set($month = $xwiki.formatDate($date, 'MMMM')) 747 + #set($day = $xwiki.formatDate($date, 'dd')) 748 + (% class=~"blogdate~" ~%) 749 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) == 750 +#end 751 +## 752 +## 753 +## 754 +#** 755 + * Displays a blog article: management tools, header, content, footer. 756 + * 757 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 758 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 759 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 760 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title 761 + * when they're displayed alone on their page since it's the page title which is used in this case) 762 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons 763 + *### 764 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions) 765 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden 766 + #isPublished($entryObj $isPublished) 767 + #isHidden($entryObj $isHidden) 768 + #if($doc.fullName == $entryDoc.fullName) 769 + (% class=~"hentry single-article~" ~%)((( 770 + #else 771 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)((( 772 + #end 773 + #if ($shouldDisplayActions) 774 + #displayEntryTools($entryDoc $entryObj) 775 + #end 776 + #if($shouldDisplayTitle) 777 + #displayEntryTitle($entryDoc $entryObj) 778 + #end 779 + #if($doc.fullName == $entryDoc.fullName) 780 + #if(!$isPublished) 781 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}} 782 + #elseif($isHidden) 783 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}} 784 + #end 785 + #end 786 + #displayEntryContent($entryDoc $entryObj $onlyExtract) 787 + #displayEntryFooter($entryDoc $entryObj) 788 + )))## hentry 789 +#end 790 +## 791 +## 792 +## 793 +#** 794 + * Checks if the provided blog is published or not. 795 + * 796 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 797 + * @param isPublished The resulting boolean, true if the entry is considered published. 798 + *### 799 +#macro(isPublished $entryObj $isPublished) 800 + #set ($isPublished = $NULL) 801 + ## This should work for both old articles, which don't have the 'published' property at all, and 802 + ## are considered published by default, and new entries, that should have 1 if published. 803 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0') 804 + #setVariable (~"$isPublished~" true) 805 + #else 806 + #setVariable (~"$isPublished~" false) 807 + #end 808 +#end 809 +## 810 +## 811 +## 812 +#** 813 + * Checks if the provided blog is hidden or not. 814 + * 815 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass. 816 + * @param isHiddel The resulting boolean, true if the entry is considered hidden. 817 + *### 818 +#macro(isHidden $entryObj $isHidden) 819 + #set ($isHidden = $NULL) 820 + ## This should work for both old articles, which don't have the 'hidden' property at all, and 821 + ## are considered visible by default, and new entries, that should have 1 if hidden. 822 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1') 823 + #setVariable (~"$isHidden~" true) 824 + #else 825 + #setVariable (~"$isHidden~" false) 826 + #end 827 +#end 828 +## 829 +## 830 +## 831 +#** 832 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit. 833 + * 834 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 835 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 836 + *### 837 +#macro(displayEntryTools $entryDoc $entryObj) 838 + #if($xcontext.action == 'view') 839 + (% class=~"blog-entry-toolbox~" ~%)((( 840 + #displayPublishButton($entryDoc $entryObj) 841 + #displayHideShowButton($entryDoc $entryObj) 842 + #displayEditButton($entryDoc $entryObj) 843 + #displayDeleteButton($entryDoc $entryObj) 844 + ))) 845 + #end 846 +#end 847 +## 848 +## 849 +## 850 +#** 851 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet. 852 + * 853 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 854 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 855 + * @todo AJAX calls. 856 + *### 857 +#macro(displayPublishButton $entryDoc $entryObj) 858 + #isPublished($entryObj $isPublished) 859 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 860 + [[#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')~"]]## 861 + #end 862 +#end 863 +## 864 +## 865 +## 866 +#** 867 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published. 868 + * 869 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 870 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 871 + *### 872 +#macro(displayHideShowButton $entryDoc $entryObj) 873 + #isPublished($entryObj $isPublished) 874 + #isHidden($entryObj $isHidden) 875 + ## Only published articles can be hidden. Unpublished articles are considered already hidden. 876 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 877 + #set ($queryString = \{ 878 + 'xredirect' : $thisURL, 879 + 'form_token' : $services.csrf.getToken() 880 + }) 881 + #if ($isHidden) 882 + #set ($discard = $queryString.putAll(\{ 883 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0, 884 + 'comment' : $services.localization.render('blog.code.madevisible') 885 + })) 886 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 887 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]## 888 + #else 889 + #set ($discard = $queryString.putAll(\{ 890 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1, 891 + 'comment' : $services.localization.render('blog.code.hid') 892 + })) 893 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 894 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]## 895 + #end 896 + #end 897 +#end 898 +## 899 +## 900 +## 901 +#** 902 + * Displays the edit button to those that can edit the article. 903 + * 904 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 905 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 906 + *### 907 +#macro(displayEditButton $entryDoc $entryObj) 908 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 909 + ## Call getDefaultEditMode() for backward compatibility with older blog posts. 910 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]## 911 + #end 912 +#end 913 +## 914 +## 915 +## 916 +#** 917 + * Displays the delete button to those that can edit the article. 918 + * 919 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 920 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 921 + * @todo AJAX calls. 922 + *### 923 +#macro(displayDeleteButton $entryDoc $entryObj) 924 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName)) 925 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]## 926 + #end 927 +#end 928 +## 929 +## 930 +## 931 +#** 932 + * Displays the title of the entry. 933 + * 934 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 935 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 936 + *### 937 +#macro(displayEntryTitle $entryDoc $entryObj) 938 + #if($doc.fullName == $entryDoc.fullName) 939 + (% class=~"entry-title~" ~%) 940 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) = 941 + #else 942 + (% class=~"entry-title~" ~%) 943 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] === 944 + #end 945 +#end 946 +## 947 +## 948 +## 949 +#** 950 + * Displays the body of the entry. 951 + * 952 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 953 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 954 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 955 + *### 956 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract) 957 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)((( 958 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent) 959 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328 960 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content 961 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}} 962 + ))) ## entry-content 963 + (% class=~"clearfloats~" ~%)((())) 964 +#end 965 +## 966 +## 967 +## 968 +#** 969 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content 970 + * of the <tt>extract</tt> field (if not empty). 971 + * 972 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 973 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 974 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 975 + * @param entryContent The resulting content. 976 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when 977 + * <tt>onlyExtract</tt> is <tt>true</tt>) 978 + *### 979 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis) 980 + #if ($onlyExtract) 981 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead 982 + ## of the content. 983 + #set ($macro.result = $entryObj.getProperty('extract').value.trim()) 984 + #end 985 + #if(~"$!macro.result~" == '') 986 + #set($macro.result = $entryObj.getProperty('content').value) 987 +#* Disabled until the content can be cleanly cut. 988 +* #if($onlyExtract && $result.length()>$maxchars) 989 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars)) 990 +* #set($i = $i + 1) 991 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~") 992 +* #end 993 +## *### 994 + #elseif (!$removeEllipsis) 995 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0') 996 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~") 997 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1') 998 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~") 999 + #end 1000 + #end 1001 + #set ($entryContent = $NULL) 1002 + #setVariable (~"$entryContent~" $macro.result) 1003 +#end 1004 +## 1005 +## 1006 +## 1007 +#** 1008 + * Displays the footer of the entry. 1009 + * 1010 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 1011 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 1012 + *### 1013 +#macro(displayEntryFooter $entryDoc $entryObj) 1014 + (% class=~"entry-footer~" ~%)((( 1015 + #isPublished($entryObj $isPublished) 1016 + (% class='entry-author-label' ~%) 1017 + #if($isPublished) 1018 + \{\{translation key='blog.code.postedby'/}} ## 1019 + #else 1020 + \{\{translation key='blog.code.createdby'/}} ## 1021 + #end 1022 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ## 1023 + #getEntryDate($entryDoc $entryObj $entryDate) 1024 + #listCategories($entryObj) #* 1025 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that 1026 + ## we assume cannot be more than 3 seconds. 1027 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ## 1028 + #if ($showcomments) 1029 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ## 1030 + #end ## 1031 + #if($entryDoc != $doc) ## 1032 + #displayEntryBlogLocation($entryDoc $entryObj) ## 1033 + #end 1034 + )))## entry-footer 1035 +#end 1036 +## 1037 +## 1038 +#** 1039 + * Display the blog for the entry (if it is not the currently displayed blog) 1040 + * 1041 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 1042 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 1043 + *### 1044 +#macro(displayEntryBlogLocation $entryDoc $entryObj) 1045 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ## 1046 + #if(~"$!blogPostsLocation~" != ~"~") ## 1047 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ## 1048 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ## 1049 + #if($doc.documentReference != $blogDocRef) ## 1050 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ## 1051 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ## 1052 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ## 1053 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ## 1054 + )))(%~%)## 1055 + #end 1056 + #end 1057 + #end 1058 +#end 1059 +## 1060 +## 1061 +## 1062 +## 1063 +#** 1064 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>. 1065 + * 1066 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 1067 + *### 1068 +#macro(listCategories $entryObj) 1069 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname) 1070 + #set($categories = $entryObj.getProperty('category').value) 1071 + #set($first = true) 1072 + #if($categories.size() > 0) 1073 + #foreach($category in $categories) 1074 + #set($categoryDoc = $!xwiki.getDocument($category)) 1075 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname})) 1076 + #if($foreach.count == 1) 1077 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ## 1078 + #else 1079 + , ## 1080 + #end## 1081 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]## 1082 + #end## 1083 + #end## 1084 + #end 1085 + #end 1086 +#end 1087 +## 1088 +## 1089 +## 1090 +#** 1091 + * Displays blog pagination links (older and newer entries). 1092 + * 1093 + * @param blogDoc the XDocument holding the blog definition object. 1094 + *### 1095 +#macro(displayNavigationLinks $blogDoc) 1096 + (% class=~"clearfloats~" ~%)((())) 1097 + #getBlogDisplayType($blogDoc $displayType) 1098 + #if($displayType == 'weekly') 1099 + (% class=~"pagingLinks~" ~%)((( 1100 + #getRequestedWeek($weekDate) 1101 + $weekDate.addWeeks(-1)## 1102 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 1103 + #sep() 1104 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above 1105 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 1106 + ))) 1107 + #elseif($displayType == 'monthly') 1108 + (% class=~"pagingLinks~" ~%)((( 1109 + #getRequestedMonth($monthDate) 1110 + $monthDate.addMonths(-1)## 1111 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 1112 + #sep() 1113 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above 1114 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 1115 + ))) 1116 + #elseif($displayType == 'all') 1117 + #else 1118 + ## Paginated 1119 + #if(($totalPages > 1)) 1120 + #set($queryString = '') 1121 + #foreach($p in $request.getParameterNames()) 1122 + #if($p != 'page' && $p != 'ipp') 1123 + #foreach($v in $request.getParameterValues($p)) 1124 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~") 1125 + #end 1126 + #end 1127 + #end 1128 + (% class=~"pagingLinks~" ~%)((( 1129 + #if ($currentPageNumber < $totalPages) 1130 + #set($currentPageNumber = $currentPageNumber + 1) 1131 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 1132 + #set($currentPageNumber = $currentPageNumber - 1) 1133 + #end 1134 + #if ($currentPageNumber > 1) 1135 + #if ($currentPageNumber < $totalPages) 1136 + #sep() 1137 + #end 1138 + #set($currentPageNumber = $currentPageNumber - 1) 1139 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 1140 + #set($currentPageNumber = $currentPageNumber + 1) 1141 + #end 1142 + (% class=~"clear~" ~%)(%~%) 1143 + )))## pagingLinks 1144 + #end 1145 + #end 1146 +#end 1147 +## 1148 +## 1149 +## 1150 +#** 1151 + * Displays a message box with ~"publish~" icon. 1152 + * 1153 + * @param message A text message concerning blog article publishing 1154 + *### 1155 +#macro(publishMessageBox $message) 1156 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message))) 1157 +#end 1158 +#** 1159 + * Displays a message box with ~"show/hide~" icon. 1160 + * 1161 + * @param message A text message concerning blog article hiding 1162 + *### 1163 +#macro(hideMessageBox $message) 1164 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message))) 1165 +#end 1166 +## 1167 +## 1168 +## 1169 +#** 1170 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are 1171 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used. 1172 + * 1173 + * @param monthDate The resulting week, a JODATime MutableDateTime. 1174 + *### 1175 +#macro(getRequestedWeek $weekDate) 1176 + #set ($weekDate = $NULL) 1177 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime) 1178 + #if(~"$!\{request.year}~" != '') 1179 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue())) 1180 + #end 1181 + #if(~"$!\{request.week}~" != '') 1182 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue())) 1183 + #end 1184 +#end 1185 +## 1186 +## 1187 +## 1188 +#** 1189 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are 1190 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used. 1191 + * 1192 + * @param monthDate The resulting month, a JODATime MutableDateTime. 1193 + *### 1194 +#macro(getRequestedMonth $monthDate) 1195 + #set ($monthDate = $NULL) 1196 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime) 1197 + #if(~"$!\{request.year}~" != '') 1198 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue())) 1199 + #end 1200 + #if(~"$!\{request.month}~" != '') 1201 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue())) 1202 + #end 1203 +#end 1204 +## 1205 +## 1206 +## 1207 +#** 1208 + * Retrieve a blog property (title, display type, etc). 1209 + * 1210 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 1211 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties. 1212 + * @param defaultValue The default value to use in case the blog object does not define one. 1213 + * @param propertyValue The resulting value. 1214 + *### 1215 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue) 1216 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~") 1217 + #if($result == '') 1218 + #set($result = $defaultValue) 1219 + #end 1220 + #set ($propertyValue = $NULL) 1221 + #setVariable (~"$propertyValue~" $result) 1222 +#end 49 49 50 -{{/velocity}} 1224 +#** 1225 + * If an error occurs when executing an action, set a specific response status and display an error message. 1226 + * 1227 + * @param status The response status. 1228 + * @param text The user readable error to be displayed. Can be a translation key. 1229 + * @param parameters The parameters to use when decoding the translation key. 1230 + *### 1231 +#macro(blog__actionResponseError $status $text $parameters) 1232 + $response.setStatus($status) 1233 + #if($request.ajax) 1234 + $services.localization.render($text, $!parameters) 1235 + #else 1236 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}} 1237 + #end 1238 +#end 1239 +## 1240 +## 1241 +## 1242 +#** 1243 + * Check if a blog is the Default blog (The one in the 'Blog' space). 1244 + * 1245 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 1246 + * @param isDefault The resulting boolean. 1247 + *### 1248 +#macro(isDefaultBlog $blogDoc $isDefault) 1249 + #set ($result = false) 1250 + #if ($blogDoc.space == 'Blog') 1251 + #set ($result = true) 1252 + #end 1253 + #setVariable(~"$isDefault~" $result) 1254 +#end 1255 +## 1256 +## 1257 +## 1258 +#** 1259 + * Retrieve the blog posts location (space). 1260 + * 1261 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 1262 + * @param postsLocation The resulting location. 1263 + *### 1264 +#macro(getBlogPostsLocation $blogSpace $postsLocation) 1265 + #getBlogDocument($blogSpace $blogDoc) 1266 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result) 1267 + #set ($postsLocation = $NULL) 1268 + #setVariable (~"$postsLocation~" $result) 1269 +#end 1270 +## 1271 +## 1272 +## 1273 +#** 1274 + * Retrieve the blog categories location (space). 1275 + * 1276 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 1277 + * @param categoriesLocation The resulting location. 1278 + *### 1279 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation) 1280 + #getBlogDocument($blogSpace $blogDoc) 1281 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result) 1282 + #set ($postsLocation = $NULL) 1283 + #setVariable (~"$categoriesLocation~" $result) 1284 +#end 1285 +###** 1286 + * Return the Query for selecting the blog posts based on the context where the posts are displayed. 1287 + * for example there is 4 different panel contexts: 1288 + * aBlog.aPost or aBlog.WebHome 1289 + * aCategorySpace.aCategory 1290 + * aCategorySpace.WebHome 1291 + * Blog.aPost or Blog.WebHome 1292 + * 1293 + * @param query The query for selecting blog entries. 1294 + * @param queryParams The parameters to bind with the generated query. 1295 + * @param targetDoc The document in which the articles will be displayed. 1296 + *### 1297 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams) 1298 + #set ($query = $NULL) 1299 + #set ($queryParams = $NULL) 1300 + #getCategoryAllBlogPostsQuery($resultQuery) 1301 + #set ($resultQueryParams = \{}) 1302 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 1303 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 1304 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%' 1305 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space)) 1306 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 1307 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~") 1308 + #elseif($targetDoc.getObject($blogCategoryClassname)) 1309 + ## Get all posts that are in a category aCategorySpace.aCategory 1310 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName)) 1311 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~") 1312 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 1313 + ## Get all posts that are in a category aCategorySpace.% 1314 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 1315 + ## Exclude incategorized posts 1316 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~") 1317 + #if ($targetDoc.space == $defaultBlogSpace) 1318 + #set ($excludedCategory = ~"Blog.Categories.WebHome~") 1319 + #end 1320 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory)) 1321 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~") 1322 + #else 1323 + ## Get all posts in blog space aBlog 1324 + #getAllBlogPostsQuery($resultQuery) 1325 + #getBlogPostsLocation($targetDoc.space $postsLocation) 1326 + #set ($discard = $resultQueryParams.put('space', $postsLocation)) 1327 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~") 1328 + #end 1329 + #setVariable(~"$query~" $resultQuery) 1330 + #setVariable(~"$queryParams~" $resultQueryParams) 1331 +#end 1332 +## 1333 +## 1334 +## 1335 +###** 1336 + * Display blog posts based on the context where the posts are displayed. 1337 + * for example there is 4 different panel contexts: 1338 + * aBlog.aPost or aBlog.WebHome 1339 + * aCategorySpace.aCategory 1340 + * aCategorySpace.WebHome 1341 + * Blog.aPost or Blog.WebHome 1342 + * 1343 + * @param targetDoc The document in which the articles will be displayed. 1344 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ... 1345 + * @param layout Layout of the the posts to display 1346 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN' 1347 + * @param limit the number of posts to display 1348 + *### 1349 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit) 1350 + #if ($postLayout == 'full') 1351 + #set ($macro.paginated = 'yes') 1352 + #end 1353 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 1354 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%' 1355 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout) 1356 + #if (~"$!layout~" == '') 1357 + #set ($layout = $postsLayout) 1358 + #end 1359 + #if ($postsVisiblity == 'recent') 1360 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 1361 + #elseif($postsVisiblity == 'unpublished') 1362 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 1363 + #end 1364 + #elseif($targetDoc.getObject($blogCategoryClassname)) 1365 + ## Display all posts that are in a category aCategorySpace.aCategory 1366 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc) 1367 + #getBlogPostsLayout($blogDoc $postsLayout) 1368 + #if (~"$!layout~" == '') 1369 + #set ($layout = $postsLayout) 1370 + #end 1371 + #if ($postsVisiblity == 'recent') 1372 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 1373 + #elseif($postsVisiblity == 'unpublished') 1374 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 1375 + #end 1376 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 1377 + ## Display all posts that are in a category aCategorySpace.% 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.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 1385 + #elseif($postsVisiblity == 'unpublished') 1386 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 1387 + #end 1388 + #else 1389 + ## Display all posts in blog space aBlog 1390 + #getBlogDocument($targetDoc.space $blogDoc) 1391 + #getBlogPostsLayout($blogDoc $postsLayout) 1392 + #if (~"$!layout~" == '') 1393 + #set ($layout = $postsLayout) 1394 + #end 1395 + #if ($postsVisiblity == 'recent') 1396 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 1397 + #elseif($postsVisiblity == 'unpublished') 1398 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 1399 + #end 1400 + #end 1401 +#end 1402 +## 1403 +## 1404 +## 1405 +#** 1406 + * Bind parameters to a query object. 1407 + * 1408 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object) 1409 + * @param queryParams the query parameters. 1410 + *### 1411 +#macro(bindQueryParameters $queryObj $queryParams) 1412 + #set ($output = $queryObj) 1413 + #foreach( $key in $queryParams.keySet() ) 1414 + #set($output = $queryObj.bindValue($key, $queryParams.get($key))) 1415 + #end 1416 + #setVariable(~"$queryObj~" $output) 1417 +#end 1418 +## 1419 +## 1420 +## 1421 +#** 1422 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail 1423 + * 1424 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt> 1425 + * property set. 1426 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default). 1427 + *### 1428 +#macro(getBlogPostsLayout $blogDoc $postsLayout) 1429 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res) 1430 + #set ($postsLayout = $NULL) 1431 + #setVariable (~"$postsLayout~" $res) 1432 +#end 1433 +## 1434 +## 1435 +## 1436 +#** 1437 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space 1438 + * 1439 + * @param categoriesSpace A <tt>String</tt>, the name of the space. 1440 + * @param blogDoc The resulting XDocument. 1441 + *### 1442 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc) 1443 + #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()) 1444 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace) 1445 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0))) 1446 + #else 1447 + ## Fallback to Blog.WebHome, the default blog 1448 + #set($macro.result = $xwiki.getDocument('Blog.WebHome')) 1449 + #end 1450 + #set ($blogDoc = $NULL) 1451 + #setVariable (~"$blogDoc~" $macro.result) 1452 +#end" %) 1453 +((( 1454 +(% class="macro-placeholder hidden" %) 1455 +((( 1456 +macro:velocity 1457 +))) 1458 +))) 1459 +))) 51 51 1461 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %) 1462 +((( 1463 +(% class="macro-placeholder hidden" %) 1464 +((( 1465 +macro:include 52 52 ))) 53 -{{velocity}} 54 -#if (!$hasEdit) 1467 + 1468 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#** 1469 + * Extract the layout parameters from a string. 1470 + * 1471 + * @param layoutParamsString The string representation of the layout parameters. 1472 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~" 1473 + * @param layoutsParameters The resulting layout parameters Map. 1474 + *### 1475 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters) 1476 + #set ($layoutsParameters = $NULL) 1477 + #set ($macro.layoutParams = \{}) 1478 + #if (~"$!layoutParamsString~" != '') 1479 + #set ($macro.paramsArr = $layoutParamsString.split('\\|')) 1480 + #foreach ($item in $macro.paramsArr) 1481 + #set ($itemSplit = $item.split('=')) 1482 + #if ($itemSplit.size() == 2) 1483 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim())) 1484 + #end 1485 + #end 1486 + #end 1487 + #setVariable(~"$layoutsParameters~" $macro.layoutParams) 1488 +#end" %) 1489 +((( 1490 +(% class="macro-placeholder hidden" %) 1491 +((( 1492 +macro:velocity 1493 +))) 1494 +))) 1495 +))) 1496 + 1497 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj) 1498 + #initLayoutVars($pDoc $pObj) 1499 + <div class=~"col-xs-12 col-sm-6 next_blog~"> 1500 + <a href=~"$pDoc.uRL~" class=~"thumbnail~"> 1501 + <div class=~"row~"> 1502 + <div class=~"col-xs-4~"> 1503 + #if ($imageAtt) 1504 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 1505 + #end 1506 + </div> 1507 + <div class=~"col-xs-8 art_det~"> 1508 + <p class=~"text-left~"> 1509 + #if($displayTitle)$!postTitle #end 1510 + <br/><span class=~"date_info~"> $!dateStr </span> 1511 + </p> 1512 + #displayPostDetails($pDoc) 1513 + </div> 1514 + </div> 1515 + </a> 1516 + </div> 1517 + #end 1518 + ## 1519 + ## 1520 + ## 1521 + #macro(displayPinnedPost $pDoc $pObj) 1522 + #initLayoutVars($pDoc $pObj) 1523 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~"> 1524 + <a href=~"$pDoc.uRL~" class=~"all-post-link~"> 1525 + <div class=~"thumbnail~"> 1526 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts) 1527 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 1528 + #end 1529 + #if ($imageAtt) 1530 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 1531 + #end 1532 + <div class=~"caption~"> 1533 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts) 1534 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 1535 + #end 1536 + #if ($displaySummaryOnPinnedPosts) 1537 + <div class=~"text-left post-summary~"> 1538 + #set ($postContent = $pObj.getProperty('extract').value) 1539 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString()) 1540 + </div> 1541 + #end 1542 + #displayPostDetails($pDoc) 1543 + </div> 1544 + </div> 1545 + </a> 1546 + </div> 1547 + #end 1548 + ## 1549 + ## 1550 + ## 1551 + #macro(formatPostDate $pDoc $pObj) 1552 + #set ($formattedDate = $NULL) 1553 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale)) 1554 + #if (~"$!dateStr~" != '') 1555 + #set ($dateArr = $dateStr.split(' ')) 1556 + #if ($dateArr.size() > 3) 1557 + #set ($dateStr = ~"~") 1558 + #foreach($s in $dateArr.subList(0, 3)) 1559 + #set ($dateStr = ~"$\{dateStr}$\{s} ~") 1560 + #end 1561 + #end 1562 + #end 1563 + #setVariable(~"$formattedDate~" $dateStr) 1564 + #end 1565 + ## 1566 + ## 1567 + ## 1568 + #macro(displayPostDetails $pDoc) 1569 + <div class=~"row post-details~"> 1570 + <div class=~"col-xs-8 detail~"> 1571 + #if ($services.like.displayButton($pDoc.documentReference)) 1572 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference)) 1573 + ## Retrieve the likes number in XWiki 12.9+ 1574 + #set ($likeNumber = $optLikeRecord.get()) 1575 + #if (!$stringtool.isNumeric($likeNumber.toString())) 1576 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9. 1577 + #set ($likeNumber = $optLikeRecord.get().likeNumber) 1578 + #end 1579 + #if ($stringtool.isNumeric($likeNumber.toString())) 1580 + <div class=~"post-likes btn btn-default disabled badge~" 1581 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~"> 1582 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span> 1583 + </div> 1584 + #end 1585 + #elseif ($services.ratings) 1586 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference)) 1587 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1) 1588 + <ul class=~"pull-left note list-inline~"> 1589 + #foreach ($x in [1..5]) 1590 + #set ($cls = ~"~") 1591 + #if ($x > $averageVote) 1592 + #set ($cls = ~"-o~") 1593 + #end 1594 + <li><span class=~"fa fa-star$\{cls}~"></span></li> 1595 + #end 1596 + </ul> 1597 + #end 1598 + #end 1599 + </div> 1600 + #if ($showPostComments) 1601 + <div class=~"col-xs-4 com_det~"> 1602 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p> 1603 + </div> 1604 + #end 1605 + </div> 1606 + #end 1607 + ## 1608 + ## 1609 + ## 1610 + #macro(initLayoutVars $pDoc $pObj) 1611 + #set ($postTitle = $pDoc.display('title', 'view', $pObj)) 1612 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image'))) 1613 + #isPublished($pObj $isPublished) 1614 + #isHidden($pObj $isHidden) 1615 + #getEntryDate($pDoc $pObj $postDate) 1616 + #formatPostDate($postDate $dateStr) 1617 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote())) 1618 + #set ($nbComments = $pDoc.getComments().size()) 1619 + #set ($showPostComments = true) 1620 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0') 1621 + #set ($showPostComments = false) 1622 + #end 1623 + #end 1624 + ## 1625 + ## 1626 + ## 1627 + #macro(displayEditPinnedPostsButton) 1628 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName)) 1629 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet')) 1630 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet')) 1631 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet')) 1632 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~")) 1633 + <div class=~"edit-pinned-posts-container~"> 1634 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~"> 1635 + <a href=~"javascript:;~" class=~"editPinnedPosts~"> 1636 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit') 1637 + </a> 1638 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/> 1639 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/> 1640 + </div> 1641 + </div> 1642 + #if (~"$!pinnedPostsObj~" == '') 1643 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/> 1644 + #end 1645 + #end 1646 + #end" %) 1647 +((( 1648 +(% class="macro-placeholder hidden" %) 1649 +((( 1650 +macro:velocity 1651 +))) 1652 +))) 1653 + 1654 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference)) 1655 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference)) 1656 + #getEntryObject($postDoc $postObj) 1657 + #if (~"$!postObj~" != '') 1658 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams) 1659 + ## 1660 + #set ($displayTitle = true) 1661 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false') 1662 + #set ($displayTitle = false) 1663 + #end 1664 + ## 1665 + #set ($displayTitleFirstOnPinnedPosts = false) 1666 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true') 1667 + #set ($displayTitleFirstOnPinnedPosts = true) 1668 + #end 1669 + ## 1670 + #set ($displaySummaryOnPinnedPosts = true) 1671 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false') 1672 + #set ($displaySummaryOnPinnedPosts = false) 1673 + #end 1674 + ## 1675 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue()) 1676 + #if ($postIndex == 0) 1677 + #set ($stopBlogPostsDisplay = false) 1678 + #end 1679 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue()) 1680 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards')) 1681 + #set($scaleWidth = 600) 1682 + #set($imgQs=~"width=$scaleWidth~") 1683 + ## Display pinned posts 1684 + ## Get the list of pinned posts 1685 + #set ($pinnedPosts = []) 1686 + #set ($pinnedPostsSourceDoc = $NULL) 1687 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '') 1688 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog'))) 1689 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro 1690 + #end 1691 + #if (~"$!pinnedPostsSourceDoc~" != '') 1692 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass')) 1693 + #if (~"$!pinnedPostsObj~" != '') 1694 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value) 1695 + #if (~"$!orderedPinnedPostsJSON~" != '') 1696 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON)) 1697 + #else 1698 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value) 1699 + #end 1700 + #end 1701 + #if ($postIndex == 0 && $pinnedPosts.size() > 0) 1702 + \{\{html clean=~"false~"}} 1703 + #set ($x = 0) 1704 + #set ($showPinnedPostsButton = true) 1705 + #foreach ($pinnedPost in $pinnedPosts) 1706 + #if ($x == 0) 1707 + <div class=~"row flex-container~"> 1708 + #if ($showPinnedPostsButton) 1709 + #displayEditPinnedPostsButton() 1710 + #set($showPinnedPostsButton = false) 1711 + #end 1712 + #end 1713 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost)) 1714 + #getEntryObject($pinnedPostDoc $pinnedPostObj) 1715 + #if (~"$!pinnedPostObj~" != '') 1716 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj) 1717 + #end 1718 + #set ($x = $mathtool.add($x, 1)) 1719 + #if ($x == 3) 1720 + #set ($x = 0) 1721 + </div> 1722 + #end 1723 + #end 1724 + #if ($mathtool.mod($x, 3) != 0) 1725 + </div> 1726 + #end 1727 + \{\{/html}} 1728 + 1729 + ## If the first post is a pinned post : this means that all the posts are pinned 1730 + ## In this case, avoid displaying the posts again after the pinned posts section. 1731 + #if ($pinnedPosts.contains($xcontext.macro.params.reference)) 1732 + #set ($stopBlogPostsDisplay = true) 1733 + #end 1734 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0) 1735 + 1736 + \{\{html}} 1737 + <div class=~"row no-pinnded-posts~"> 1738 + #displayEditPinnedPostsButton() 1739 + </div> 1740 + \{\{/html}} 1741 + 1742 + #end 1743 + #end 1744 + #if (!$stopBlogPostsDisplay) 1745 + \{\{html clean=~"false~"}} 1746 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0) 1747 + #set ($nbDisplayedPosts = 0) 1748 + #end 1749 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0) 1750 + #if ($nbDisplayedPosts != 0) 1751 + </div> 1752 + #set ($lastHtmlTag = 'c') 1753 + #end 1754 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 1755 + <div class=~"row~"> 1756 + #set ($lastHtmlTag = 'o') 1757 + #set ($lastRowClass = ~"~") 1758 + #else 1759 + <div class=~"row flex-container~"> 1760 + #set ($lastHtmlTag = 'o') 1761 + #set ($lastRowClass = ~"flex~") 1762 + #end 1763 + #end 1764 + #displaySmallPost($postDoc $postObj) 1765 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 1766 + </div> 1767 + #set ($lastHtmlTag = 'c') 1768 + #end 1769 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1)) 1770 + #if ($postIndex == $mathtool.sub($listResultsCount, 1)) 1771 + #if (~"$!lastHtmlTag~" == 'o') 1772 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~") 1773 + <div class=~"col-xs-12 col-sm-6~"></div> 1774 + #end 1775 + </div> 1776 + #end 1777 + #end 1778 + \{\{/html}} 1779 + #end 1780 + #else 1781 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}} 1782 + #end 1783 + #else 1784 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}} 1785 + #end" %) 1786 +((( 1787 +(% class="macro-placeholder hidden" %) 1788 +((( 1789 +macro:velocity 1790 +))) 1791 + 1792 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"row flex-container~"> 1793 +<div class=~"col-xs-12 col-sm-6 next_blog~"> 1794 +<a href=~"/Nieuws/Nieuwsbrief%20januari%202024~" class=~"thumbnail~"> 1795 +<div class=~"row~"> 1796 +<div class=~"col-xs-4~"> 1797 +<img src=~"/download/Nieuws/Nieuwsbrief%20januari%202024/man-outdoor-light-architecture-people-street-1194699-pxhere.com.jpg?width=600&rev=1.1~" /> 1798 +</div> 1799 +<div class=~"col-xs-8 art_det~"> 1800 +<p class=~"text-left~"> 1801 +Nieuwsbrief januari 2024 <br/><span class=~"date_info~"> 5 feb. 2024 </span> 1802 +</p> 1803 +<div class=~"row post-details~"> 1804 +<div class=~"col-xs-8 detail~"> 1805 +<div class=~"post-likes btn btn-default disabled badge~" 1806 +title=~"Number of likes on this page: 3~"> 1807 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">3</span> 1808 +</div> 1809 +</div> 1810 +<div class=~"col-xs-4 com_det~"> 1811 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p> 1812 +</div> 1813 +</div> 1814 +</div> 1815 +</div> 1816 +</a> 1817 +</div>" %) 1818 +((( 1819 +(% class="macro-placeholder hidden" %) 1820 +((( 1821 +macro:html 1822 +))) 1823 + 1824 +(% class="row flex-container" %) 1825 +((( 1826 +(% class="col-xs-12 col-sm-6 next_blog" %) 1827 +((( 1828 +(% class="row" %) 1829 +((( 1830 +(% class="col-xs-4" %) 1831 +((( 1832 +[[~[~[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"]] 1833 +))) 1834 + 1835 +(% class="col-xs-8 art_det" %) 1836 +((( 1837 +(% class="text-left" %) 1838 +[[Nieuwsbrief januari 2024 1839 +(% class="date_info" %) 5 feb. 2024>>path:/Nieuws/Nieuwsbrief%20januari%202024||class="thumbnail"]] 1840 + 1841 +(% class="row post-details" %) 1842 +((( 1843 +(% class="col-xs-8 detail" %) 1844 +((( 1845 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 3" %) 1846 +((( 1847 +[[(% class="like-number" %)3>>path:/Nieuws/Nieuwsbrief%20januari%202024||class="thumbnail"]] 1848 +))) 1849 +))) 1850 + 1851 +(% class="col-xs-4 com_det" %) 1852 +((( 1853 +(% class="text-right" %) 1854 +[[(0)>>path:/Nieuws/Nieuwsbrief%20januari%202024||class="thumbnail"]] 1855 +))) 1856 +))) 1857 +))) 1858 +))) 1859 +))) 1860 + 1861 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Audit BMI en BORG~" params=~"displayTitle=true|useSummary=true|list-limit=6|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=6|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024~"" %) 1862 +((( 1863 +(% class="macro-placeholder hidden" %) 1864 +((( 1865 +macro:blogPostLayoutCards 1866 +))) 1867 + 1868 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %) 1869 +((( 1870 +(% class="macro-placeholder hidden" %) 1871 +((( 1872 +macro:include 1873 +))) 1874 + 1875 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %) 1876 +((( 1877 +(% class="macro-placeholder hidden" %) 1878 +((( 1879 +macro:include 1880 +))) 1881 + 1882 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog 1883 +#set($blogClassname = 'Blog.BlogClass') 1884 +#set($blogTemplate = 'Blog.BlogTemplate') 1885 +#set($blogSheet = 'Blog.BlogSheet') 1886 +## Blog entries 1887 +#set($blogPostClassname = 'Blog.BlogPostClass') 1888 +#set($blogPostTemplate = 'Blog.BlogPostTemplate') 1889 +#set($blogPostSheet = 'Blog.BlogPostSheet') 1890 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number) 1891 +#set($oldArticleClassname = 'XWiki.ArticleClass') 1892 +## Categories 1893 +#set($blogCategoryClassname = 'Blog.CategoryClass') 1894 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate') 1895 +#set($blogCategorySheet = 'Blog.CategorySheet') 1896 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet') 1897 +#set($oldBlogCategoryClassname = 'Blog.Categories') 1898 +#set($defaultCategoryParent = 'Blog.Categories') 1899 +## Style 1900 +#set($blogStyleDocumentName = 'Blog.BlogStyle') 1901 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName)) 1902 +## Clientside scripts 1903 +#set($blogScriptsDocumentName = 'Blog.BlogScripts') 1904 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher')) 1905 +## Misc 1906 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString)) 1907 +#set($isBlogPost = $doc.getObject($blogPostClassname)) 1908 +#set($defaultBlogSpace = 'Blog') 1909 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname)) 1910 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 1911 +## 1912 +## 1913 +## 1914 +#** 1915 + * Displays an image, taken from the blog style document. 1916 + * 1917 + * @param $imgName The name of the icon from icons set to use. 1918 + *# 1919 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %) 1920 +((( 1921 +(% class="macro-placeholder hidden" %) 1922 +((( 1923 +macro:velocity 1924 +))) 1925 +))) 1926 +))) 1927 + 1928 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## 1929 +## 1930 +## 1931 +## Import the blog skin and javascripts. 1932 +$!xwiki.ssx.use($blogStyleDocumentName)## 1933 +$!xwiki.jsx.use($blogScriptsDocumentName)## 1934 +## 1935 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation) 1936 +#template('hierarchy_macros.vm')## 1937 +## 1938 +## 1939 +#** 1940 + * Prints a blog. This is the main macro used in the BlogSheet. 1941 + * 1942 + * @param blogDoc the XDocument holding the blog definition object. 1943 + *### 1944 +#macro(printBlog $blogDoc) 1945 + \{\{include reference='Blog.CreatePost'/}} 1946 + 1947 + ## Use the blogPostList macro to display the blogposts 1948 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro 1949 + ## do not support FTM the monthly and weekly blog display types 1950 + #getBlogDisplayType($blogDoc $displayType) 1951 + #if ($displayType == 'weekly' || $displayType == 'monthly') 1952 + #getBlogEntries($blogDoc $entries) 1953 + #displayBlog($entries 'index' true true) 1954 + #displayNavigationLinks($blogDoc) 1955 + #else 1956 + #getBlogDisplayType($blogDoc $displayType) 1957 + #set ($paginated = 'no') 1958 + #if ($displayType == 'paginated') 1959 + #set ($paginated = 'yes') 1960 + #end 1961 + #getBlogPostsLayout($blogDoc $postsLayout) 1962 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}}))) 1963 + #end 1964 +#end 1965 +## 1966 +## 1967 +## 1968 +#** 1969 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title, 1970 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index, 1971 + * all entries). 1972 + * 1973 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 1974 + *### 1975 +#macro(showBlogInfo $blogDoc) 1976 + #if($blogDoc.getObject($blogClassname)) 1977 + ## Keep testing for inline action for backward compatibility with older blogs. 1978 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline') 1979 + #macro(displayProperty $blogDoc $propname) 1980 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)): 1981 + : $blogDoc.display($propname) 1982 + #end 1983 + #displayProperty($blogDoc 'title') 1984 + #displayProperty($blogDoc 'description') 1985 + #displayProperty($blogDoc 'displayType') 1986 + #displayProperty($blogDoc 'itemsPerPage') 1987 + #displayProperty($blogDoc 'postsLayout') 1988 + #displayProperty($blogDoc 'postsLayoutParameters') 1989 + #else 1990 + $blogDoc.display('description') 1991 + #end 1992 + #elseif($doc.fullName == $blogSheet) 1993 += $services.localization.render('blog.code.blogsheet') = 1994 + \{\{translation key='blog.code.sheetexplanation'/}} 1995 + #else 1996 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}} 1997 + #end 1998 +#end 1999 +## 2000 +## 2001 +## 2002 +#** 2003 + * Retrieve the blog document, which usually is either <tt><Space>.WebHome</tt> for whole-spaces blogs, or 2004 + * <tt><Space>.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first 2005 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current 2006 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog. 2007 + * 2008 + * @param space A <tt>String</tt>, the name of the space where to search. 2009 + * @param blogDoc The resulting XDocument. 2010 + *### 2011 +#macro(getBlogDocument $space $blogDoc) 2012 + #set ($result = $NULL) 2013 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object. 2014 + ## 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 2015 + ## identify the right blog based on a configuration object in a WebPreferences page. 2016 + #set ($spaceReference = $services.model.resolveSpace($space)) 2017 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference)) 2018 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef)) 2019 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass')) 2020 + #if ($preferencesObj) 2021 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog'))) 2022 + #end 2023 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy. 2024 + #if (~"$!result~" == '') 2025 + ## First, try the Space.WebHome, for a whole-space blog 2026 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~")) 2027 + #if(!$result.getObject($blogClassname)) 2028 + ## Second, try the Space.Blog document 2029 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~")) 2030 + #if(!$result.getObject($blogClassname)) 2031 + ## Third, try searching for a blog document in the current space 2032 + ## Prevent the query fail when the space contains dots '.' 2033 + #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()) 2034 + #if($blogDocs.size() > 0) 2035 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 2036 + #else 2037 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space 2038 + #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()) 2039 + #if($blogDocs.size() > 0) 2040 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 2041 + #else 2042 + ## Last, fallback to Blog.WebHome, the default blog 2043 + #set($result = $xwiki.getDocument('Blog.WebHome')) 2044 + #end 2045 + #end 2046 + #end 2047 + #end 2048 + #end 2049 + #set ($blogDoc = $NULL) 2050 + #setVariable (~"$blogDoc~" $result) 2051 +#end 2052 +## 2053 +## 2054 +## 2055 +#** 2056 + * Retrieve the blog title. 2057 + * 2058 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set. 2059 + * @param title The resulting title. 2060 + *### 2061 +#macro(getBlogTitle $blogDoc $title) 2062 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them. 2063 + #set ($title = $NULL) 2064 + #setVariable (~"$title~" $!blogDoc.displayTitle) 2065 +#end 2066 +## 2067 +## 2068 +## 2069 +#** 2070 + * Retrieve the blog description. 2071 + * 2072 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt> 2073 + * property set. 2074 + * @param description The resulting description. 2075 + *### 2076 +#macro(getBlogDescription $blogDoc $description) 2077 + #getBlogProperty($blogDoc 'description' '' $result) 2078 + #set ($description = $NULL) 2079 + #setVariable (~"$description~" $result) 2080 +#end 2081 +## 2082 +## 2083 +## 2084 +#** 2085 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog 2086 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on 2087 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a 2088 + * month), or all. 2089 + * 2090 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 2091 + * @param entries The resulting list of entries to display, a list of XDocument names. 2092 + *### 2093 +#macro(getBlogEntries $blogDoc $entries) 2094 + #if (!$entries) 2095 + #setVariable (~"$entries~" []) 2096 + #end 2097 + #getAllBlogPostsQuery($query) 2098 + #isDefaultBlog($blogDoc $isDefault) 2099 + #set($queryParams = \{}) 2100 + #if ($isDefault) 2101 + #getCategoryAllBlogPostsQuery($query) 2102 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~") 2103 + #set($discard = $queryParams.put('creator', $xcontext.user)) 2104 + #set($discard = $queryParams.put('space', $blogDoc.space)) 2105 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 2106 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace)) 2107 + #else 2108 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~") 2109 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation) 2110 + #set($discard = $queryParams.put('space', $blogPostsLocation)) 2111 + #set($discard = $queryParams.put('parent', $blogDoc.space)) 2112 + #end 2113 + #getBlogDisplayType($blogDoc $displayType) 2114 + #if($displayType == 'weekly') 2115 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams) 2116 + #elseif($displayType == 'monthly') 2117 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams) 2118 + #elseif($displayType == 'all') 2119 + #getAllBlogEntries($blogDoc $query $entries $queryParams) 2120 + #else 2121 + #getPagedBlogEntries($blogDoc $query $entries $queryParams) 2122 + #end 2123 +#end 2124 +## 2125 +## 2126 +## 2127 +#** 2128 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents 2129 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the 2130 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property 2131 + * (10 if not defined). 2132 + * 2133 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 2134 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 2135 + * refined to restrict to a given space, or to a given search criteria, etc. 2136 + * @param entries The resulting list of entries to display, a list of XDocument names. 2137 + * @param queryParams The parameters to bind with the query. 2138 + *### 2139 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams) 2140 + #if (!$entries) 2141 + #setVariable (~"$entries~" []) 2142 + #end 2143 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 2144 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~")) 2145 + #bindQueryParameters($countQueryObj $queryParams) 2146 + #bindQueryParameters($queryObj $queryParams) 2147 + #set($totalEntries = $countQueryObj.count()) 2148 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage) 2149 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue()) 2150 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 2151 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 2152 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute())) 2153 +#end 2154 +## 2155 +## 2156 +## 2157 +#** 2158 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is 2159 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4 2160 + * digit year). Initially the current week is displayed. 2161 + * 2162 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 2163 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 2164 + * refined to restrict to a given space, or to a given search criteria, etc. 2165 + * @param entries The resulting list of entries to display, a list of XDocument names. 2166 + * @param queryParams The parameters to bind with the query. 2167 + *### 2168 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams) 2169 + #if (!$entries) 2170 + #setVariable (~"$entries~" []) 2171 + #end 2172 + #getRequestedWeek($weekDate) 2173 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 2174 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor())) 2175 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling())) 2176 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 2177 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 2178 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 2179 + #bindQueryParameters($countQueryObj $queryParams) 2180 + #bindQueryParameters($queryObj $queryParams) 2181 + #set($totalEntries = $countQueryObj.count()) 2182 + #set($discard = $entries.addAll($queryObj.execute())) 2183 +#end 2184 +## 2185 +## 2186 +## 2187 +#** 2188 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is 2189 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4 2190 + * digit year). Initially the current month is displayed. 2191 + * 2192 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 2193 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 2194 + * refined to restrict to a given space, or to a given search criteria, etc. 2195 + * @param entries The resulting list of entries to display, a list of XDocument names. 2196 + * @param queryParams The parameters to bind with the query. 2197 + *### 2198 +#macro(getMonthlyBlogEntries $blogDoc $query $entries) 2199 + #if (!$entries) 2200 + #setVariable (~"$entries~" []) 2201 + #end 2202 + #getRequestedMonth($monthDate) 2203 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 2204 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor())) 2205 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling())) 2206 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 2207 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 2208 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 2209 + #bindQueryParameters($countQueryObj $queryParams) 2210 + #bindQueryParameters($queryObj $queryParams) 2211 + #set($totalEntries = $countQueryObj.count()) 2212 + #set($discard = $entries.addAll($queryObj.execute())) 2213 +#end 2214 +## 2215 +## 2216 +## 2217 +#** 2218 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned. 2219 + * 2220 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 2221 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 2222 + * refined to restrict to a given space, or to a given search criteria, etc. 2223 + * @param entries The resulting list of entries to display, a list of XDocument names. 2224 + * @param queryParams The parameters to bind with the query. 2225 + *### 2226 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams) 2227 + #if (!$entries) 2228 + #setVariable (~"$entries~" []) 2229 + #end 2230 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 2231 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 2232 + #bindQueryParameters($countQueryObj $queryParams) 2233 + #bindQueryParameters($queryObj $queryParams) 2234 + #set($totalEntries = $countQueryObj.count()) 2235 + #set($discard = $entries.addAll($queryObj.execute())) 2236 +#end 2237 +## 2238 +## 2239 +## 2240 +#** 2241 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned. 2242 + * 2243 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 2244 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 2245 + * refined to restrict to a given space, or to a given search criteria, etc. 2246 + * @param queryParams The parameters to bind with the query. 2247 + * @param entries The resulting list of entries to display, a list of XDocument names. 2248 + *### 2249 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries) 2250 + #if (!$entries) 2251 + #setVariable (~"$entries~" []) 2252 + #end 2253 + #set($query = ~"$\{query} and isPublished.value = 0~") 2254 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 2255 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 2256 + #bindQueryParameters($countQueryObj $queryParams) 2257 + #bindQueryParameters($queryObj $queryParams) 2258 + #set($totalEntries = $countQueryObj.count()) 2259 + #set($discard = $entries.addAll($queryObj.execute())) 2260 +#end 2261 +## 2262 +## 2263 +## 2264 +#** 2265 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog. 2266 + * 2267 + * @param entries The resulting list of entries to display, a list of XDocument names. 2268 + *### 2269 +#macro(getGlobalBlogEntries $entries) 2270 + #if (!$entries) 2271 + #setVariable (~"$entries~" []) 2272 + #end 2273 + #getAllBlogPostsQuery($query) 2274 + #set($totalEntries = $services.query.hql($query).count()) 2275 + #set($defaultItemsPerPage = 20) 2276 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 2277 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 2278 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute())) 2279 +#end 2280 +#** 2281 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific 2282 + * blog, nor specify a range or an ordering criteria. 2283 + * 2284 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code. 2285 + * 2286 + * @param query The basic query for selecting blog entries. 2287 + *# 2288 +#macro(getBlogEntriesBaseQuery $query) 2289 + #getAllBlogPostsQuery($query) 2290 +#end 2291 +#** 2292 + * Return the Query for selecting the all wiki blog posts without filtering 2293 + * 2294 + * @param query The basic query for selecting blog entries. 2295 + *# 2296 +#macro(getAllBlogPostsQuery $query) 2297 + #set ($query = $NULL) 2298 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished, 2299 + IntegerProperty hidden, DateProperty publishDate 2300 + where doc.fullName <> '$blogPostTemplate' and 2301 + obj.name=doc.fullName and obj.className='$blogPostClassname' and 2302 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and 2303 + hidden.id.id = obj.id and hidden.id.name='hidden' and 2304 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and 2305 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~") 2306 +#end 2307 +## 2308 +## 2309 +## 2310 +###** 2311 + * Return the Query for selecting the all wiki blog posts with categories filtering 2312 + * 2313 + * @param query The basic query for selecting blog entries. 2314 + *### 2315 +#macro(getCategoryAllBlogPostsQuery $query) 2316 + #set ($query = $NULL) 2317 + #getAllBlogPostsQuery($baseQuery) 2318 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList')) 2319 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~") 2320 +#end 2321 +## 2322 +## 2323 +## 2324 +#** 2325 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a 2326 + * week), monthly (all entries in a month), or all. 2327 + * 2328 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt> 2329 + * property set. 2330 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated. 2331 + *### 2332 +#macro(getBlogDisplayType $blogDoc $displayType) 2333 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result) 2334 + #set ($displayType = $NULL) 2335 + #setVariable (~"$displayType~" $result) 2336 +#end 2337 +## 2338 +## 2339 +## 2340 +#** 2341 + * Displays a list of entries. 2342 + * 2343 + * @param entries The entries to display, a list of XDocument names. 2344 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results, 2345 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently 2346 + * used values: index, single, category, search, unpublished, hidden. 2347 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content. 2348 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're 2349 + * displayed alone on their page since it's the page title which is used in this case) 2350 + *### 2351 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles) 2352 + #set($blogDay = '') 2353 + (% class=~"hfeed $!\{displaying}~" ~%)((( 2354 + (% class=~"blogDay~" ~%)((( 2355 + #foreach ($entryDoc in $xwiki.wrapDocs($entries)) 2356 + #getEntryObject($entryDoc $entryObj) 2357 + ## Although all entries should have one of the two objects, better check to be sure. 2358 + #if(~"$!\{entryObj}~" != '') 2359 + #getEntryDate($entryDoc $entryObj $entryDate) 2360 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet. 2361 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd')) 2362 + #if($blogDay != $entryDateStr) 2363 + #if($blogDay != '') 2364 + ))) 2365 + (% class=~"blogDay~" ~%)((( 2366 + #end 2367 + #displayBlogDate($entryDate) 2368 + #set ($blogDay = $entryDateStr) 2369 + #end 2370 + ## Finally, display the entry. 2371 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true) 2372 + #end 2373 + #end 2374 + )))## blogDay 2375 + )))## hfeed 2376 +#end 2377 +## 2378 +## 2379 +## 2380 +#** 2381 + * Get the entry object, either a new BlogPost or an old Article. 2382 + * 2383 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2384 + * @param entryObj The resulting xobject of the blog post. 2385 + *### 2386 +#macro(getEntryObject $entryDoc $__entryObj) 2387 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~")) 2388 + #if(!$result) 2389 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~")) 2390 + #end 2391 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from 2392 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be 2393 + ## overwritten in this case but it's less likely to have such a variable defined before. 2394 + #set ($__entryObj = $NULL) 2395 + #setVariable (~"$__entryObj~" $result) 2396 +#end 2397 +## 2398 +## 2399 +## 2400 +#** 2401 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is 2402 + * the document creation date, but can be edited by the user. 2403 + * 2404 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2405 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2406 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>. 2407 + *### 2408 +#macro(getEntryDate $entryDoc $entryObj $result) 2409 + #set ($result = $NULL) 2410 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value) 2411 +#end 2412 +## 2413 +## 2414 +## 2415 +#** 2416 + * Displays a date, nicely formatted as a calendar page. 2417 + * 2418 + * @param date The date to display, an instance of <tt>java.util.Date</tt>. 2419 + *### 2420 +#macro(displayBlogDate $date) 2421 + #set($year = $xwiki.formatDate($date, 'yyyy')) 2422 + ## 3 letter month name, like Jan, Dec. 2423 + #set($month = $xwiki.formatDate($date, 'MMM')) 2424 + ## Uncomment to get a full length month name, like January, December. 2425 + ## TODO: this could be defined somewhere in the blog style. 2426 + ## #set($month = $xwiki.formatDate($date, 'MMMM')) 2427 + #set($day = $xwiki.formatDate($date, 'dd')) 2428 + (% class=~"blogdate~" ~%) 2429 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) == 2430 +#end 2431 +## 2432 +## 2433 +## 2434 +#** 2435 + * Displays a blog article: management tools, header, content, footer. 2436 + * 2437 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2438 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2439 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 2440 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title 2441 + * when they're displayed alone on their page since it's the page title which is used in this case) 2442 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons 2443 + *### 2444 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions) 2445 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden 2446 + #isPublished($entryObj $isPublished) 2447 + #isHidden($entryObj $isHidden) 2448 + #if($doc.fullName == $entryDoc.fullName) 2449 + (% class=~"hentry single-article~" ~%)((( 2450 + #else 2451 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)((( 2452 + #end 2453 + #if ($shouldDisplayActions) 2454 + #displayEntryTools($entryDoc $entryObj) 2455 + #end 2456 + #if($shouldDisplayTitle) 2457 + #displayEntryTitle($entryDoc $entryObj) 2458 + #end 2459 + #if($doc.fullName == $entryDoc.fullName) 2460 + #if(!$isPublished) 2461 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}} 2462 + #elseif($isHidden) 2463 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}} 2464 + #end 2465 + #end 2466 + #displayEntryContent($entryDoc $entryObj $onlyExtract) 2467 + #displayEntryFooter($entryDoc $entryObj) 2468 + )))## hentry 2469 +#end 2470 +## 2471 +## 2472 +## 2473 +#** 2474 + * Checks if the provided blog is published or not. 2475 + * 2476 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2477 + * @param isPublished The resulting boolean, true if the entry is considered published. 2478 + *### 2479 +#macro(isPublished $entryObj $isPublished) 2480 + #set ($isPublished = $NULL) 2481 + ## This should work for both old articles, which don't have the 'published' property at all, and 2482 + ## are considered published by default, and new entries, that should have 1 if published. 2483 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0') 2484 + #setVariable (~"$isPublished~" true) 2485 + #else 2486 + #setVariable (~"$isPublished~" false) 2487 + #end 2488 +#end 2489 +## 2490 +## 2491 +## 2492 +#** 2493 + * Checks if the provided blog is hidden or not. 2494 + * 2495 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass. 2496 + * @param isHiddel The resulting boolean, true if the entry is considered hidden. 2497 + *### 2498 +#macro(isHidden $entryObj $isHidden) 2499 + #set ($isHidden = $NULL) 2500 + ## This should work for both old articles, which don't have the 'hidden' property at all, and 2501 + ## are considered visible by default, and new entries, that should have 1 if hidden. 2502 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1') 2503 + #setVariable (~"$isHidden~" true) 2504 + #else 2505 + #setVariable (~"$isHidden~" false) 2506 + #end 2507 +#end 2508 +## 2509 +## 2510 +## 2511 +#** 2512 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit. 2513 + * 2514 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2515 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2516 + *### 2517 +#macro(displayEntryTools $entryDoc $entryObj) 2518 + #if($xcontext.action == 'view') 2519 + (% class=~"blog-entry-toolbox~" ~%)((( 2520 + #displayPublishButton($entryDoc $entryObj) 2521 + #displayHideShowButton($entryDoc $entryObj) 2522 + #displayEditButton($entryDoc $entryObj) 2523 + #displayDeleteButton($entryDoc $entryObj) 2524 + ))) 2525 + #end 2526 +#end 2527 +## 2528 +## 2529 +## 2530 +#** 2531 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet. 2532 + * 2533 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2534 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2535 + * @todo AJAX calls. 2536 + *### 2537 +#macro(displayPublishButton $entryDoc $entryObj) 2538 + #isPublished($entryObj $isPublished) 2539 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 2540 + [[#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')~"]]## 2541 + #end 2542 +#end 2543 +## 2544 +## 2545 +## 2546 +#** 2547 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published. 2548 + * 2549 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2550 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2551 + *### 2552 +#macro(displayHideShowButton $entryDoc $entryObj) 2553 + #isPublished($entryObj $isPublished) 2554 + #isHidden($entryObj $isHidden) 2555 + ## Only published articles can be hidden. Unpublished articles are considered already hidden. 2556 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 2557 + #set ($queryString = \{ 2558 + 'xredirect' : $thisURL, 2559 + 'form_token' : $services.csrf.getToken() 2560 + }) 2561 + #if ($isHidden) 2562 + #set ($discard = $queryString.putAll(\{ 2563 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0, 2564 + 'comment' : $services.localization.render('blog.code.madevisible') 2565 + })) 2566 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 2567 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]## 2568 + #else 2569 + #set ($discard = $queryString.putAll(\{ 2570 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1, 2571 + 'comment' : $services.localization.render('blog.code.hid') 2572 + })) 2573 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 2574 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]## 2575 + #end 2576 + #end 2577 +#end 2578 +## 2579 +## 2580 +## 2581 +#** 2582 + * Displays the edit button to those that can edit the article. 2583 + * 2584 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2585 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2586 + *### 2587 +#macro(displayEditButton $entryDoc $entryObj) 2588 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 2589 + ## Call getDefaultEditMode() for backward compatibility with older blog posts. 2590 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]## 2591 + #end 2592 +#end 2593 +## 2594 +## 2595 +## 2596 +#** 2597 + * Displays the delete button to those that can edit the article. 2598 + * 2599 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2600 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2601 + * @todo AJAX calls. 2602 + *### 2603 +#macro(displayDeleteButton $entryDoc $entryObj) 2604 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName)) 2605 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]## 2606 + #end 2607 +#end 2608 +## 2609 +## 2610 +## 2611 +#** 2612 + * Displays the title of the entry. 2613 + * 2614 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2615 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2616 + *### 2617 +#macro(displayEntryTitle $entryDoc $entryObj) 2618 + #if($doc.fullName == $entryDoc.fullName) 2619 + (% class=~"entry-title~" ~%) 2620 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) = 2621 + #else 2622 + (% class=~"entry-title~" ~%) 2623 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] === 2624 + #end 2625 +#end 2626 +## 2627 +## 2628 +## 2629 +#** 2630 + * Displays the body of the entry. 2631 + * 2632 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2633 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2634 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 2635 + *### 2636 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract) 2637 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)((( 2638 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent) 2639 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328 2640 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content 2641 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}} 2642 + ))) ## entry-content 2643 + (% class=~"clearfloats~" ~%)((())) 2644 +#end 2645 +## 2646 +## 2647 +## 2648 +#** 2649 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content 2650 + * of the <tt>extract</tt> field (if not empty). 2651 + * 2652 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2653 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2654 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 2655 + * @param entryContent The resulting content. 2656 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when 2657 + * <tt>onlyExtract</tt> is <tt>true</tt>) 2658 + *### 2659 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis) 2660 + #if ($onlyExtract) 2661 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead 2662 + ## of the content. 2663 + #set ($macro.result = $entryObj.getProperty('extract').value.trim()) 2664 + #end 2665 + #if(~"$!macro.result~" == '') 2666 + #set($macro.result = $entryObj.getProperty('content').value) 2667 +#* Disabled until the content can be cleanly cut. 2668 +* #if($onlyExtract && $result.length()>$maxchars) 2669 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars)) 2670 +* #set($i = $i + 1) 2671 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~") 2672 +* #end 2673 +## *### 2674 + #elseif (!$removeEllipsis) 2675 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0') 2676 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~") 2677 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1') 2678 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~") 2679 + #end 2680 + #end 2681 + #set ($entryContent = $NULL) 2682 + #setVariable (~"$entryContent~" $macro.result) 2683 +#end 2684 +## 2685 +## 2686 +## 2687 +#** 2688 + * Displays the footer of the entry. 2689 + * 2690 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2691 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2692 + *### 2693 +#macro(displayEntryFooter $entryDoc $entryObj) 2694 + (% class=~"entry-footer~" ~%)((( 2695 + #isPublished($entryObj $isPublished) 2696 + (% class='entry-author-label' ~%) 2697 + #if($isPublished) 2698 + \{\{translation key='blog.code.postedby'/}} ## 2699 + #else 2700 + \{\{translation key='blog.code.createdby'/}} ## 2701 + #end 2702 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ## 2703 + #getEntryDate($entryDoc $entryObj $entryDate) 2704 + #listCategories($entryObj) #* 2705 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that 2706 + ## we assume cannot be more than 3 seconds. 2707 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ## 2708 + #if ($showcomments) 2709 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ## 2710 + #end ## 2711 + #if($entryDoc != $doc) ## 2712 + #displayEntryBlogLocation($entryDoc $entryObj) ## 2713 + #end 2714 + )))## entry-footer 2715 +#end 2716 +## 2717 +## 2718 +#** 2719 + * Display the blog for the entry (if it is not the currently displayed blog) 2720 + * 2721 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 2722 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2723 + *### 2724 +#macro(displayEntryBlogLocation $entryDoc $entryObj) 2725 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ## 2726 + #if(~"$!blogPostsLocation~" != ~"~") ## 2727 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ## 2728 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ## 2729 + #if($doc.documentReference != $blogDocRef) ## 2730 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ## 2731 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ## 2732 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ## 2733 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ## 2734 + )))(%~%)## 2735 + #end 2736 + #end 2737 + #end 2738 +#end 2739 +## 2740 +## 2741 +## 2742 +## 2743 +#** 2744 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>. 2745 + * 2746 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 2747 + *### 2748 +#macro(listCategories $entryObj) 2749 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname) 2750 + #set($categories = $entryObj.getProperty('category').value) 2751 + #set($first = true) 2752 + #if($categories.size() > 0) 2753 + #foreach($category in $categories) 2754 + #set($categoryDoc = $!xwiki.getDocument($category)) 2755 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname})) 2756 + #if($foreach.count == 1) 2757 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ## 2758 + #else 2759 + , ## 2760 + #end## 2761 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]## 2762 + #end## 2763 + #end## 2764 + #end 2765 + #end 2766 +#end 2767 +## 2768 +## 2769 +## 2770 +#** 2771 + * Displays blog pagination links (older and newer entries). 2772 + * 2773 + * @param blogDoc the XDocument holding the blog definition object. 2774 + *### 2775 +#macro(displayNavigationLinks $blogDoc) 2776 + (% class=~"clearfloats~" ~%)((())) 2777 + #getBlogDisplayType($blogDoc $displayType) 2778 + #if($displayType == 'weekly') 2779 + (% class=~"pagingLinks~" ~%)((( 2780 + #getRequestedWeek($weekDate) 2781 + $weekDate.addWeeks(-1)## 2782 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 2783 + #sep() 2784 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above 2785 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 2786 + ))) 2787 + #elseif($displayType == 'monthly') 2788 + (% class=~"pagingLinks~" ~%)((( 2789 + #getRequestedMonth($monthDate) 2790 + $monthDate.addMonths(-1)## 2791 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 2792 + #sep() 2793 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above 2794 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 2795 + ))) 2796 + #elseif($displayType == 'all') 2797 + #else 2798 + ## Paginated 2799 + #if(($totalPages > 1)) 2800 + #set($queryString = '') 2801 + #foreach($p in $request.getParameterNames()) 2802 + #if($p != 'page' && $p != 'ipp') 2803 + #foreach($v in $request.getParameterValues($p)) 2804 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~") 2805 + #end 2806 + #end 2807 + #end 2808 + (% class=~"pagingLinks~" ~%)((( 2809 + #if ($currentPageNumber < $totalPages) 2810 + #set($currentPageNumber = $currentPageNumber + 1) 2811 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 2812 + #set($currentPageNumber = $currentPageNumber - 1) 2813 + #end 2814 + #if ($currentPageNumber > 1) 2815 + #if ($currentPageNumber < $totalPages) 2816 + #sep() 2817 + #end 2818 + #set($currentPageNumber = $currentPageNumber - 1) 2819 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 2820 + #set($currentPageNumber = $currentPageNumber + 1) 2821 + #end 2822 + (% class=~"clear~" ~%)(%~%) 2823 + )))## pagingLinks 2824 + #end 2825 + #end 2826 +#end 2827 +## 2828 +## 2829 +## 2830 +#** 2831 + * Displays a message box with ~"publish~" icon. 2832 + * 2833 + * @param message A text message concerning blog article publishing 2834 + *### 2835 +#macro(publishMessageBox $message) 2836 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message))) 2837 +#end 2838 +#** 2839 + * Displays a message box with ~"show/hide~" icon. 2840 + * 2841 + * @param message A text message concerning blog article hiding 2842 + *### 2843 +#macro(hideMessageBox $message) 2844 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message))) 2845 +#end 2846 +## 2847 +## 2848 +## 2849 +#** 2850 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are 2851 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used. 2852 + * 2853 + * @param monthDate The resulting week, a JODATime MutableDateTime. 2854 + *### 2855 +#macro(getRequestedWeek $weekDate) 2856 + #set ($weekDate = $NULL) 2857 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime) 2858 + #if(~"$!\{request.year}~" != '') 2859 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue())) 2860 + #end 2861 + #if(~"$!\{request.week}~" != '') 2862 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue())) 2863 + #end 2864 +#end 2865 +## 2866 +## 2867 +## 2868 +#** 2869 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are 2870 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used. 2871 + * 2872 + * @param monthDate The resulting month, a JODATime MutableDateTime. 2873 + *### 2874 +#macro(getRequestedMonth $monthDate) 2875 + #set ($monthDate = $NULL) 2876 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime) 2877 + #if(~"$!\{request.year}~" != '') 2878 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue())) 2879 + #end 2880 + #if(~"$!\{request.month}~" != '') 2881 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue())) 2882 + #end 2883 +#end 2884 +## 2885 +## 2886 +## 2887 +#** 2888 + * Retrieve a blog property (title, display type, etc). 2889 + * 2890 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 2891 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties. 2892 + * @param defaultValue The default value to use in case the blog object does not define one. 2893 + * @param propertyValue The resulting value. 2894 + *### 2895 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue) 2896 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~") 2897 + #if($result == '') 2898 + #set($result = $defaultValue) 2899 + #end 2900 + #set ($propertyValue = $NULL) 2901 + #setVariable (~"$propertyValue~" $result) 2902 +#end 2903 + 2904 +#** 2905 + * If an error occurs when executing an action, set a specific response status and display an error message. 2906 + * 2907 + * @param status The response status. 2908 + * @param text The user readable error to be displayed. Can be a translation key. 2909 + * @param parameters The parameters to use when decoding the translation key. 2910 + *### 2911 +#macro(blog__actionResponseError $status $text $parameters) 2912 + $response.setStatus($status) 2913 + #if($request.ajax) 2914 + $services.localization.render($text, $!parameters) 2915 + #else 2916 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}} 2917 + #end 2918 +#end 2919 +## 2920 +## 2921 +## 2922 +#** 2923 + * Check if a blog is the Default blog (The one in the 'Blog' space). 2924 + * 2925 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 2926 + * @param isDefault The resulting boolean. 2927 + *### 2928 +#macro(isDefaultBlog $blogDoc $isDefault) 2929 + #set ($result = false) 2930 + #if ($blogDoc.space == 'Blog') 2931 + #set ($result = true) 2932 + #end 2933 + #setVariable(~"$isDefault~" $result) 2934 +#end 2935 +## 2936 +## 2937 +## 2938 +#** 2939 + * Retrieve the blog posts location (space). 2940 + * 2941 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 2942 + * @param postsLocation The resulting location. 2943 + *### 2944 +#macro(getBlogPostsLocation $blogSpace $postsLocation) 2945 + #getBlogDocument($blogSpace $blogDoc) 2946 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result) 2947 + #set ($postsLocation = $NULL) 2948 + #setVariable (~"$postsLocation~" $result) 2949 +#end 2950 +## 2951 +## 2952 +## 2953 +#** 2954 + * Retrieve the blog categories location (space). 2955 + * 2956 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 2957 + * @param categoriesLocation The resulting location. 2958 + *### 2959 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation) 2960 + #getBlogDocument($blogSpace $blogDoc) 2961 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result) 2962 + #set ($postsLocation = $NULL) 2963 + #setVariable (~"$categoriesLocation~" $result) 2964 +#end 2965 +###** 2966 + * Return the Query for selecting the blog posts based on the context where the posts are displayed. 2967 + * for example there is 4 different panel contexts: 2968 + * aBlog.aPost or aBlog.WebHome 2969 + * aCategorySpace.aCategory 2970 + * aCategorySpace.WebHome 2971 + * Blog.aPost or Blog.WebHome 2972 + * 2973 + * @param query The query for selecting blog entries. 2974 + * @param queryParams The parameters to bind with the generated query. 2975 + * @param targetDoc The document in which the articles will be displayed. 2976 + *### 2977 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams) 2978 + #set ($query = $NULL) 2979 + #set ($queryParams = $NULL) 2980 + #getCategoryAllBlogPostsQuery($resultQuery) 2981 + #set ($resultQueryParams = \{}) 2982 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 2983 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 2984 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%' 2985 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space)) 2986 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 2987 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~") 2988 + #elseif($targetDoc.getObject($blogCategoryClassname)) 2989 + ## Get all posts that are in a category aCategorySpace.aCategory 2990 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName)) 2991 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~") 2992 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 2993 + ## Get all posts that are in a category aCategorySpace.% 2994 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 2995 + ## Exclude incategorized posts 2996 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~") 2997 + #if ($targetDoc.space == $defaultBlogSpace) 2998 + #set ($excludedCategory = ~"Blog.Categories.WebHome~") 2999 + #end 3000 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory)) 3001 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~") 3002 + #else 3003 + ## Get all posts in blog space aBlog 3004 + #getAllBlogPostsQuery($resultQuery) 3005 + #getBlogPostsLocation($targetDoc.space $postsLocation) 3006 + #set ($discard = $resultQueryParams.put('space', $postsLocation)) 3007 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~") 3008 + #end 3009 + #setVariable(~"$query~" $resultQuery) 3010 + #setVariable(~"$queryParams~" $resultQueryParams) 3011 +#end 3012 +## 3013 +## 3014 +## 3015 +###** 3016 + * Display blog posts based on the context where the posts are displayed. 3017 + * for example there is 4 different panel contexts: 3018 + * aBlog.aPost or aBlog.WebHome 3019 + * aCategorySpace.aCategory 3020 + * aCategorySpace.WebHome 3021 + * Blog.aPost or Blog.WebHome 3022 + * 3023 + * @param targetDoc The document in which the articles will be displayed. 3024 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ... 3025 + * @param layout Layout of the the posts to display 3026 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN' 3027 + * @param limit the number of posts to display 3028 + *### 3029 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit) 3030 + #if ($postLayout == 'full') 3031 + #set ($macro.paginated = 'yes') 3032 + #end 3033 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 3034 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%' 3035 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout) 3036 + #if (~"$!layout~" == '') 3037 + #set ($layout = $postsLayout) 3038 + #end 3039 + #if ($postsVisiblity == 'recent') 3040 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 3041 + #elseif($postsVisiblity == 'unpublished') 3042 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 3043 + #end 3044 + #elseif($targetDoc.getObject($blogCategoryClassname)) 3045 + ## Display all posts that are in a category aCategorySpace.aCategory 3046 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc) 3047 + #getBlogPostsLayout($blogDoc $postsLayout) 3048 + #if (~"$!layout~" == '') 3049 + #set ($layout = $postsLayout) 3050 + #end 3051 + #if ($postsVisiblity == 'recent') 3052 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 3053 + #elseif($postsVisiblity == 'unpublished') 3054 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 3055 + #end 3056 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 3057 + ## Display all posts that are in a category aCategorySpace.% 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.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 3065 + #elseif($postsVisiblity == 'unpublished') 3066 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 3067 + #end 3068 + #else 3069 + ## Display all posts in blog space aBlog 3070 + #getBlogDocument($targetDoc.space $blogDoc) 3071 + #getBlogPostsLayout($blogDoc $postsLayout) 3072 + #if (~"$!layout~" == '') 3073 + #set ($layout = $postsLayout) 3074 + #end 3075 + #if ($postsVisiblity == 'recent') 3076 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 3077 + #elseif($postsVisiblity == 'unpublished') 3078 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 3079 + #end 3080 + #end 3081 +#end 3082 +## 3083 +## 3084 +## 3085 +#** 3086 + * Bind parameters to a query object. 3087 + * 3088 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object) 3089 + * @param queryParams the query parameters. 3090 + *### 3091 +#macro(bindQueryParameters $queryObj $queryParams) 3092 + #set ($output = $queryObj) 3093 + #foreach( $key in $queryParams.keySet() ) 3094 + #set($output = $queryObj.bindValue($key, $queryParams.get($key))) 3095 + #end 3096 + #setVariable(~"$queryObj~" $output) 3097 +#end 3098 +## 3099 +## 3100 +## 3101 +#** 3102 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail 3103 + * 3104 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt> 3105 + * property set. 3106 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default). 3107 + *### 3108 +#macro(getBlogPostsLayout $blogDoc $postsLayout) 3109 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res) 3110 + #set ($postsLayout = $NULL) 3111 + #setVariable (~"$postsLayout~" $res) 3112 +#end 3113 +## 3114 +## 3115 +## 3116 +#** 3117 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space 3118 + * 3119 + * @param categoriesSpace A <tt>String</tt>, the name of the space. 3120 + * @param blogDoc The resulting XDocument. 3121 + *### 3122 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc) 3123 + #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()) 3124 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace) 3125 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0))) 3126 + #else 3127 + ## Fallback to Blog.WebHome, the default blog 3128 + #set($macro.result = $xwiki.getDocument('Blog.WebHome')) 3129 + #end 3130 + #set ($blogDoc = $NULL) 3131 + #setVariable (~"$blogDoc~" $macro.result) 3132 +#end" %) 3133 +((( 3134 +(% class="macro-placeholder hidden" %) 3135 +((( 3136 +macro:velocity 3137 +))) 3138 +))) 3139 +))) 3140 + 3141 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %) 3142 +((( 3143 +(% class="macro-placeholder hidden" %) 3144 +((( 3145 +macro:include 3146 +))) 3147 + 3148 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#** 3149 + * Extract the layout parameters from a string. 3150 + * 3151 + * @param layoutParamsString The string representation of the layout parameters. 3152 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~" 3153 + * @param layoutsParameters The resulting layout parameters Map. 3154 + *### 3155 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters) 3156 + #set ($layoutsParameters = $NULL) 3157 + #set ($macro.layoutParams = \{}) 3158 + #if (~"$!layoutParamsString~" != '') 3159 + #set ($macro.paramsArr = $layoutParamsString.split('\\|')) 3160 + #foreach ($item in $macro.paramsArr) 3161 + #set ($itemSplit = $item.split('=')) 3162 + #if ($itemSplit.size() == 2) 3163 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim())) 3164 + #end 3165 + #end 3166 + #end 3167 + #setVariable(~"$layoutsParameters~" $macro.layoutParams) 3168 +#end" %) 3169 +((( 3170 +(% class="macro-placeholder hidden" %) 3171 +((( 3172 +macro:velocity 3173 +))) 3174 +))) 3175 +))) 3176 + 3177 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj) 3178 + #initLayoutVars($pDoc $pObj) 3179 + <div class=~"col-xs-12 col-sm-6 next_blog~"> 3180 + <a href=~"$pDoc.uRL~" class=~"thumbnail~"> 3181 + <div class=~"row~"> 3182 + <div class=~"col-xs-4~"> 3183 + #if ($imageAtt) 3184 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 3185 + #end 3186 + </div> 3187 + <div class=~"col-xs-8 art_det~"> 3188 + <p class=~"text-left~"> 3189 + #if($displayTitle)$!postTitle #end 3190 + <br/><span class=~"date_info~"> $!dateStr </span> 3191 + </p> 3192 + #displayPostDetails($pDoc) 3193 + </div> 3194 + </div> 3195 + </a> 3196 + </div> 3197 + #end 3198 + ## 3199 + ## 3200 + ## 3201 + #macro(displayPinnedPost $pDoc $pObj) 3202 + #initLayoutVars($pDoc $pObj) 3203 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~"> 3204 + <a href=~"$pDoc.uRL~" class=~"all-post-link~"> 3205 + <div class=~"thumbnail~"> 3206 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts) 3207 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 3208 + #end 3209 + #if ($imageAtt) 3210 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 3211 + #end 3212 + <div class=~"caption~"> 3213 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts) 3214 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 3215 + #end 3216 + #if ($displaySummaryOnPinnedPosts) 3217 + <div class=~"text-left post-summary~"> 3218 + #set ($postContent = $pObj.getProperty('extract').value) 3219 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString()) 3220 + </div> 3221 + #end 3222 + #displayPostDetails($pDoc) 3223 + </div> 3224 + </div> 3225 + </a> 3226 + </div> 3227 + #end 3228 + ## 3229 + ## 3230 + ## 3231 + #macro(formatPostDate $pDoc $pObj) 3232 + #set ($formattedDate = $NULL) 3233 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale)) 3234 + #if (~"$!dateStr~" != '') 3235 + #set ($dateArr = $dateStr.split(' ')) 3236 + #if ($dateArr.size() > 3) 3237 + #set ($dateStr = ~"~") 3238 + #foreach($s in $dateArr.subList(0, 3)) 3239 + #set ($dateStr = ~"$\{dateStr}$\{s} ~") 3240 + #end 3241 + #end 3242 + #end 3243 + #setVariable(~"$formattedDate~" $dateStr) 3244 + #end 3245 + ## 3246 + ## 3247 + ## 3248 + #macro(displayPostDetails $pDoc) 3249 + <div class=~"row post-details~"> 3250 + <div class=~"col-xs-8 detail~"> 3251 + #if ($services.like.displayButton($pDoc.documentReference)) 3252 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference)) 3253 + ## Retrieve the likes number in XWiki 12.9+ 3254 + #set ($likeNumber = $optLikeRecord.get()) 3255 + #if (!$stringtool.isNumeric($likeNumber.toString())) 3256 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9. 3257 + #set ($likeNumber = $optLikeRecord.get().likeNumber) 3258 + #end 3259 + #if ($stringtool.isNumeric($likeNumber.toString())) 3260 + <div class=~"post-likes btn btn-default disabled badge~" 3261 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~"> 3262 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span> 3263 + </div> 3264 + #end 3265 + #elseif ($services.ratings) 3266 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference)) 3267 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1) 3268 + <ul class=~"pull-left note list-inline~"> 3269 + #foreach ($x in [1..5]) 3270 + #set ($cls = ~"~") 3271 + #if ($x > $averageVote) 3272 + #set ($cls = ~"-o~") 3273 + #end 3274 + <li><span class=~"fa fa-star$\{cls}~"></span></li> 3275 + #end 3276 + </ul> 3277 + #end 3278 + #end 3279 + </div> 3280 + #if ($showPostComments) 3281 + <div class=~"col-xs-4 com_det~"> 3282 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p> 3283 + </div> 3284 + #end 3285 + </div> 3286 + #end 3287 + ## 3288 + ## 3289 + ## 3290 + #macro(initLayoutVars $pDoc $pObj) 3291 + #set ($postTitle = $pDoc.display('title', 'view', $pObj)) 3292 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image'))) 3293 + #isPublished($pObj $isPublished) 3294 + #isHidden($pObj $isHidden) 3295 + #getEntryDate($pDoc $pObj $postDate) 3296 + #formatPostDate($postDate $dateStr) 3297 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote())) 3298 + #set ($nbComments = $pDoc.getComments().size()) 3299 + #set ($showPostComments = true) 3300 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0') 3301 + #set ($showPostComments = false) 3302 + #end 3303 + #end 3304 + ## 3305 + ## 3306 + ## 3307 + #macro(displayEditPinnedPostsButton) 3308 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName)) 3309 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet')) 3310 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet')) 3311 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet')) 3312 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~")) 3313 + <div class=~"edit-pinned-posts-container~"> 3314 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~"> 3315 + <a href=~"javascript:;~" class=~"editPinnedPosts~"> 3316 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit') 3317 + </a> 3318 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/> 3319 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/> 3320 + </div> 3321 + </div> 3322 + #if (~"$!pinnedPostsObj~" == '') 3323 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/> 3324 + #end 3325 + #end 3326 + #end" %) 3327 +((( 3328 +(% class="macro-placeholder hidden" %) 3329 +((( 3330 +macro:velocity 3331 +))) 3332 +))) 3333 + 3334 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference)) 3335 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference)) 3336 + #getEntryObject($postDoc $postObj) 3337 + #if (~"$!postObj~" != '') 3338 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams) 3339 + ## 3340 + #set ($displayTitle = true) 3341 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false') 3342 + #set ($displayTitle = false) 3343 + #end 3344 + ## 3345 + #set ($displayTitleFirstOnPinnedPosts = false) 3346 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true') 3347 + #set ($displayTitleFirstOnPinnedPosts = true) 3348 + #end 3349 + ## 3350 + #set ($displaySummaryOnPinnedPosts = true) 3351 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false') 3352 + #set ($displaySummaryOnPinnedPosts = false) 3353 + #end 3354 + ## 3355 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue()) 3356 + #if ($postIndex == 0) 3357 + #set ($stopBlogPostsDisplay = false) 3358 + #end 3359 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue()) 3360 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards')) 3361 + #set($scaleWidth = 600) 3362 + #set($imgQs=~"width=$scaleWidth~") 3363 + ## Display pinned posts 3364 + ## Get the list of pinned posts 3365 + #set ($pinnedPosts = []) 3366 + #set ($pinnedPostsSourceDoc = $NULL) 3367 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '') 3368 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog'))) 3369 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro 3370 + #end 3371 + #if (~"$!pinnedPostsSourceDoc~" != '') 3372 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass')) 3373 + #if (~"$!pinnedPostsObj~" != '') 3374 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value) 3375 + #if (~"$!orderedPinnedPostsJSON~" != '') 3376 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON)) 3377 + #else 3378 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value) 3379 + #end 3380 + #end 3381 + #if ($postIndex == 0 && $pinnedPosts.size() > 0) 3382 + \{\{html clean=~"false~"}} 3383 + #set ($x = 0) 3384 + #set ($showPinnedPostsButton = true) 3385 + #foreach ($pinnedPost in $pinnedPosts) 3386 + #if ($x == 0) 3387 + <div class=~"row flex-container~"> 3388 + #if ($showPinnedPostsButton) 3389 + #displayEditPinnedPostsButton() 3390 + #set($showPinnedPostsButton = false) 3391 + #end 3392 + #end 3393 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost)) 3394 + #getEntryObject($pinnedPostDoc $pinnedPostObj) 3395 + #if (~"$!pinnedPostObj~" != '') 3396 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj) 3397 + #end 3398 + #set ($x = $mathtool.add($x, 1)) 3399 + #if ($x == 3) 3400 + #set ($x = 0) 3401 + </div> 3402 + #end 3403 + #end 3404 + #if ($mathtool.mod($x, 3) != 0) 3405 + </div> 3406 + #end 3407 + \{\{/html}} 3408 + 3409 + ## If the first post is a pinned post : this means that all the posts are pinned 3410 + ## In this case, avoid displaying the posts again after the pinned posts section. 3411 + #if ($pinnedPosts.contains($xcontext.macro.params.reference)) 3412 + #set ($stopBlogPostsDisplay = true) 3413 + #end 3414 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0) 3415 + 3416 + \{\{html}} 3417 + <div class=~"row no-pinnded-posts~"> 3418 + #displayEditPinnedPostsButton() 3419 + </div> 3420 + \{\{/html}} 3421 + 3422 + #end 3423 + #end 3424 + #if (!$stopBlogPostsDisplay) 3425 + \{\{html clean=~"false~"}} 3426 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0) 3427 + #set ($nbDisplayedPosts = 0) 3428 + #end 3429 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0) 3430 + #if ($nbDisplayedPosts != 0) 3431 + </div> 3432 + #set ($lastHtmlTag = 'c') 3433 + #end 3434 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 3435 + <div class=~"row~"> 3436 + #set ($lastHtmlTag = 'o') 3437 + #set ($lastRowClass = ~"~") 3438 + #else 3439 + <div class=~"row flex-container~"> 3440 + #set ($lastHtmlTag = 'o') 3441 + #set ($lastRowClass = ~"flex~") 3442 + #end 3443 + #end 3444 + #displaySmallPost($postDoc $postObj) 3445 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 3446 + </div> 3447 + #set ($lastHtmlTag = 'c') 3448 + #end 3449 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1)) 3450 + #if ($postIndex == $mathtool.sub($listResultsCount, 1)) 3451 + #if (~"$!lastHtmlTag~" == 'o') 3452 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~") 3453 + <div class=~"col-xs-12 col-sm-6~"></div> 3454 + #end 3455 + </div> 3456 + #end 3457 + #end 3458 + \{\{/html}} 3459 + #end 3460 + #else 3461 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}} 3462 + #end 3463 + #else 3464 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}} 3465 + #end" %) 3466 +((( 3467 +(% class="macro-placeholder hidden" %) 3468 +((( 3469 +macro:velocity 3470 +))) 3471 + 3472 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"col-xs-12 col-sm-6 next_blog~"> 3473 +<a href=~"/Nieuws/Audit%20BMI%20en%20BORG~" class=~"thumbnail~"> 3474 +<div class=~"row~"> 3475 +<div class=~"col-xs-4~"> 3476 +<img src=~"/download/Nieuws/Audit%20BMI%20en%20BORG/giphy.gif?width=600&rev=1.1~" /> 3477 +</div> 3478 +<div class=~"col-xs-8 art_det~"> 3479 +<p class=~"text-left~"> 3480 +Audit BMI en BORG <br/><span class=~"date_info~"> 15 jan. 2024 </span> 3481 +</p> 3482 +<div class=~"row post-details~"> 3483 +<div class=~"col-xs-8 detail~"> 3484 +<div class=~"post-likes btn btn-default disabled badge~" 3485 +title=~"Number of likes on this page: 0~"> 3486 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">0</span> 3487 +</div> 3488 +</div> 3489 +<div class=~"col-xs-4 com_det~"> 3490 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p> 3491 +</div> 3492 +</div> 3493 +</div> 3494 +</div> 3495 +</a> 3496 +</div>" %) 3497 +((( 3498 +(% class="macro-placeholder hidden" %) 3499 +((( 3500 +macro:html 3501 +))) 3502 + 3503 +(% class="col-xs-12 col-sm-6 next_blog" %) 3504 +((( 3505 +(% class="row" %) 3506 +((( 3507 +(% class="col-xs-4" %) 3508 +((( 3509 +[[~[~[image:/download/Nieuws/Audit%20BMI%20en%20BORG/giphy.gif?width=600&rev=1.1~]~]>>path:/Nieuws/Audit%20BMI%20en%20BORG||class="thumbnail"]] 3510 +))) 3511 + 3512 +(% class="col-xs-8 art_det" %) 3513 +((( 3514 +(% class="text-left" %) 3515 +[[Audit BMI en BORG 3516 +(% class="date_info" %) 15 jan. 2024>>path:/Nieuws/Audit%20BMI%20en%20BORG||class="thumbnail"]] 3517 + 3518 +(% class="row post-details" %) 3519 +((( 3520 +(% class="col-xs-8 detail" %) 3521 +((( 3522 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 0" %) 3523 +((( 3524 +[[(% class="like-number" %)0>>path:/Nieuws/Audit%20BMI%20en%20BORG||class="thumbnail"]] 3525 +))) 3526 +))) 3527 + 3528 +(% class="col-xs-4 com_det" %) 3529 +((( 3530 +(% class="text-right" %) 3531 +[[(0)>>path:/Nieuws/Audit%20BMI%20en%20BORG||class="thumbnail"]] 3532 +))) 3533 +))) 3534 +))) 3535 +))) 3536 +))) 3537 +))) 3538 +))) 3539 +))) 3540 + 3541 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Nieuwsbrief december 2023~" params=~"displayTitle=true|useSummary=true|list-limit=6|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=6|postIndex=0|previousPostReference=|postIndex=1|previousPostReference=Nieuws.Nieuwsbrief januari 2024|postIndex=2|previousPostReference=Nieuws.Audit BMI en BORG~"" %) 3542 +((( 3543 +(% class="macro-placeholder hidden" %) 3544 +((( 3545 +macro:blogPostLayoutCards 3546 +))) 3547 + 3548 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %) 3549 +((( 3550 +(% class="macro-placeholder hidden" %) 3551 +((( 3552 +macro:include 3553 +))) 3554 + 3555 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %) 3556 +((( 3557 +(% class="macro-placeholder hidden" %) 3558 +((( 3559 +macro:include 3560 +))) 3561 + 3562 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog 3563 +#set($blogClassname = 'Blog.BlogClass') 3564 +#set($blogTemplate = 'Blog.BlogTemplate') 3565 +#set($blogSheet = 'Blog.BlogSheet') 3566 +## Blog entries 3567 +#set($blogPostClassname = 'Blog.BlogPostClass') 3568 +#set($blogPostTemplate = 'Blog.BlogPostTemplate') 3569 +#set($blogPostSheet = 'Blog.BlogPostSheet') 3570 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number) 3571 +#set($oldArticleClassname = 'XWiki.ArticleClass') 3572 +## Categories 3573 +#set($blogCategoryClassname = 'Blog.CategoryClass') 3574 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate') 3575 +#set($blogCategorySheet = 'Blog.CategorySheet') 3576 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet') 3577 +#set($oldBlogCategoryClassname = 'Blog.Categories') 3578 +#set($defaultCategoryParent = 'Blog.Categories') 3579 +## Style 3580 +#set($blogStyleDocumentName = 'Blog.BlogStyle') 3581 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName)) 3582 +## Clientside scripts 3583 +#set($blogScriptsDocumentName = 'Blog.BlogScripts') 3584 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher')) 3585 +## Misc 3586 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString)) 3587 +#set($isBlogPost = $doc.getObject($blogPostClassname)) 3588 +#set($defaultBlogSpace = 'Blog') 3589 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname)) 3590 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 3591 +## 3592 +## 3593 +## 3594 +#** 3595 + * Displays an image, taken from the blog style document. 3596 + * 3597 + * @param $imgName The name of the icon from icons set to use. 3598 + *# 3599 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %) 3600 +((( 3601 +(% class="macro-placeholder hidden" %) 3602 +((( 3603 +macro:velocity 3604 +))) 3605 +))) 3606 +))) 3607 + 3608 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## 3609 +## 3610 +## 3611 +## Import the blog skin and javascripts. 3612 +$!xwiki.ssx.use($blogStyleDocumentName)## 3613 +$!xwiki.jsx.use($blogScriptsDocumentName)## 3614 +## 3615 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation) 3616 +#template('hierarchy_macros.vm')## 3617 +## 3618 +## 3619 +#** 3620 + * Prints a blog. This is the main macro used in the BlogSheet. 3621 + * 3622 + * @param blogDoc the XDocument holding the blog definition object. 3623 + *### 3624 +#macro(printBlog $blogDoc) 3625 + \{\{include reference='Blog.CreatePost'/}} 3626 + 3627 + ## Use the blogPostList macro to display the blogposts 3628 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro 3629 + ## do not support FTM the monthly and weekly blog display types 3630 + #getBlogDisplayType($blogDoc $displayType) 3631 + #if ($displayType == 'weekly' || $displayType == 'monthly') 3632 + #getBlogEntries($blogDoc $entries) 3633 + #displayBlog($entries 'index' true true) 3634 + #displayNavigationLinks($blogDoc) 3635 + #else 3636 + #getBlogDisplayType($blogDoc $displayType) 3637 + #set ($paginated = 'no') 3638 + #if ($displayType == 'paginated') 3639 + #set ($paginated = 'yes') 3640 + #end 3641 + #getBlogPostsLayout($blogDoc $postsLayout) 3642 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}}))) 3643 + #end 3644 +#end 3645 +## 3646 +## 3647 +## 3648 +#** 3649 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title, 3650 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index, 3651 + * all entries). 3652 + * 3653 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 3654 + *### 3655 +#macro(showBlogInfo $blogDoc) 3656 + #if($blogDoc.getObject($blogClassname)) 3657 + ## Keep testing for inline action for backward compatibility with older blogs. 3658 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline') 3659 + #macro(displayProperty $blogDoc $propname) 3660 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)): 3661 + : $blogDoc.display($propname) 3662 + #end 3663 + #displayProperty($blogDoc 'title') 3664 + #displayProperty($blogDoc 'description') 3665 + #displayProperty($blogDoc 'displayType') 3666 + #displayProperty($blogDoc 'itemsPerPage') 3667 + #displayProperty($blogDoc 'postsLayout') 3668 + #displayProperty($blogDoc 'postsLayoutParameters') 3669 + #else 3670 + $blogDoc.display('description') 3671 + #end 3672 + #elseif($doc.fullName == $blogSheet) 3673 += $services.localization.render('blog.code.blogsheet') = 3674 + \{\{translation key='blog.code.sheetexplanation'/}} 3675 + #else 3676 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}} 3677 + #end 3678 +#end 3679 +## 3680 +## 3681 +## 3682 +#** 3683 + * Retrieve the blog document, which usually is either <tt><Space>.WebHome</tt> for whole-spaces blogs, or 3684 + * <tt><Space>.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first 3685 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current 3686 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog. 3687 + * 3688 + * @param space A <tt>String</tt>, the name of the space where to search. 3689 + * @param blogDoc The resulting XDocument. 3690 + *### 3691 +#macro(getBlogDocument $space $blogDoc) 3692 + #set ($result = $NULL) 3693 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object. 3694 + ## 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 3695 + ## identify the right blog based on a configuration object in a WebPreferences page. 3696 + #set ($spaceReference = $services.model.resolveSpace($space)) 3697 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference)) 3698 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef)) 3699 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass')) 3700 + #if ($preferencesObj) 3701 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog'))) 3702 + #end 3703 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy. 3704 + #if (~"$!result~" == '') 3705 + ## First, try the Space.WebHome, for a whole-space blog 3706 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~")) 3707 + #if(!$result.getObject($blogClassname)) 3708 + ## Second, try the Space.Blog document 3709 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~")) 3710 + #if(!$result.getObject($blogClassname)) 3711 + ## Third, try searching for a blog document in the current space 3712 + ## Prevent the query fail when the space contains dots '.' 3713 + #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()) 3714 + #if($blogDocs.size() > 0) 3715 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 3716 + #else 3717 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space 3718 + #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()) 3719 + #if($blogDocs.size() > 0) 3720 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 3721 + #else 3722 + ## Last, fallback to Blog.WebHome, the default blog 3723 + #set($result = $xwiki.getDocument('Blog.WebHome')) 3724 + #end 3725 + #end 3726 + #end 3727 + #end 3728 + #end 3729 + #set ($blogDoc = $NULL) 3730 + #setVariable (~"$blogDoc~" $result) 3731 +#end 3732 +## 3733 +## 3734 +## 3735 +#** 3736 + * Retrieve the blog title. 3737 + * 3738 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set. 3739 + * @param title The resulting title. 3740 + *### 3741 +#macro(getBlogTitle $blogDoc $title) 3742 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them. 3743 + #set ($title = $NULL) 3744 + #setVariable (~"$title~" $!blogDoc.displayTitle) 3745 +#end 3746 +## 3747 +## 3748 +## 3749 +#** 3750 + * Retrieve the blog description. 3751 + * 3752 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt> 3753 + * property set. 3754 + * @param description The resulting description. 3755 + *### 3756 +#macro(getBlogDescription $blogDoc $description) 3757 + #getBlogProperty($blogDoc 'description' '' $result) 3758 + #set ($description = $NULL) 3759 + #setVariable (~"$description~" $result) 3760 +#end 3761 +## 3762 +## 3763 +## 3764 +#** 3765 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog 3766 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on 3767 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a 3768 + * month), or all. 3769 + * 3770 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 3771 + * @param entries The resulting list of entries to display, a list of XDocument names. 3772 + *### 3773 +#macro(getBlogEntries $blogDoc $entries) 3774 + #if (!$entries) 3775 + #setVariable (~"$entries~" []) 3776 + #end 3777 + #getAllBlogPostsQuery($query) 3778 + #isDefaultBlog($blogDoc $isDefault) 3779 + #set($queryParams = \{}) 3780 + #if ($isDefault) 3781 + #getCategoryAllBlogPostsQuery($query) 3782 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~") 3783 + #set($discard = $queryParams.put('creator', $xcontext.user)) 3784 + #set($discard = $queryParams.put('space', $blogDoc.space)) 3785 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 3786 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace)) 3787 + #else 3788 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~") 3789 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation) 3790 + #set($discard = $queryParams.put('space', $blogPostsLocation)) 3791 + #set($discard = $queryParams.put('parent', $blogDoc.space)) 3792 + #end 3793 + #getBlogDisplayType($blogDoc $displayType) 3794 + #if($displayType == 'weekly') 3795 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams) 3796 + #elseif($displayType == 'monthly') 3797 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams) 3798 + #elseif($displayType == 'all') 3799 + #getAllBlogEntries($blogDoc $query $entries $queryParams) 3800 + #else 3801 + #getPagedBlogEntries($blogDoc $query $entries $queryParams) 3802 + #end 3803 +#end 3804 +## 3805 +## 3806 +## 3807 +#** 3808 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents 3809 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the 3810 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property 3811 + * (10 if not defined). 3812 + * 3813 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 3814 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 3815 + * refined to restrict to a given space, or to a given search criteria, etc. 3816 + * @param entries The resulting list of entries to display, a list of XDocument names. 3817 + * @param queryParams The parameters to bind with the query. 3818 + *### 3819 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams) 3820 + #if (!$entries) 3821 + #setVariable (~"$entries~" []) 3822 + #end 3823 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 3824 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~")) 3825 + #bindQueryParameters($countQueryObj $queryParams) 3826 + #bindQueryParameters($queryObj $queryParams) 3827 + #set($totalEntries = $countQueryObj.count()) 3828 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage) 3829 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue()) 3830 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 3831 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 3832 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute())) 3833 +#end 3834 +## 3835 +## 3836 +## 3837 +#** 3838 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is 3839 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4 3840 + * digit year). Initially the current week is displayed. 3841 + * 3842 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 3843 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 3844 + * refined to restrict to a given space, or to a given search criteria, etc. 3845 + * @param entries The resulting list of entries to display, a list of XDocument names. 3846 + * @param queryParams The parameters to bind with the query. 3847 + *### 3848 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams) 3849 + #if (!$entries) 3850 + #setVariable (~"$entries~" []) 3851 + #end 3852 + #getRequestedWeek($weekDate) 3853 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 3854 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor())) 3855 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling())) 3856 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 3857 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 3858 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 3859 + #bindQueryParameters($countQueryObj $queryParams) 3860 + #bindQueryParameters($queryObj $queryParams) 3861 + #set($totalEntries = $countQueryObj.count()) 3862 + #set($discard = $entries.addAll($queryObj.execute())) 3863 +#end 3864 +## 3865 +## 3866 +## 3867 +#** 3868 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is 3869 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4 3870 + * digit year). Initially the current month is displayed. 3871 + * 3872 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 3873 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 3874 + * refined to restrict to a given space, or to a given search criteria, etc. 3875 + * @param entries The resulting list of entries to display, a list of XDocument names. 3876 + * @param queryParams The parameters to bind with the query. 3877 + *### 3878 +#macro(getMonthlyBlogEntries $blogDoc $query $entries) 3879 + #if (!$entries) 3880 + #setVariable (~"$entries~" []) 3881 + #end 3882 + #getRequestedMonth($monthDate) 3883 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 3884 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor())) 3885 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling())) 3886 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 3887 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 3888 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 3889 + #bindQueryParameters($countQueryObj $queryParams) 3890 + #bindQueryParameters($queryObj $queryParams) 3891 + #set($totalEntries = $countQueryObj.count()) 3892 + #set($discard = $entries.addAll($queryObj.execute())) 3893 +#end 3894 +## 3895 +## 3896 +## 3897 +#** 3898 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned. 3899 + * 3900 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 3901 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 3902 + * refined to restrict to a given space, or to a given search criteria, etc. 3903 + * @param entries The resulting list of entries to display, a list of XDocument names. 3904 + * @param queryParams The parameters to bind with the query. 3905 + *### 3906 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams) 3907 + #if (!$entries) 3908 + #setVariable (~"$entries~" []) 3909 + #end 3910 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 3911 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 3912 + #bindQueryParameters($countQueryObj $queryParams) 3913 + #bindQueryParameters($queryObj $queryParams) 3914 + #set($totalEntries = $countQueryObj.count()) 3915 + #set($discard = $entries.addAll($queryObj.execute())) 3916 +#end 3917 +## 3918 +## 3919 +## 3920 +#** 3921 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned. 3922 + * 3923 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 3924 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 3925 + * refined to restrict to a given space, or to a given search criteria, etc. 3926 + * @param queryParams The parameters to bind with the query. 3927 + * @param entries The resulting list of entries to display, a list of XDocument names. 3928 + *### 3929 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries) 3930 + #if (!$entries) 3931 + #setVariable (~"$entries~" []) 3932 + #end 3933 + #set($query = ~"$\{query} and isPublished.value = 0~") 3934 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 3935 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 3936 + #bindQueryParameters($countQueryObj $queryParams) 3937 + #bindQueryParameters($queryObj $queryParams) 3938 + #set($totalEntries = $countQueryObj.count()) 3939 + #set($discard = $entries.addAll($queryObj.execute())) 3940 +#end 3941 +## 3942 +## 3943 +## 3944 +#** 3945 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog. 3946 + * 3947 + * @param entries The resulting list of entries to display, a list of XDocument names. 3948 + *### 3949 +#macro(getGlobalBlogEntries $entries) 3950 + #if (!$entries) 3951 + #setVariable (~"$entries~" []) 3952 + #end 3953 + #getAllBlogPostsQuery($query) 3954 + #set($totalEntries = $services.query.hql($query).count()) 3955 + #set($defaultItemsPerPage = 20) 3956 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 3957 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 3958 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute())) 3959 +#end 3960 +#** 3961 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific 3962 + * blog, nor specify a range or an ordering criteria. 3963 + * 3964 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code. 3965 + * 3966 + * @param query The basic query for selecting blog entries. 3967 + *# 3968 +#macro(getBlogEntriesBaseQuery $query) 3969 + #getAllBlogPostsQuery($query) 3970 +#end 3971 +#** 3972 + * Return the Query for selecting the all wiki blog posts without filtering 3973 + * 3974 + * @param query The basic query for selecting blog entries. 3975 + *# 3976 +#macro(getAllBlogPostsQuery $query) 3977 + #set ($query = $NULL) 3978 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished, 3979 + IntegerProperty hidden, DateProperty publishDate 3980 + where doc.fullName <> '$blogPostTemplate' and 3981 + obj.name=doc.fullName and obj.className='$blogPostClassname' and 3982 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and 3983 + hidden.id.id = obj.id and hidden.id.name='hidden' and 3984 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and 3985 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~") 3986 +#end 3987 +## 3988 +## 3989 +## 3990 +###** 3991 + * Return the Query for selecting the all wiki blog posts with categories filtering 3992 + * 3993 + * @param query The basic query for selecting blog entries. 3994 + *### 3995 +#macro(getCategoryAllBlogPostsQuery $query) 3996 + #set ($query = $NULL) 3997 + #getAllBlogPostsQuery($baseQuery) 3998 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList')) 3999 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~") 4000 +#end 4001 +## 4002 +## 4003 +## 4004 +#** 4005 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a 4006 + * week), monthly (all entries in a month), or all. 4007 + * 4008 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt> 4009 + * property set. 4010 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated. 4011 + *### 4012 +#macro(getBlogDisplayType $blogDoc $displayType) 4013 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result) 4014 + #set ($displayType = $NULL) 4015 + #setVariable (~"$displayType~" $result) 4016 +#end 4017 +## 4018 +## 4019 +## 4020 +#** 4021 + * Displays a list of entries. 4022 + * 4023 + * @param entries The entries to display, a list of XDocument names. 4024 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results, 4025 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently 4026 + * used values: index, single, category, search, unpublished, hidden. 4027 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content. 4028 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're 4029 + * displayed alone on their page since it's the page title which is used in this case) 4030 + *### 4031 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles) 4032 + #set($blogDay = '') 4033 + (% class=~"hfeed $!\{displaying}~" ~%)((( 4034 + (% class=~"blogDay~" ~%)((( 4035 + #foreach ($entryDoc in $xwiki.wrapDocs($entries)) 4036 + #getEntryObject($entryDoc $entryObj) 4037 + ## Although all entries should have one of the two objects, better check to be sure. 4038 + #if(~"$!\{entryObj}~" != '') 4039 + #getEntryDate($entryDoc $entryObj $entryDate) 4040 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet. 4041 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd')) 4042 + #if($blogDay != $entryDateStr) 4043 + #if($blogDay != '') 4044 + ))) 4045 + (% class=~"blogDay~" ~%)((( 4046 + #end 4047 + #displayBlogDate($entryDate) 4048 + #set ($blogDay = $entryDateStr) 4049 + #end 4050 + ## Finally, display the entry. 4051 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true) 4052 + #end 4053 + #end 4054 + )))## blogDay 4055 + )))## hfeed 4056 +#end 4057 +## 4058 +## 4059 +## 4060 +#** 4061 + * Get the entry object, either a new BlogPost or an old Article. 4062 + * 4063 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4064 + * @param entryObj The resulting xobject of the blog post. 4065 + *### 4066 +#macro(getEntryObject $entryDoc $__entryObj) 4067 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~")) 4068 + #if(!$result) 4069 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~")) 4070 + #end 4071 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from 4072 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be 4073 + ## overwritten in this case but it's less likely to have such a variable defined before. 4074 + #set ($__entryObj = $NULL) 4075 + #setVariable (~"$__entryObj~" $result) 4076 +#end 4077 +## 4078 +## 4079 +## 4080 +#** 4081 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is 4082 + * the document creation date, but can be edited by the user. 4083 + * 4084 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4085 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4086 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>. 4087 + *### 4088 +#macro(getEntryDate $entryDoc $entryObj $result) 4089 + #set ($result = $NULL) 4090 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value) 4091 +#end 4092 +## 4093 +## 4094 +## 4095 +#** 4096 + * Displays a date, nicely formatted as a calendar page. 4097 + * 4098 + * @param date The date to display, an instance of <tt>java.util.Date</tt>. 4099 + *### 4100 +#macro(displayBlogDate $date) 4101 + #set($year = $xwiki.formatDate($date, 'yyyy')) 4102 + ## 3 letter month name, like Jan, Dec. 4103 + #set($month = $xwiki.formatDate($date, 'MMM')) 4104 + ## Uncomment to get a full length month name, like January, December. 4105 + ## TODO: this could be defined somewhere in the blog style. 4106 + ## #set($month = $xwiki.formatDate($date, 'MMMM')) 4107 + #set($day = $xwiki.formatDate($date, 'dd')) 4108 + (% class=~"blogdate~" ~%) 4109 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) == 4110 +#end 4111 +## 4112 +## 4113 +## 4114 +#** 4115 + * Displays a blog article: management tools, header, content, footer. 4116 + * 4117 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4118 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4119 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 4120 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title 4121 + * when they're displayed alone on their page since it's the page title which is used in this case) 4122 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons 4123 + *### 4124 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions) 4125 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden 4126 + #isPublished($entryObj $isPublished) 4127 + #isHidden($entryObj $isHidden) 4128 + #if($doc.fullName == $entryDoc.fullName) 4129 + (% class=~"hentry single-article~" ~%)((( 4130 + #else 4131 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)((( 4132 + #end 4133 + #if ($shouldDisplayActions) 4134 + #displayEntryTools($entryDoc $entryObj) 4135 + #end 4136 + #if($shouldDisplayTitle) 4137 + #displayEntryTitle($entryDoc $entryObj) 4138 + #end 4139 + #if($doc.fullName == $entryDoc.fullName) 4140 + #if(!$isPublished) 4141 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}} 4142 + #elseif($isHidden) 4143 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}} 4144 + #end 4145 + #end 4146 + #displayEntryContent($entryDoc $entryObj $onlyExtract) 4147 + #displayEntryFooter($entryDoc $entryObj) 4148 + )))## hentry 4149 +#end 4150 +## 4151 +## 4152 +## 4153 +#** 4154 + * Checks if the provided blog is published or not. 4155 + * 4156 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4157 + * @param isPublished The resulting boolean, true if the entry is considered published. 4158 + *### 4159 +#macro(isPublished $entryObj $isPublished) 4160 + #set ($isPublished = $NULL) 4161 + ## This should work for both old articles, which don't have the 'published' property at all, and 4162 + ## are considered published by default, and new entries, that should have 1 if published. 4163 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0') 4164 + #setVariable (~"$isPublished~" true) 4165 + #else 4166 + #setVariable (~"$isPublished~" false) 4167 + #end 4168 +#end 4169 +## 4170 +## 4171 +## 4172 +#** 4173 + * Checks if the provided blog is hidden or not. 4174 + * 4175 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass. 4176 + * @param isHiddel The resulting boolean, true if the entry is considered hidden. 4177 + *### 4178 +#macro(isHidden $entryObj $isHidden) 4179 + #set ($isHidden = $NULL) 4180 + ## This should work for both old articles, which don't have the 'hidden' property at all, and 4181 + ## are considered visible by default, and new entries, that should have 1 if hidden. 4182 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1') 4183 + #setVariable (~"$isHidden~" true) 4184 + #else 4185 + #setVariable (~"$isHidden~" false) 4186 + #end 4187 +#end 4188 +## 4189 +## 4190 +## 4191 +#** 4192 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit. 4193 + * 4194 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4195 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4196 + *### 4197 +#macro(displayEntryTools $entryDoc $entryObj) 4198 + #if($xcontext.action == 'view') 4199 + (% class=~"blog-entry-toolbox~" ~%)((( 4200 + #displayPublishButton($entryDoc $entryObj) 4201 + #displayHideShowButton($entryDoc $entryObj) 4202 + #displayEditButton($entryDoc $entryObj) 4203 + #displayDeleteButton($entryDoc $entryObj) 4204 + ))) 4205 + #end 4206 +#end 4207 +## 4208 +## 4209 +## 4210 +#** 4211 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet. 4212 + * 4213 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4214 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4215 + * @todo AJAX calls. 4216 + *### 4217 +#macro(displayPublishButton $entryDoc $entryObj) 4218 + #isPublished($entryObj $isPublished) 4219 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 4220 + [[#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')~"]]## 4221 + #end 4222 +#end 4223 +## 4224 +## 4225 +## 4226 +#** 4227 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published. 4228 + * 4229 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4230 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4231 + *### 4232 +#macro(displayHideShowButton $entryDoc $entryObj) 4233 + #isPublished($entryObj $isPublished) 4234 + #isHidden($entryObj $isHidden) 4235 + ## Only published articles can be hidden. Unpublished articles are considered already hidden. 4236 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 4237 + #set ($queryString = \{ 4238 + 'xredirect' : $thisURL, 4239 + 'form_token' : $services.csrf.getToken() 4240 + }) 4241 + #if ($isHidden) 4242 + #set ($discard = $queryString.putAll(\{ 4243 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0, 4244 + 'comment' : $services.localization.render('blog.code.madevisible') 4245 + })) 4246 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 4247 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]## 4248 + #else 4249 + #set ($discard = $queryString.putAll(\{ 4250 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1, 4251 + 'comment' : $services.localization.render('blog.code.hid') 4252 + })) 4253 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 4254 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]## 4255 + #end 4256 + #end 4257 +#end 4258 +## 4259 +## 4260 +## 4261 +#** 4262 + * Displays the edit button to those that can edit the article. 4263 + * 4264 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4265 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4266 + *### 4267 +#macro(displayEditButton $entryDoc $entryObj) 4268 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 4269 + ## Call getDefaultEditMode() for backward compatibility with older blog posts. 4270 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]## 4271 + #end 4272 +#end 4273 +## 4274 +## 4275 +## 4276 +#** 4277 + * Displays the delete button to those that can edit the article. 4278 + * 4279 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4280 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4281 + * @todo AJAX calls. 4282 + *### 4283 +#macro(displayDeleteButton $entryDoc $entryObj) 4284 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName)) 4285 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]## 4286 + #end 4287 +#end 4288 +## 4289 +## 4290 +## 4291 +#** 4292 + * Displays the title of the entry. 4293 + * 4294 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4295 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4296 + *### 4297 +#macro(displayEntryTitle $entryDoc $entryObj) 4298 + #if($doc.fullName == $entryDoc.fullName) 4299 + (% class=~"entry-title~" ~%) 4300 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) = 4301 + #else 4302 + (% class=~"entry-title~" ~%) 4303 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] === 4304 + #end 4305 +#end 4306 +## 4307 +## 4308 +## 4309 +#** 4310 + * Displays the body of the entry. 4311 + * 4312 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4313 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4314 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 4315 + *### 4316 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract) 4317 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)((( 4318 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent) 4319 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328 4320 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content 4321 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}} 4322 + ))) ## entry-content 4323 + (% class=~"clearfloats~" ~%)((())) 4324 +#end 4325 +## 4326 +## 4327 +## 4328 +#** 4329 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content 4330 + * of the <tt>extract</tt> field (if not empty). 4331 + * 4332 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4333 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4334 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 4335 + * @param entryContent The resulting content. 4336 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when 4337 + * <tt>onlyExtract</tt> is <tt>true</tt>) 4338 + *### 4339 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis) 4340 + #if ($onlyExtract) 4341 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead 4342 + ## of the content. 4343 + #set ($macro.result = $entryObj.getProperty('extract').value.trim()) 4344 + #end 4345 + #if(~"$!macro.result~" == '') 4346 + #set($macro.result = $entryObj.getProperty('content').value) 4347 +#* Disabled until the content can be cleanly cut. 4348 +* #if($onlyExtract && $result.length()>$maxchars) 4349 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars)) 4350 +* #set($i = $i + 1) 4351 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~") 4352 +* #end 4353 +## *### 4354 + #elseif (!$removeEllipsis) 4355 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0') 4356 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~") 4357 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1') 4358 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~") 4359 + #end 4360 + #end 4361 + #set ($entryContent = $NULL) 4362 + #setVariable (~"$entryContent~" $macro.result) 4363 +#end 4364 +## 4365 +## 4366 +## 4367 +#** 4368 + * Displays the footer of the entry. 4369 + * 4370 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4371 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4372 + *### 4373 +#macro(displayEntryFooter $entryDoc $entryObj) 4374 + (% class=~"entry-footer~" ~%)((( 4375 + #isPublished($entryObj $isPublished) 4376 + (% class='entry-author-label' ~%) 4377 + #if($isPublished) 4378 + \{\{translation key='blog.code.postedby'/}} ## 4379 + #else 4380 + \{\{translation key='blog.code.createdby'/}} ## 4381 + #end 4382 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ## 4383 + #getEntryDate($entryDoc $entryObj $entryDate) 4384 + #listCategories($entryObj) #* 4385 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that 4386 + ## we assume cannot be more than 3 seconds. 4387 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ## 4388 + #if ($showcomments) 4389 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ## 4390 + #end ## 4391 + #if($entryDoc != $doc) ## 4392 + #displayEntryBlogLocation($entryDoc $entryObj) ## 4393 + #end 4394 + )))## entry-footer 4395 +#end 4396 +## 4397 +## 4398 +#** 4399 + * Display the blog for the entry (if it is not the currently displayed blog) 4400 + * 4401 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 4402 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4403 + *### 4404 +#macro(displayEntryBlogLocation $entryDoc $entryObj) 4405 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ## 4406 + #if(~"$!blogPostsLocation~" != ~"~") ## 4407 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ## 4408 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ## 4409 + #if($doc.documentReference != $blogDocRef) ## 4410 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ## 4411 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ## 4412 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ## 4413 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ## 4414 + )))(%~%)## 4415 + #end 4416 + #end 4417 + #end 4418 +#end 4419 +## 4420 +## 4421 +## 4422 +## 4423 +#** 4424 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>. 4425 + * 4426 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 4427 + *### 4428 +#macro(listCategories $entryObj) 4429 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname) 4430 + #set($categories = $entryObj.getProperty('category').value) 4431 + #set($first = true) 4432 + #if($categories.size() > 0) 4433 + #foreach($category in $categories) 4434 + #set($categoryDoc = $!xwiki.getDocument($category)) 4435 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname})) 4436 + #if($foreach.count == 1) 4437 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ## 4438 + #else 4439 + , ## 4440 + #end## 4441 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]## 4442 + #end## 4443 + #end## 4444 + #end 4445 + #end 4446 +#end 4447 +## 4448 +## 4449 +## 4450 +#** 4451 + * Displays blog pagination links (older and newer entries). 4452 + * 4453 + * @param blogDoc the XDocument holding the blog definition object. 4454 + *### 4455 +#macro(displayNavigationLinks $blogDoc) 4456 + (% class=~"clearfloats~" ~%)((())) 4457 + #getBlogDisplayType($blogDoc $displayType) 4458 + #if($displayType == 'weekly') 4459 + (% class=~"pagingLinks~" ~%)((( 4460 + #getRequestedWeek($weekDate) 4461 + $weekDate.addWeeks(-1)## 4462 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 4463 + #sep() 4464 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above 4465 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 4466 + ))) 4467 + #elseif($displayType == 'monthly') 4468 + (% class=~"pagingLinks~" ~%)((( 4469 + #getRequestedMonth($monthDate) 4470 + $monthDate.addMonths(-1)## 4471 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 4472 + #sep() 4473 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above 4474 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 4475 + ))) 4476 + #elseif($displayType == 'all') 4477 + #else 4478 + ## Paginated 4479 + #if(($totalPages > 1)) 4480 + #set($queryString = '') 4481 + #foreach($p in $request.getParameterNames()) 4482 + #if($p != 'page' && $p != 'ipp') 4483 + #foreach($v in $request.getParameterValues($p)) 4484 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~") 4485 + #end 4486 + #end 4487 + #end 4488 + (% class=~"pagingLinks~" ~%)((( 4489 + #if ($currentPageNumber < $totalPages) 4490 + #set($currentPageNumber = $currentPageNumber + 1) 4491 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 4492 + #set($currentPageNumber = $currentPageNumber - 1) 4493 + #end 4494 + #if ($currentPageNumber > 1) 4495 + #if ($currentPageNumber < $totalPages) 4496 + #sep() 4497 + #end 4498 + #set($currentPageNumber = $currentPageNumber - 1) 4499 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 4500 + #set($currentPageNumber = $currentPageNumber + 1) 4501 + #end 4502 + (% class=~"clear~" ~%)(%~%) 4503 + )))## pagingLinks 4504 + #end 4505 + #end 4506 +#end 4507 +## 4508 +## 4509 +## 4510 +#** 4511 + * Displays a message box with ~"publish~" icon. 4512 + * 4513 + * @param message A text message concerning blog article publishing 4514 + *### 4515 +#macro(publishMessageBox $message) 4516 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message))) 4517 +#end 4518 +#** 4519 + * Displays a message box with ~"show/hide~" icon. 4520 + * 4521 + * @param message A text message concerning blog article hiding 4522 + *### 4523 +#macro(hideMessageBox $message) 4524 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message))) 4525 +#end 4526 +## 4527 +## 4528 +## 4529 +#** 4530 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are 4531 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used. 4532 + * 4533 + * @param monthDate The resulting week, a JODATime MutableDateTime. 4534 + *### 4535 +#macro(getRequestedWeek $weekDate) 4536 + #set ($weekDate = $NULL) 4537 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime) 4538 + #if(~"$!\{request.year}~" != '') 4539 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue())) 4540 + #end 4541 + #if(~"$!\{request.week}~" != '') 4542 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue())) 4543 + #end 4544 +#end 4545 +## 4546 +## 4547 +## 4548 +#** 4549 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are 4550 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used. 4551 + * 4552 + * @param monthDate The resulting month, a JODATime MutableDateTime. 4553 + *### 4554 +#macro(getRequestedMonth $monthDate) 4555 + #set ($monthDate = $NULL) 4556 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime) 4557 + #if(~"$!\{request.year}~" != '') 4558 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue())) 4559 + #end 4560 + #if(~"$!\{request.month}~" != '') 4561 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue())) 4562 + #end 4563 +#end 4564 +## 4565 +## 4566 +## 4567 +#** 4568 + * Retrieve a blog property (title, display type, etc). 4569 + * 4570 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 4571 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties. 4572 + * @param defaultValue The default value to use in case the blog object does not define one. 4573 + * @param propertyValue The resulting value. 4574 + *### 4575 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue) 4576 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~") 4577 + #if($result == '') 4578 + #set($result = $defaultValue) 4579 + #end 4580 + #set ($propertyValue = $NULL) 4581 + #setVariable (~"$propertyValue~" $result) 4582 +#end 4583 + 4584 +#** 4585 + * If an error occurs when executing an action, set a specific response status and display an error message. 4586 + * 4587 + * @param status The response status. 4588 + * @param text The user readable error to be displayed. Can be a translation key. 4589 + * @param parameters The parameters to use when decoding the translation key. 4590 + *### 4591 +#macro(blog__actionResponseError $status $text $parameters) 4592 + $response.setStatus($status) 4593 + #if($request.ajax) 4594 + $services.localization.render($text, $!parameters) 4595 + #else 4596 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}} 4597 + #end 4598 +#end 4599 +## 4600 +## 4601 +## 4602 +#** 4603 + * Check if a blog is the Default blog (The one in the 'Blog' space). 4604 + * 4605 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 4606 + * @param isDefault The resulting boolean. 4607 + *### 4608 +#macro(isDefaultBlog $blogDoc $isDefault) 4609 + #set ($result = false) 4610 + #if ($blogDoc.space == 'Blog') 4611 + #set ($result = true) 4612 + #end 4613 + #setVariable(~"$isDefault~" $result) 4614 +#end 4615 +## 4616 +## 4617 +## 4618 +#** 4619 + * Retrieve the blog posts location (space). 4620 + * 4621 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 4622 + * @param postsLocation The resulting location. 4623 + *### 4624 +#macro(getBlogPostsLocation $blogSpace $postsLocation) 4625 + #getBlogDocument($blogSpace $blogDoc) 4626 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result) 4627 + #set ($postsLocation = $NULL) 4628 + #setVariable (~"$postsLocation~" $result) 4629 +#end 4630 +## 4631 +## 4632 +## 4633 +#** 4634 + * Retrieve the blog categories location (space). 4635 + * 4636 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 4637 + * @param categoriesLocation The resulting location. 4638 + *### 4639 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation) 4640 + #getBlogDocument($blogSpace $blogDoc) 4641 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result) 4642 + #set ($postsLocation = $NULL) 4643 + #setVariable (~"$categoriesLocation~" $result) 4644 +#end 4645 +###** 4646 + * Return the Query for selecting the blog posts based on the context where the posts are displayed. 4647 + * for example there is 4 different panel contexts: 4648 + * aBlog.aPost or aBlog.WebHome 4649 + * aCategorySpace.aCategory 4650 + * aCategorySpace.WebHome 4651 + * Blog.aPost or Blog.WebHome 4652 + * 4653 + * @param query The query for selecting blog entries. 4654 + * @param queryParams The parameters to bind with the generated query. 4655 + * @param targetDoc The document in which the articles will be displayed. 4656 + *### 4657 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams) 4658 + #set ($query = $NULL) 4659 + #set ($queryParams = $NULL) 4660 + #getCategoryAllBlogPostsQuery($resultQuery) 4661 + #set ($resultQueryParams = \{}) 4662 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 4663 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 4664 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%' 4665 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space)) 4666 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 4667 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~") 4668 + #elseif($targetDoc.getObject($blogCategoryClassname)) 4669 + ## Get all posts that are in a category aCategorySpace.aCategory 4670 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName)) 4671 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~") 4672 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 4673 + ## Get all posts that are in a category aCategorySpace.% 4674 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 4675 + ## Exclude incategorized posts 4676 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~") 4677 + #if ($targetDoc.space == $defaultBlogSpace) 4678 + #set ($excludedCategory = ~"Blog.Categories.WebHome~") 4679 + #end 4680 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory)) 4681 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~") 4682 + #else 4683 + ## Get all posts in blog space aBlog 4684 + #getAllBlogPostsQuery($resultQuery) 4685 + #getBlogPostsLocation($targetDoc.space $postsLocation) 4686 + #set ($discard = $resultQueryParams.put('space', $postsLocation)) 4687 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~") 4688 + #end 4689 + #setVariable(~"$query~" $resultQuery) 4690 + #setVariable(~"$queryParams~" $resultQueryParams) 4691 +#end 4692 +## 4693 +## 4694 +## 4695 +###** 4696 + * Display blog posts based on the context where the posts are displayed. 4697 + * for example there is 4 different panel contexts: 4698 + * aBlog.aPost or aBlog.WebHome 4699 + * aCategorySpace.aCategory 4700 + * aCategorySpace.WebHome 4701 + * Blog.aPost or Blog.WebHome 4702 + * 4703 + * @param targetDoc The document in which the articles will be displayed. 4704 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ... 4705 + * @param layout Layout of the the posts to display 4706 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN' 4707 + * @param limit the number of posts to display 4708 + *### 4709 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit) 4710 + #if ($postLayout == 'full') 4711 + #set ($macro.paginated = 'yes') 4712 + #end 4713 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 4714 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%' 4715 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout) 4716 + #if (~"$!layout~" == '') 4717 + #set ($layout = $postsLayout) 4718 + #end 4719 + #if ($postsVisiblity == 'recent') 4720 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 4721 + #elseif($postsVisiblity == 'unpublished') 4722 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 4723 + #end 4724 + #elseif($targetDoc.getObject($blogCategoryClassname)) 4725 + ## Display all posts that are in a category aCategorySpace.aCategory 4726 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc) 4727 + #getBlogPostsLayout($blogDoc $postsLayout) 4728 + #if (~"$!layout~" == '') 4729 + #set ($layout = $postsLayout) 4730 + #end 4731 + #if ($postsVisiblity == 'recent') 4732 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 4733 + #elseif($postsVisiblity == 'unpublished') 4734 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 4735 + #end 4736 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 4737 + ## Display all posts that are in a category aCategorySpace.% 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.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 4745 + #elseif($postsVisiblity == 'unpublished') 4746 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 4747 + #end 4748 + #else 4749 + ## Display all posts in blog space aBlog 4750 + #getBlogDocument($targetDoc.space $blogDoc) 4751 + #getBlogPostsLayout($blogDoc $postsLayout) 4752 + #if (~"$!layout~" == '') 4753 + #set ($layout = $postsLayout) 4754 + #end 4755 + #if ($postsVisiblity == 'recent') 4756 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 4757 + #elseif($postsVisiblity == 'unpublished') 4758 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 4759 + #end 4760 + #end 4761 +#end 4762 +## 4763 +## 4764 +## 4765 +#** 4766 + * Bind parameters to a query object. 4767 + * 4768 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object) 4769 + * @param queryParams the query parameters. 4770 + *### 4771 +#macro(bindQueryParameters $queryObj $queryParams) 4772 + #set ($output = $queryObj) 4773 + #foreach( $key in $queryParams.keySet() ) 4774 + #set($output = $queryObj.bindValue($key, $queryParams.get($key))) 4775 + #end 4776 + #setVariable(~"$queryObj~" $output) 4777 +#end 4778 +## 4779 +## 4780 +## 4781 +#** 4782 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail 4783 + * 4784 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt> 4785 + * property set. 4786 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default). 4787 + *### 4788 +#macro(getBlogPostsLayout $blogDoc $postsLayout) 4789 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res) 4790 + #set ($postsLayout = $NULL) 4791 + #setVariable (~"$postsLayout~" $res) 4792 +#end 4793 +## 4794 +## 4795 +## 4796 +#** 4797 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space 4798 + * 4799 + * @param categoriesSpace A <tt>String</tt>, the name of the space. 4800 + * @param blogDoc The resulting XDocument. 4801 + *### 4802 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc) 4803 + #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()) 4804 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace) 4805 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0))) 4806 + #else 4807 + ## Fallback to Blog.WebHome, the default blog 4808 + #set($macro.result = $xwiki.getDocument('Blog.WebHome')) 4809 + #end 4810 + #set ($blogDoc = $NULL) 4811 + #setVariable (~"$blogDoc~" $macro.result) 4812 +#end" %) 4813 +((( 4814 +(% class="macro-placeholder hidden" %) 4815 +((( 4816 +macro:velocity 4817 +))) 4818 +))) 4819 +))) 4820 + 4821 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %) 4822 +((( 4823 +(% class="macro-placeholder hidden" %) 4824 +((( 4825 +macro:include 4826 +))) 4827 + 4828 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#** 4829 + * Extract the layout parameters from a string. 4830 + * 4831 + * @param layoutParamsString The string representation of the layout parameters. 4832 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~" 4833 + * @param layoutsParameters The resulting layout parameters Map. 4834 + *### 4835 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters) 4836 + #set ($layoutsParameters = $NULL) 4837 + #set ($macro.layoutParams = \{}) 4838 + #if (~"$!layoutParamsString~" != '') 4839 + #set ($macro.paramsArr = $layoutParamsString.split('\\|')) 4840 + #foreach ($item in $macro.paramsArr) 4841 + #set ($itemSplit = $item.split('=')) 4842 + #if ($itemSplit.size() == 2) 4843 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim())) 4844 + #end 4845 + #end 4846 + #end 4847 + #setVariable(~"$layoutsParameters~" $macro.layoutParams) 4848 +#end" %) 4849 +((( 4850 +(% class="macro-placeholder hidden" %) 4851 +((( 4852 +macro:velocity 4853 +))) 4854 +))) 4855 +))) 4856 + 4857 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj) 4858 + #initLayoutVars($pDoc $pObj) 4859 + <div class=~"col-xs-12 col-sm-6 next_blog~"> 4860 + <a href=~"$pDoc.uRL~" class=~"thumbnail~"> 4861 + <div class=~"row~"> 4862 + <div class=~"col-xs-4~"> 4863 + #if ($imageAtt) 4864 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 4865 + #end 4866 + </div> 4867 + <div class=~"col-xs-8 art_det~"> 4868 + <p class=~"text-left~"> 4869 + #if($displayTitle)$!postTitle #end 4870 + <br/><span class=~"date_info~"> $!dateStr </span> 4871 + </p> 4872 + #displayPostDetails($pDoc) 4873 + </div> 4874 + </div> 4875 + </a> 4876 + </div> 4877 + #end 4878 + ## 4879 + ## 4880 + ## 4881 + #macro(displayPinnedPost $pDoc $pObj) 4882 + #initLayoutVars($pDoc $pObj) 4883 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~"> 4884 + <a href=~"$pDoc.uRL~" class=~"all-post-link~"> 4885 + <div class=~"thumbnail~"> 4886 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts) 4887 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 4888 + #end 4889 + #if ($imageAtt) 4890 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 4891 + #end 4892 + <div class=~"caption~"> 4893 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts) 4894 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 4895 + #end 4896 + #if ($displaySummaryOnPinnedPosts) 4897 + <div class=~"text-left post-summary~"> 4898 + #set ($postContent = $pObj.getProperty('extract').value) 4899 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString()) 4900 + </div> 4901 + #end 4902 + #displayPostDetails($pDoc) 4903 + </div> 4904 + </div> 4905 + </a> 4906 + </div> 4907 + #end 4908 + ## 4909 + ## 4910 + ## 4911 + #macro(formatPostDate $pDoc $pObj) 4912 + #set ($formattedDate = $NULL) 4913 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale)) 4914 + #if (~"$!dateStr~" != '') 4915 + #set ($dateArr = $dateStr.split(' ')) 4916 + #if ($dateArr.size() > 3) 4917 + #set ($dateStr = ~"~") 4918 + #foreach($s in $dateArr.subList(0, 3)) 4919 + #set ($dateStr = ~"$\{dateStr}$\{s} ~") 4920 + #end 4921 + #end 4922 + #end 4923 + #setVariable(~"$formattedDate~" $dateStr) 4924 + #end 4925 + ## 4926 + ## 4927 + ## 4928 + #macro(displayPostDetails $pDoc) 4929 + <div class=~"row post-details~"> 4930 + <div class=~"col-xs-8 detail~"> 4931 + #if ($services.like.displayButton($pDoc.documentReference)) 4932 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference)) 4933 + ## Retrieve the likes number in XWiki 12.9+ 4934 + #set ($likeNumber = $optLikeRecord.get()) 4935 + #if (!$stringtool.isNumeric($likeNumber.toString())) 4936 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9. 4937 + #set ($likeNumber = $optLikeRecord.get().likeNumber) 4938 + #end 4939 + #if ($stringtool.isNumeric($likeNumber.toString())) 4940 + <div class=~"post-likes btn btn-default disabled badge~" 4941 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~"> 4942 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span> 4943 + </div> 4944 + #end 4945 + #elseif ($services.ratings) 4946 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference)) 4947 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1) 4948 + <ul class=~"pull-left note list-inline~"> 4949 + #foreach ($x in [1..5]) 4950 + #set ($cls = ~"~") 4951 + #if ($x > $averageVote) 4952 + #set ($cls = ~"-o~") 4953 + #end 4954 + <li><span class=~"fa fa-star$\{cls}~"></span></li> 4955 + #end 4956 + </ul> 4957 + #end 4958 + #end 4959 + </div> 4960 + #if ($showPostComments) 4961 + <div class=~"col-xs-4 com_det~"> 4962 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p> 4963 + </div> 4964 + #end 4965 + </div> 4966 + #end 4967 + ## 4968 + ## 4969 + ## 4970 + #macro(initLayoutVars $pDoc $pObj) 4971 + #set ($postTitle = $pDoc.display('title', 'view', $pObj)) 4972 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image'))) 4973 + #isPublished($pObj $isPublished) 4974 + #isHidden($pObj $isHidden) 4975 + #getEntryDate($pDoc $pObj $postDate) 4976 + #formatPostDate($postDate $dateStr) 4977 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote())) 4978 + #set ($nbComments = $pDoc.getComments().size()) 4979 + #set ($showPostComments = true) 4980 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0') 4981 + #set ($showPostComments = false) 4982 + #end 4983 + #end 4984 + ## 4985 + ## 4986 + ## 4987 + #macro(displayEditPinnedPostsButton) 4988 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName)) 4989 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet')) 4990 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet')) 4991 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet')) 4992 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~")) 4993 + <div class=~"edit-pinned-posts-container~"> 4994 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~"> 4995 + <a href=~"javascript:;~" class=~"editPinnedPosts~"> 4996 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit') 4997 + </a> 4998 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/> 4999 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/> 5000 + </div> 5001 + </div> 5002 + #if (~"$!pinnedPostsObj~" == '') 5003 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/> 5004 + #end 5005 + #end 5006 + #end" %) 5007 +((( 5008 +(% class="macro-placeholder hidden" %) 5009 +((( 5010 +macro:velocity 5011 +))) 5012 +))) 5013 + 5014 +(% data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference)) 5015 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference)) 5016 + #getEntryObject($postDoc $postObj) 5017 + #if (~"$!postObj~" != '') 5018 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams) 5019 + ## 5020 + #set ($displayTitle = true) 5021 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false') 5022 + #set ($displayTitle = false) 5023 + #end 5024 + ## 5025 + #set ($displayTitleFirstOnPinnedPosts = false) 5026 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true') 5027 + #set ($displayTitleFirstOnPinnedPosts = true) 5028 + #end 5029 + ## 5030 + #set ($displaySummaryOnPinnedPosts = true) 5031 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false') 5032 + #set ($displaySummaryOnPinnedPosts = false) 5033 + #end 5034 + ## 5035 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue()) 5036 + #if ($postIndex == 0) 5037 + #set ($stopBlogPostsDisplay = false) 5038 + #end 5039 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue()) 5040 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards')) 5041 + #set($scaleWidth = 600) 5042 + #set($imgQs=~"width=$scaleWidth~") 5043 + ## Display pinned posts 5044 + ## Get the list of pinned posts 5045 + #set ($pinnedPosts = []) 5046 + #set ($pinnedPostsSourceDoc = $NULL) 5047 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '') 5048 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog'))) 5049 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro 5050 + #end 5051 + #if (~"$!pinnedPostsSourceDoc~" != '') 5052 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass')) 5053 + #if (~"$!pinnedPostsObj~" != '') 5054 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value) 5055 + #if (~"$!orderedPinnedPostsJSON~" != '') 5056 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON)) 5057 + #else 5058 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value) 5059 + #end 5060 + #end 5061 + #if ($postIndex == 0 && $pinnedPosts.size() > 0) 5062 + \{\{html clean=~"false~"}} 5063 + #set ($x = 0) 5064 + #set ($showPinnedPostsButton = true) 5065 + #foreach ($pinnedPost in $pinnedPosts) 5066 + #if ($x == 0) 5067 + <div class=~"row flex-container~"> 5068 + #if ($showPinnedPostsButton) 5069 + #displayEditPinnedPostsButton() 5070 + #set($showPinnedPostsButton = false) 5071 + #end 5072 + #end 5073 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost)) 5074 + #getEntryObject($pinnedPostDoc $pinnedPostObj) 5075 + #if (~"$!pinnedPostObj~" != '') 5076 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj) 5077 + #end 5078 + #set ($x = $mathtool.add($x, 1)) 5079 + #if ($x == 3) 5080 + #set ($x = 0) 5081 + </div> 5082 + #end 5083 + #end 5084 + #if ($mathtool.mod($x, 3) != 0) 5085 + </div> 5086 + #end 5087 + \{\{/html}} 5088 + 5089 + ## If the first post is a pinned post : this means that all the posts are pinned 5090 + ## In this case, avoid displaying the posts again after the pinned posts section. 5091 + #if ($pinnedPosts.contains($xcontext.macro.params.reference)) 5092 + #set ($stopBlogPostsDisplay = true) 5093 + #end 5094 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0) 5095 + 5096 + \{\{html}} 5097 + <div class=~"row no-pinnded-posts~"> 5098 + #displayEditPinnedPostsButton() 5099 + </div> 5100 + \{\{/html}} 5101 + 5102 + #end 5103 + #end 5104 + #if (!$stopBlogPostsDisplay) 5105 + \{\{html clean=~"false~"}} 5106 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0) 5107 + #set ($nbDisplayedPosts = 0) 5108 + #end 5109 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0) 5110 + #if ($nbDisplayedPosts != 0) 5111 + </div> 5112 + #set ($lastHtmlTag = 'c') 5113 + #end 5114 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 5115 + <div class=~"row~"> 5116 + #set ($lastHtmlTag = 'o') 5117 + #set ($lastRowClass = ~"~") 5118 + #else 5119 + <div class=~"row flex-container~"> 5120 + #set ($lastHtmlTag = 'o') 5121 + #set ($lastRowClass = ~"flex~") 5122 + #end 5123 + #end 5124 + #displaySmallPost($postDoc $postObj) 5125 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 5126 + </div> 5127 + #set ($lastHtmlTag = 'c') 5128 + #end 5129 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1)) 5130 + #if ($postIndex == $mathtool.sub($listResultsCount, 1)) 5131 + #if (~"$!lastHtmlTag~" == 'o') 5132 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~") 5133 + <div class=~"col-xs-12 col-sm-6~"></div> 5134 + #end 5135 + </div> 5136 + #end 5137 + #end 5138 + \{\{/html}} 5139 + #end 5140 + #else 5141 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}} 5142 + #end 5143 + #else 5144 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}} 5145 + #end" class="macro hidden macro-placeholder" %)macro:velocity(% data-macro="startmacro:html|-|clean=~"false~"|-|</div> 5146 +<div class=~"row flex-container~"> 5147 +<div class=~"col-xs-12 col-sm-6 next_blog~"> 5148 +<a href=~"/Nieuws/Nieuwsbrief%20december%202023~" class=~"thumbnail~"> 5149 +<div class=~"row~"> 5150 +<div class=~"col-xs-4~"> 5151 +<img src=~"/download/Nieuws/Nieuwsbrief%20december%202023/snow-cold-winter-white-sweet-weather-1363025-pxhere.com.jpg?width=600&rev=1.1~" /> 5152 +</div> 5153 +<div class=~"col-xs-8 art_det~"> 5154 +<p class=~"text-left~"> 5155 +Nieuwsbrief december 2023 <br/><span class=~"date_info~"> 10 jan. 2024 </span> 5156 +</p> 5157 +<div class=~"row post-details~"> 5158 +<div class=~"col-xs-8 detail~"> 5159 +<div class=~"post-likes btn btn-default disabled badge~" 5160 +title=~"Number of likes on this page: 1~"> 5161 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">1</span> 5162 +</div> 5163 +</div> 5164 +<div class=~"col-xs-4 com_det~"> 5165 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p> 5166 +</div> 5167 +</div> 5168 +</div> 5169 +</div> 5170 +</a> 5171 +</div>" class="macro macro hidden macro-placeholder" %)macro:html 5172 +))) 5173 +))) 5174 + 5175 +(% class="row flex-container" %) 5176 +((( 5177 +(% class="col-xs-12 col-sm-6 next_blog" %) 5178 +((( 5179 +(% class="row" %) 5180 +((( 5181 +(% class="col-xs-4" %) 5182 +((( 5183 +[[~[~[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"]] 5184 +))) 5185 + 5186 +(% class="col-xs-8 art_det" %) 5187 +((( 5188 +(% class="text-left" %) 5189 +[[Nieuwsbrief december 2023 5190 +(% class="date_info" %) 10 jan. 2024>>path:/Nieuws/Nieuwsbrief%20december%202023||class="thumbnail"]] 5191 + 5192 +(% class="row post-details" %) 5193 +((( 5194 +(% class="col-xs-8 detail" %) 5195 +((( 5196 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 1" %) 5197 +((( 5198 +[[(% class="like-number" %)1>>path:/Nieuws/Nieuwsbrief%20december%202023||class="thumbnail"]] 5199 +))) 5200 +))) 5201 + 5202 +(% class="col-xs-4 com_det" %) 5203 +((( 5204 +(% class="text-right" %) 5205 +[[(0)>>path:/Nieuws/Nieuwsbrief%20december%202023||class="thumbnail"]] 5206 +))) 5207 +))) 5208 +))) 5209 +))) 5210 +))) 5211 + 5212 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Nieuwsbrief november 2023~" params=~"displayTitle=true|useSummary=true|list-limit=6|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=6|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~"" %) 5213 +((( 5214 +(% class="macro-placeholder hidden" %) 5215 +((( 5216 +macro:blogPostLayoutCards 5217 +))) 5218 + 5219 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %) 5220 +((( 5221 +(% class="macro-placeholder hidden" %) 5222 +((( 5223 +macro:include 5224 +))) 5225 + 5226 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %) 5227 +((( 5228 +(% class="macro-placeholder hidden" %) 5229 +((( 5230 +macro:include 5231 +))) 5232 + 5233 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog 5234 +#set($blogClassname = 'Blog.BlogClass') 5235 +#set($blogTemplate = 'Blog.BlogTemplate') 5236 +#set($blogSheet = 'Blog.BlogSheet') 5237 +## Blog entries 5238 +#set($blogPostClassname = 'Blog.BlogPostClass') 5239 +#set($blogPostTemplate = 'Blog.BlogPostTemplate') 5240 +#set($blogPostSheet = 'Blog.BlogPostSheet') 5241 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number) 5242 +#set($oldArticleClassname = 'XWiki.ArticleClass') 5243 +## Categories 5244 +#set($blogCategoryClassname = 'Blog.CategoryClass') 5245 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate') 5246 +#set($blogCategorySheet = 'Blog.CategorySheet') 5247 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet') 5248 +#set($oldBlogCategoryClassname = 'Blog.Categories') 5249 +#set($defaultCategoryParent = 'Blog.Categories') 5250 +## Style 5251 +#set($blogStyleDocumentName = 'Blog.BlogStyle') 5252 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName)) 5253 +## Clientside scripts 5254 +#set($blogScriptsDocumentName = 'Blog.BlogScripts') 5255 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher')) 5256 +## Misc 5257 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString)) 5258 +#set($isBlogPost = $doc.getObject($blogPostClassname)) 5259 +#set($defaultBlogSpace = 'Blog') 5260 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname)) 5261 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 5262 +## 5263 +## 5264 +## 5265 +#** 5266 + * Displays an image, taken from the blog style document. 5267 + * 5268 + * @param $imgName The name of the icon from icons set to use. 5269 + *# 5270 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %) 5271 +((( 5272 +(% class="macro-placeholder hidden" %) 5273 +((( 5274 +macro:velocity 5275 +))) 5276 +))) 5277 +))) 5278 + 5279 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## 5280 +## 5281 +## 5282 +## Import the blog skin and javascripts. 5283 +$!xwiki.ssx.use($blogStyleDocumentName)## 5284 +$!xwiki.jsx.use($blogScriptsDocumentName)## 5285 +## 5286 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation) 5287 +#template('hierarchy_macros.vm')## 5288 +## 5289 +## 5290 +#** 5291 + * Prints a blog. This is the main macro used in the BlogSheet. 5292 + * 5293 + * @param blogDoc the XDocument holding the blog definition object. 5294 + *### 5295 +#macro(printBlog $blogDoc) 5296 + \{\{include reference='Blog.CreatePost'/}} 5297 + 5298 + ## Use the blogPostList macro to display the blogposts 5299 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro 5300 + ## do not support FTM the monthly and weekly blog display types 5301 + #getBlogDisplayType($blogDoc $displayType) 5302 + #if ($displayType == 'weekly' || $displayType == 'monthly') 5303 + #getBlogEntries($blogDoc $entries) 5304 + #displayBlog($entries 'index' true true) 5305 + #displayNavigationLinks($blogDoc) 5306 + #else 5307 + #getBlogDisplayType($blogDoc $displayType) 5308 + #set ($paginated = 'no') 5309 + #if ($displayType == 'paginated') 5310 + #set ($paginated = 'yes') 5311 + #end 5312 + #getBlogPostsLayout($blogDoc $postsLayout) 5313 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}}))) 5314 + #end 5315 +#end 5316 +## 5317 +## 5318 +## 5319 +#** 5320 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title, 5321 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index, 5322 + * all entries). 5323 + * 5324 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 5325 + *### 5326 +#macro(showBlogInfo $blogDoc) 5327 + #if($blogDoc.getObject($blogClassname)) 5328 + ## Keep testing for inline action for backward compatibility with older blogs. 5329 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline') 5330 + #macro(displayProperty $blogDoc $propname) 5331 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)): 5332 + : $blogDoc.display($propname) 5333 + #end 5334 + #displayProperty($blogDoc 'title') 5335 + #displayProperty($blogDoc 'description') 5336 + #displayProperty($blogDoc 'displayType') 5337 + #displayProperty($blogDoc 'itemsPerPage') 5338 + #displayProperty($blogDoc 'postsLayout') 5339 + #displayProperty($blogDoc 'postsLayoutParameters') 5340 + #else 5341 + $blogDoc.display('description') 5342 + #end 5343 + #elseif($doc.fullName == $blogSheet) 5344 += $services.localization.render('blog.code.blogsheet') = 5345 + \{\{translation key='blog.code.sheetexplanation'/}} 5346 + #else 5347 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}} 5348 + #end 5349 +#end 5350 +## 5351 +## 5352 +## 5353 +#** 5354 + * Retrieve the blog document, which usually is either <tt><Space>.WebHome</tt> for whole-spaces blogs, or 5355 + * <tt><Space>.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first 5356 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current 5357 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog. 5358 + * 5359 + * @param space A <tt>String</tt>, the name of the space where to search. 5360 + * @param blogDoc The resulting XDocument. 5361 + *### 5362 +#macro(getBlogDocument $space $blogDoc) 5363 + #set ($result = $NULL) 5364 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object. 5365 + ## 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 5366 + ## identify the right blog based on a configuration object in a WebPreferences page. 5367 + #set ($spaceReference = $services.model.resolveSpace($space)) 5368 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference)) 5369 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef)) 5370 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass')) 5371 + #if ($preferencesObj) 5372 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog'))) 5373 + #end 5374 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy. 5375 + #if (~"$!result~" == '') 5376 + ## First, try the Space.WebHome, for a whole-space blog 5377 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~")) 5378 + #if(!$result.getObject($blogClassname)) 5379 + ## Second, try the Space.Blog document 5380 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~")) 5381 + #if(!$result.getObject($blogClassname)) 5382 + ## Third, try searching for a blog document in the current space 5383 + ## Prevent the query fail when the space contains dots '.' 5384 + #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()) 5385 + #if($blogDocs.size() > 0) 5386 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 5387 + #else 5388 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space 5389 + #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()) 5390 + #if($blogDocs.size() > 0) 5391 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 5392 + #else 5393 + ## Last, fallback to Blog.WebHome, the default blog 5394 + #set($result = $xwiki.getDocument('Blog.WebHome')) 5395 + #end 5396 + #end 5397 + #end 5398 + #end 5399 + #end 5400 + #set ($blogDoc = $NULL) 5401 + #setVariable (~"$blogDoc~" $result) 5402 +#end 5403 +## 5404 +## 5405 +## 5406 +#** 5407 + * Retrieve the blog title. 5408 + * 5409 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set. 5410 + * @param title The resulting title. 5411 + *### 5412 +#macro(getBlogTitle $blogDoc $title) 5413 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them. 5414 + #set ($title = $NULL) 5415 + #setVariable (~"$title~" $!blogDoc.displayTitle) 5416 +#end 5417 +## 5418 +## 5419 +## 5420 +#** 5421 + * Retrieve the blog description. 5422 + * 5423 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt> 5424 + * property set. 5425 + * @param description The resulting description. 5426 + *### 5427 +#macro(getBlogDescription $blogDoc $description) 5428 + #getBlogProperty($blogDoc 'description' '' $result) 5429 + #set ($description = $NULL) 5430 + #setVariable (~"$description~" $result) 5431 +#end 5432 +## 5433 +## 5434 +## 5435 +#** 5436 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog 5437 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on 5438 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a 5439 + * month), or all. 5440 + * 5441 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 5442 + * @param entries The resulting list of entries to display, a list of XDocument names. 5443 + *### 5444 +#macro(getBlogEntries $blogDoc $entries) 5445 + #if (!$entries) 5446 + #setVariable (~"$entries~" []) 5447 + #end 5448 + #getAllBlogPostsQuery($query) 5449 + #isDefaultBlog($blogDoc $isDefault) 5450 + #set($queryParams = \{}) 5451 + #if ($isDefault) 5452 + #getCategoryAllBlogPostsQuery($query) 5453 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~") 5454 + #set($discard = $queryParams.put('creator', $xcontext.user)) 5455 + #set($discard = $queryParams.put('space', $blogDoc.space)) 5456 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 5457 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace)) 5458 + #else 5459 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~") 5460 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation) 5461 + #set($discard = $queryParams.put('space', $blogPostsLocation)) 5462 + #set($discard = $queryParams.put('parent', $blogDoc.space)) 5463 + #end 5464 + #getBlogDisplayType($blogDoc $displayType) 5465 + #if($displayType == 'weekly') 5466 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams) 5467 + #elseif($displayType == 'monthly') 5468 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams) 5469 + #elseif($displayType == 'all') 5470 + #getAllBlogEntries($blogDoc $query $entries $queryParams) 5471 + #else 5472 + #getPagedBlogEntries($blogDoc $query $entries $queryParams) 5473 + #end 5474 +#end 5475 +## 5476 +## 5477 +## 5478 +#** 5479 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents 5480 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the 5481 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property 5482 + * (10 if not defined). 5483 + * 5484 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 5485 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 5486 + * refined to restrict to a given space, or to a given search criteria, etc. 5487 + * @param entries The resulting list of entries to display, a list of XDocument names. 5488 + * @param queryParams The parameters to bind with the query. 5489 + *### 5490 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams) 5491 + #if (!$entries) 5492 + #setVariable (~"$entries~" []) 5493 + #end 5494 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 5495 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~")) 5496 + #bindQueryParameters($countQueryObj $queryParams) 5497 + #bindQueryParameters($queryObj $queryParams) 5498 + #set($totalEntries = $countQueryObj.count()) 5499 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage) 5500 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue()) 5501 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 5502 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 5503 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute())) 5504 +#end 5505 +## 5506 +## 5507 +## 5508 +#** 5509 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is 5510 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4 5511 + * digit year). Initially the current week is displayed. 5512 + * 5513 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 5514 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 5515 + * refined to restrict to a given space, or to a given search criteria, etc. 5516 + * @param entries The resulting list of entries to display, a list of XDocument names. 5517 + * @param queryParams The parameters to bind with the query. 5518 + *### 5519 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams) 5520 + #if (!$entries) 5521 + #setVariable (~"$entries~" []) 5522 + #end 5523 + #getRequestedWeek($weekDate) 5524 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 5525 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor())) 5526 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling())) 5527 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 5528 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 5529 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 5530 + #bindQueryParameters($countQueryObj $queryParams) 5531 + #bindQueryParameters($queryObj $queryParams) 5532 + #set($totalEntries = $countQueryObj.count()) 5533 + #set($discard = $entries.addAll($queryObj.execute())) 5534 +#end 5535 +## 5536 +## 5537 +## 5538 +#** 5539 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is 5540 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4 5541 + * digit year). Initially the current month is displayed. 5542 + * 5543 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 5544 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 5545 + * refined to restrict to a given space, or to a given search criteria, etc. 5546 + * @param entries The resulting list of entries to display, a list of XDocument names. 5547 + * @param queryParams The parameters to bind with the query. 5548 + *### 5549 +#macro(getMonthlyBlogEntries $blogDoc $query $entries) 5550 + #if (!$entries) 5551 + #setVariable (~"$entries~" []) 5552 + #end 5553 + #getRequestedMonth($monthDate) 5554 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 5555 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor())) 5556 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling())) 5557 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 5558 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 5559 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 5560 + #bindQueryParameters($countQueryObj $queryParams) 5561 + #bindQueryParameters($queryObj $queryParams) 5562 + #set($totalEntries = $countQueryObj.count()) 5563 + #set($discard = $entries.addAll($queryObj.execute())) 5564 +#end 5565 +## 5566 +## 5567 +## 5568 +#** 5569 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned. 5570 + * 5571 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 5572 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 5573 + * refined to restrict to a given space, or to a given search criteria, etc. 5574 + * @param entries The resulting list of entries to display, a list of XDocument names. 5575 + * @param queryParams The parameters to bind with the query. 5576 + *### 5577 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams) 5578 + #if (!$entries) 5579 + #setVariable (~"$entries~" []) 5580 + #end 5581 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 5582 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 5583 + #bindQueryParameters($countQueryObj $queryParams) 5584 + #bindQueryParameters($queryObj $queryParams) 5585 + #set($totalEntries = $countQueryObj.count()) 5586 + #set($discard = $entries.addAll($queryObj.execute())) 5587 +#end 5588 +## 5589 +## 5590 +## 5591 +#** 5592 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned. 5593 + * 5594 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 5595 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 5596 + * refined to restrict to a given space, or to a given search criteria, etc. 5597 + * @param queryParams The parameters to bind with the query. 5598 + * @param entries The resulting list of entries to display, a list of XDocument names. 5599 + *### 5600 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries) 5601 + #if (!$entries) 5602 + #setVariable (~"$entries~" []) 5603 + #end 5604 + #set($query = ~"$\{query} and isPublished.value = 0~") 5605 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 5606 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 5607 + #bindQueryParameters($countQueryObj $queryParams) 5608 + #bindQueryParameters($queryObj $queryParams) 5609 + #set($totalEntries = $countQueryObj.count()) 5610 + #set($discard = $entries.addAll($queryObj.execute())) 5611 +#end 5612 +## 5613 +## 5614 +## 5615 +#** 5616 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog. 5617 + * 5618 + * @param entries The resulting list of entries to display, a list of XDocument names. 5619 + *### 5620 +#macro(getGlobalBlogEntries $entries) 5621 + #if (!$entries) 5622 + #setVariable (~"$entries~" []) 5623 + #end 5624 + #getAllBlogPostsQuery($query) 5625 + #set($totalEntries = $services.query.hql($query).count()) 5626 + #set($defaultItemsPerPage = 20) 5627 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 5628 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 5629 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute())) 5630 +#end 5631 +#** 5632 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific 5633 + * blog, nor specify a range or an ordering criteria. 5634 + * 5635 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code. 5636 + * 5637 + * @param query The basic query for selecting blog entries. 5638 + *# 5639 +#macro(getBlogEntriesBaseQuery $query) 5640 + #getAllBlogPostsQuery($query) 5641 +#end 5642 +#** 5643 + * Return the Query for selecting the all wiki blog posts without filtering 5644 + * 5645 + * @param query The basic query for selecting blog entries. 5646 + *# 5647 +#macro(getAllBlogPostsQuery $query) 5648 + #set ($query = $NULL) 5649 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished, 5650 + IntegerProperty hidden, DateProperty publishDate 5651 + where doc.fullName <> '$blogPostTemplate' and 5652 + obj.name=doc.fullName and obj.className='$blogPostClassname' and 5653 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and 5654 + hidden.id.id = obj.id and hidden.id.name='hidden' and 5655 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and 5656 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~") 5657 +#end 5658 +## 5659 +## 5660 +## 5661 +###** 5662 + * Return the Query for selecting the all wiki blog posts with categories filtering 5663 + * 5664 + * @param query The basic query for selecting blog entries. 5665 + *### 5666 +#macro(getCategoryAllBlogPostsQuery $query) 5667 + #set ($query = $NULL) 5668 + #getAllBlogPostsQuery($baseQuery) 5669 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList')) 5670 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~") 5671 +#end 5672 +## 5673 +## 5674 +## 5675 +#** 5676 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a 5677 + * week), monthly (all entries in a month), or all. 5678 + * 5679 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt> 5680 + * property set. 5681 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated. 5682 + *### 5683 +#macro(getBlogDisplayType $blogDoc $displayType) 5684 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result) 5685 + #set ($displayType = $NULL) 5686 + #setVariable (~"$displayType~" $result) 5687 +#end 5688 +## 5689 +## 5690 +## 5691 +#** 5692 + * Displays a list of entries. 5693 + * 5694 + * @param entries The entries to display, a list of XDocument names. 5695 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results, 5696 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently 5697 + * used values: index, single, category, search, unpublished, hidden. 5698 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content. 5699 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're 5700 + * displayed alone on their page since it's the page title which is used in this case) 5701 + *### 5702 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles) 5703 + #set($blogDay = '') 5704 + (% class=~"hfeed $!\{displaying}~" ~%)((( 5705 + (% class=~"blogDay~" ~%)((( 5706 + #foreach ($entryDoc in $xwiki.wrapDocs($entries)) 5707 + #getEntryObject($entryDoc $entryObj) 5708 + ## Although all entries should have one of the two objects, better check to be sure. 5709 + #if(~"$!\{entryObj}~" != '') 5710 + #getEntryDate($entryDoc $entryObj $entryDate) 5711 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet. 5712 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd')) 5713 + #if($blogDay != $entryDateStr) 5714 + #if($blogDay != '') 5715 + ))) 5716 + (% class=~"blogDay~" ~%)((( 5717 + #end 5718 + #displayBlogDate($entryDate) 5719 + #set ($blogDay = $entryDateStr) 5720 + #end 5721 + ## Finally, display the entry. 5722 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true) 5723 + #end 5724 + #end 5725 + )))## blogDay 5726 + )))## hfeed 5727 +#end 5728 +## 5729 +## 5730 +## 5731 +#** 5732 + * Get the entry object, either a new BlogPost or an old Article. 5733 + * 5734 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5735 + * @param entryObj The resulting xobject of the blog post. 5736 + *### 5737 +#macro(getEntryObject $entryDoc $__entryObj) 5738 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~")) 5739 + #if(!$result) 5740 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~")) 5741 + #end 5742 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from 5743 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be 5744 + ## overwritten in this case but it's less likely to have such a variable defined before. 5745 + #set ($__entryObj = $NULL) 5746 + #setVariable (~"$__entryObj~" $result) 5747 +#end 5748 +## 5749 +## 5750 +## 5751 +#** 5752 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is 5753 + * the document creation date, but can be edited by the user. 5754 + * 5755 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5756 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5757 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>. 5758 + *### 5759 +#macro(getEntryDate $entryDoc $entryObj $result) 5760 + #set ($result = $NULL) 5761 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value) 5762 +#end 5763 +## 5764 +## 5765 +## 5766 +#** 5767 + * Displays a date, nicely formatted as a calendar page. 5768 + * 5769 + * @param date The date to display, an instance of <tt>java.util.Date</tt>. 5770 + *### 5771 +#macro(displayBlogDate $date) 5772 + #set($year = $xwiki.formatDate($date, 'yyyy')) 5773 + ## 3 letter month name, like Jan, Dec. 5774 + #set($month = $xwiki.formatDate($date, 'MMM')) 5775 + ## Uncomment to get a full length month name, like January, December. 5776 + ## TODO: this could be defined somewhere in the blog style. 5777 + ## #set($month = $xwiki.formatDate($date, 'MMMM')) 5778 + #set($day = $xwiki.formatDate($date, 'dd')) 5779 + (% class=~"blogdate~" ~%) 5780 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) == 5781 +#end 5782 +## 5783 +## 5784 +## 5785 +#** 5786 + * Displays a blog article: management tools, header, content, footer. 5787 + * 5788 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5789 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5790 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 5791 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title 5792 + * when they're displayed alone on their page since it's the page title which is used in this case) 5793 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons 5794 + *### 5795 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions) 5796 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden 5797 + #isPublished($entryObj $isPublished) 5798 + #isHidden($entryObj $isHidden) 5799 + #if($doc.fullName == $entryDoc.fullName) 5800 + (% class=~"hentry single-article~" ~%)((( 5801 + #else 5802 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)((( 5803 + #end 5804 + #if ($shouldDisplayActions) 5805 + #displayEntryTools($entryDoc $entryObj) 5806 + #end 5807 + #if($shouldDisplayTitle) 5808 + #displayEntryTitle($entryDoc $entryObj) 5809 + #end 5810 + #if($doc.fullName == $entryDoc.fullName) 5811 + #if(!$isPublished) 5812 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}} 5813 + #elseif($isHidden) 5814 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}} 5815 + #end 5816 + #end 5817 + #displayEntryContent($entryDoc $entryObj $onlyExtract) 5818 + #displayEntryFooter($entryDoc $entryObj) 5819 + )))## hentry 5820 +#end 5821 +## 5822 +## 5823 +## 5824 +#** 5825 + * Checks if the provided blog is published or not. 5826 + * 5827 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5828 + * @param isPublished The resulting boolean, true if the entry is considered published. 5829 + *### 5830 +#macro(isPublished $entryObj $isPublished) 5831 + #set ($isPublished = $NULL) 5832 + ## This should work for both old articles, which don't have the 'published' property at all, and 5833 + ## are considered published by default, and new entries, that should have 1 if published. 5834 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0') 5835 + #setVariable (~"$isPublished~" true) 5836 + #else 5837 + #setVariable (~"$isPublished~" false) 5838 + #end 5839 +#end 5840 +## 5841 +## 5842 +## 5843 +#** 5844 + * Checks if the provided blog is hidden or not. 5845 + * 5846 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass. 5847 + * @param isHiddel The resulting boolean, true if the entry is considered hidden. 5848 + *### 5849 +#macro(isHidden $entryObj $isHidden) 5850 + #set ($isHidden = $NULL) 5851 + ## This should work for both old articles, which don't have the 'hidden' property at all, and 5852 + ## are considered visible by default, and new entries, that should have 1 if hidden. 5853 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1') 5854 + #setVariable (~"$isHidden~" true) 5855 + #else 5856 + #setVariable (~"$isHidden~" false) 5857 + #end 5858 +#end 5859 +## 5860 +## 5861 +## 5862 +#** 5863 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit. 5864 + * 5865 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5866 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5867 + *### 5868 +#macro(displayEntryTools $entryDoc $entryObj) 5869 + #if($xcontext.action == 'view') 5870 + (% class=~"blog-entry-toolbox~" ~%)((( 5871 + #displayPublishButton($entryDoc $entryObj) 5872 + #displayHideShowButton($entryDoc $entryObj) 5873 + #displayEditButton($entryDoc $entryObj) 5874 + #displayDeleteButton($entryDoc $entryObj) 5875 + ))) 5876 + #end 5877 +#end 5878 +## 5879 +## 5880 +## 5881 +#** 5882 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet. 5883 + * 5884 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5885 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5886 + * @todo AJAX calls. 5887 + *### 5888 +#macro(displayPublishButton $entryDoc $entryObj) 5889 + #isPublished($entryObj $isPublished) 5890 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 5891 + [[#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')~"]]## 5892 + #end 5893 +#end 5894 +## 5895 +## 5896 +## 5897 +#** 5898 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published. 5899 + * 5900 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5901 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5902 + *### 5903 +#macro(displayHideShowButton $entryDoc $entryObj) 5904 + #isPublished($entryObj $isPublished) 5905 + #isHidden($entryObj $isHidden) 5906 + ## Only published articles can be hidden. Unpublished articles are considered already hidden. 5907 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 5908 + #set ($queryString = \{ 5909 + 'xredirect' : $thisURL, 5910 + 'form_token' : $services.csrf.getToken() 5911 + }) 5912 + #if ($isHidden) 5913 + #set ($discard = $queryString.putAll(\{ 5914 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0, 5915 + 'comment' : $services.localization.render('blog.code.madevisible') 5916 + })) 5917 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 5918 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]## 5919 + #else 5920 + #set ($discard = $queryString.putAll(\{ 5921 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1, 5922 + 'comment' : $services.localization.render('blog.code.hid') 5923 + })) 5924 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 5925 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]## 5926 + #end 5927 + #end 5928 +#end 5929 +## 5930 +## 5931 +## 5932 +#** 5933 + * Displays the edit button to those that can edit the article. 5934 + * 5935 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5936 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5937 + *### 5938 +#macro(displayEditButton $entryDoc $entryObj) 5939 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 5940 + ## Call getDefaultEditMode() for backward compatibility with older blog posts. 5941 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]## 5942 + #end 5943 +#end 5944 +## 5945 +## 5946 +## 5947 +#** 5948 + * Displays the delete button to those that can edit the article. 5949 + * 5950 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5951 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5952 + * @todo AJAX calls. 5953 + *### 5954 +#macro(displayDeleteButton $entryDoc $entryObj) 5955 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName)) 5956 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]## 5957 + #end 5958 +#end 5959 +## 5960 +## 5961 +## 5962 +#** 5963 + * Displays the title of the entry. 5964 + * 5965 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5966 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5967 + *### 5968 +#macro(displayEntryTitle $entryDoc $entryObj) 5969 + #if($doc.fullName == $entryDoc.fullName) 5970 + (% class=~"entry-title~" ~%) 5971 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) = 5972 + #else 5973 + (% class=~"entry-title~" ~%) 5974 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] === 5975 + #end 5976 +#end 5977 +## 5978 +## 5979 +## 5980 +#** 5981 + * Displays the body of the entry. 5982 + * 5983 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 5984 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 5985 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 5986 + *### 5987 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract) 5988 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)((( 5989 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent) 5990 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328 5991 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content 5992 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}} 5993 + ))) ## entry-content 5994 + (% class=~"clearfloats~" ~%)((())) 5995 +#end 5996 +## 5997 +## 5998 +## 5999 +#** 6000 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content 6001 + * of the <tt>extract</tt> field (if not empty). 6002 + * 6003 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 6004 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 6005 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 6006 + * @param entryContent The resulting content. 6007 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when 6008 + * <tt>onlyExtract</tt> is <tt>true</tt>) 6009 + *### 6010 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis) 6011 + #if ($onlyExtract) 6012 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead 6013 + ## of the content. 6014 + #set ($macro.result = $entryObj.getProperty('extract').value.trim()) 6015 + #end 6016 + #if(~"$!macro.result~" == '') 6017 + #set($macro.result = $entryObj.getProperty('content').value) 6018 +#* Disabled until the content can be cleanly cut. 6019 +* #if($onlyExtract && $result.length()>$maxchars) 6020 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars)) 6021 +* #set($i = $i + 1) 6022 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~") 6023 +* #end 6024 +## *### 6025 + #elseif (!$removeEllipsis) 6026 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0') 6027 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~") 6028 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1') 6029 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~") 6030 + #end 6031 + #end 6032 + #set ($entryContent = $NULL) 6033 + #setVariable (~"$entryContent~" $macro.result) 6034 +#end 6035 +## 6036 +## 6037 +## 6038 +#** 6039 + * Displays the footer of the entry. 6040 + * 6041 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 6042 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 6043 + *### 6044 +#macro(displayEntryFooter $entryDoc $entryObj) 6045 + (% class=~"entry-footer~" ~%)((( 6046 + #isPublished($entryObj $isPublished) 6047 + (% class='entry-author-label' ~%) 6048 + #if($isPublished) 6049 + \{\{translation key='blog.code.postedby'/}} ## 6050 + #else 6051 + \{\{translation key='blog.code.createdby'/}} ## 6052 + #end 6053 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ## 6054 + #getEntryDate($entryDoc $entryObj $entryDate) 6055 + #listCategories($entryObj) #* 6056 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that 6057 + ## we assume cannot be more than 3 seconds. 6058 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ## 6059 + #if ($showcomments) 6060 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ## 6061 + #end ## 6062 + #if($entryDoc != $doc) ## 6063 + #displayEntryBlogLocation($entryDoc $entryObj) ## 6064 + #end 6065 + )))## entry-footer 6066 +#end 6067 +## 6068 +## 6069 +#** 6070 + * Display the blog for the entry (if it is not the currently displayed blog) 6071 + * 6072 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 6073 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 6074 + *### 6075 +#macro(displayEntryBlogLocation $entryDoc $entryObj) 6076 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ## 6077 + #if(~"$!blogPostsLocation~" != ~"~") ## 6078 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ## 6079 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ## 6080 + #if($doc.documentReference != $blogDocRef) ## 6081 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ## 6082 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ## 6083 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ## 6084 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ## 6085 + )))(%~%)## 6086 + #end 6087 + #end 6088 + #end 6089 +#end 6090 +## 6091 +## 6092 +## 6093 +## 6094 +#** 6095 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>. 6096 + * 6097 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 6098 + *### 6099 +#macro(listCategories $entryObj) 6100 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname) 6101 + #set($categories = $entryObj.getProperty('category').value) 6102 + #set($first = true) 6103 + #if($categories.size() > 0) 6104 + #foreach($category in $categories) 6105 + #set($categoryDoc = $!xwiki.getDocument($category)) 6106 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname})) 6107 + #if($foreach.count == 1) 6108 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ## 6109 + #else 6110 + , ## 6111 + #end## 6112 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]## 6113 + #end## 6114 + #end## 6115 + #end 6116 + #end 6117 +#end 6118 +## 6119 +## 6120 +## 6121 +#** 6122 + * Displays blog pagination links (older and newer entries). 6123 + * 6124 + * @param blogDoc the XDocument holding the blog definition object. 6125 + *### 6126 +#macro(displayNavigationLinks $blogDoc) 6127 + (% class=~"clearfloats~" ~%)((())) 6128 + #getBlogDisplayType($blogDoc $displayType) 6129 + #if($displayType == 'weekly') 6130 + (% class=~"pagingLinks~" ~%)((( 6131 + #getRequestedWeek($weekDate) 6132 + $weekDate.addWeeks(-1)## 6133 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 6134 + #sep() 6135 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above 6136 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 6137 + ))) 6138 + #elseif($displayType == 'monthly') 6139 + (% class=~"pagingLinks~" ~%)((( 6140 + #getRequestedMonth($monthDate) 6141 + $monthDate.addMonths(-1)## 6142 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 6143 + #sep() 6144 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above 6145 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 6146 + ))) 6147 + #elseif($displayType == 'all') 6148 + #else 6149 + ## Paginated 6150 + #if(($totalPages > 1)) 6151 + #set($queryString = '') 6152 + #foreach($p in $request.getParameterNames()) 6153 + #if($p != 'page' && $p != 'ipp') 6154 + #foreach($v in $request.getParameterValues($p)) 6155 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~") 6156 + #end 6157 + #end 6158 + #end 6159 + (% class=~"pagingLinks~" ~%)((( 6160 + #if ($currentPageNumber < $totalPages) 6161 + #set($currentPageNumber = $currentPageNumber + 1) 6162 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 6163 + #set($currentPageNumber = $currentPageNumber - 1) 6164 + #end 6165 + #if ($currentPageNumber > 1) 6166 + #if ($currentPageNumber < $totalPages) 6167 + #sep() 6168 + #end 6169 + #set($currentPageNumber = $currentPageNumber - 1) 6170 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 6171 + #set($currentPageNumber = $currentPageNumber + 1) 6172 + #end 6173 + (% class=~"clear~" ~%)(%~%) 6174 + )))## pagingLinks 6175 + #end 6176 + #end 6177 +#end 6178 +## 6179 +## 6180 +## 6181 +#** 6182 + * Displays a message box with ~"publish~" icon. 6183 + * 6184 + * @param message A text message concerning blog article publishing 6185 + *### 6186 +#macro(publishMessageBox $message) 6187 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message))) 6188 +#end 6189 +#** 6190 + * Displays a message box with ~"show/hide~" icon. 6191 + * 6192 + * @param message A text message concerning blog article hiding 6193 + *### 6194 +#macro(hideMessageBox $message) 6195 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message))) 6196 +#end 6197 +## 6198 +## 6199 +## 6200 +#** 6201 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are 6202 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used. 6203 + * 6204 + * @param monthDate The resulting week, a JODATime MutableDateTime. 6205 + *### 6206 +#macro(getRequestedWeek $weekDate) 6207 + #set ($weekDate = $NULL) 6208 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime) 6209 + #if(~"$!\{request.year}~" != '') 6210 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue())) 6211 + #end 6212 + #if(~"$!\{request.week}~" != '') 6213 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue())) 6214 + #end 6215 +#end 6216 +## 6217 +## 6218 +## 6219 +#** 6220 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are 6221 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used. 6222 + * 6223 + * @param monthDate The resulting month, a JODATime MutableDateTime. 6224 + *### 6225 +#macro(getRequestedMonth $monthDate) 6226 + #set ($monthDate = $NULL) 6227 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime) 6228 + #if(~"$!\{request.year}~" != '') 6229 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue())) 6230 + #end 6231 + #if(~"$!\{request.month}~" != '') 6232 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue())) 6233 + #end 6234 +#end 6235 +## 6236 +## 6237 +## 6238 +#** 6239 + * Retrieve a blog property (title, display type, etc). 6240 + * 6241 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 6242 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties. 6243 + * @param defaultValue The default value to use in case the blog object does not define one. 6244 + * @param propertyValue The resulting value. 6245 + *### 6246 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue) 6247 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~") 6248 + #if($result == '') 6249 + #set($result = $defaultValue) 6250 + #end 6251 + #set ($propertyValue = $NULL) 6252 + #setVariable (~"$propertyValue~" $result) 6253 +#end 6254 + 6255 +#** 6256 + * If an error occurs when executing an action, set a specific response status and display an error message. 6257 + * 6258 + * @param status The response status. 6259 + * @param text The user readable error to be displayed. Can be a translation key. 6260 + * @param parameters The parameters to use when decoding the translation key. 6261 + *### 6262 +#macro(blog__actionResponseError $status $text $parameters) 6263 + $response.setStatus($status) 6264 + #if($request.ajax) 6265 + $services.localization.render($text, $!parameters) 6266 + #else 6267 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}} 6268 + #end 6269 +#end 6270 +## 6271 +## 6272 +## 6273 +#** 6274 + * Check if a blog is the Default blog (The one in the 'Blog' space). 6275 + * 6276 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 6277 + * @param isDefault The resulting boolean. 6278 + *### 6279 +#macro(isDefaultBlog $blogDoc $isDefault) 6280 + #set ($result = false) 6281 + #if ($blogDoc.space == 'Blog') 6282 + #set ($result = true) 6283 + #end 6284 + #setVariable(~"$isDefault~" $result) 6285 +#end 6286 +## 6287 +## 6288 +## 6289 +#** 6290 + * Retrieve the blog posts location (space). 6291 + * 6292 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 6293 + * @param postsLocation The resulting location. 6294 + *### 6295 +#macro(getBlogPostsLocation $blogSpace $postsLocation) 6296 + #getBlogDocument($blogSpace $blogDoc) 6297 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result) 6298 + #set ($postsLocation = $NULL) 6299 + #setVariable (~"$postsLocation~" $result) 6300 +#end 6301 +## 6302 +## 6303 +## 6304 +#** 6305 + * Retrieve the blog categories location (space). 6306 + * 6307 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 6308 + * @param categoriesLocation The resulting location. 6309 + *### 6310 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation) 6311 + #getBlogDocument($blogSpace $blogDoc) 6312 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result) 6313 + #set ($postsLocation = $NULL) 6314 + #setVariable (~"$categoriesLocation~" $result) 6315 +#end 6316 +###** 6317 + * Return the Query for selecting the blog posts based on the context where the posts are displayed. 6318 + * for example there is 4 different panel contexts: 6319 + * aBlog.aPost or aBlog.WebHome 6320 + * aCategorySpace.aCategory 6321 + * aCategorySpace.WebHome 6322 + * Blog.aPost or Blog.WebHome 6323 + * 6324 + * @param query The query for selecting blog entries. 6325 + * @param queryParams The parameters to bind with the generated query. 6326 + * @param targetDoc The document in which the articles will be displayed. 6327 + *### 6328 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams) 6329 + #set ($query = $NULL) 6330 + #set ($queryParams = $NULL) 6331 + #getCategoryAllBlogPostsQuery($resultQuery) 6332 + #set ($resultQueryParams = \{}) 6333 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 6334 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 6335 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%' 6336 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space)) 6337 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 6338 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~") 6339 + #elseif($targetDoc.getObject($blogCategoryClassname)) 6340 + ## Get all posts that are in a category aCategorySpace.aCategory 6341 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName)) 6342 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~") 6343 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 6344 + ## Get all posts that are in a category aCategorySpace.% 6345 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 6346 + ## Exclude incategorized posts 6347 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~") 6348 + #if ($targetDoc.space == $defaultBlogSpace) 6349 + #set ($excludedCategory = ~"Blog.Categories.WebHome~") 6350 + #end 6351 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory)) 6352 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~") 6353 + #else 6354 + ## Get all posts in blog space aBlog 6355 + #getAllBlogPostsQuery($resultQuery) 6356 + #getBlogPostsLocation($targetDoc.space $postsLocation) 6357 + #set ($discard = $resultQueryParams.put('space', $postsLocation)) 6358 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~") 6359 + #end 6360 + #setVariable(~"$query~" $resultQuery) 6361 + #setVariable(~"$queryParams~" $resultQueryParams) 6362 +#end 6363 +## 6364 +## 6365 +## 6366 +###** 6367 + * Display blog posts based on the context where the posts are displayed. 6368 + * for example there is 4 different panel contexts: 6369 + * aBlog.aPost or aBlog.WebHome 6370 + * aCategorySpace.aCategory 6371 + * aCategorySpace.WebHome 6372 + * Blog.aPost or Blog.WebHome 6373 + * 6374 + * @param targetDoc The document in which the articles will be displayed. 6375 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ... 6376 + * @param layout Layout of the the posts to display 6377 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN' 6378 + * @param limit the number of posts to display 6379 + *### 6380 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit) 6381 + #if ($postLayout == 'full') 6382 + #set ($macro.paginated = 'yes') 6383 + #end 6384 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 6385 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%' 6386 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout) 6387 + #if (~"$!layout~" == '') 6388 + #set ($layout = $postsLayout) 6389 + #end 6390 + #if ($postsVisiblity == 'recent') 6391 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 6392 + #elseif($postsVisiblity == 'unpublished') 6393 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 6394 + #end 6395 + #elseif($targetDoc.getObject($blogCategoryClassname)) 6396 + ## Display all posts that are in a category aCategorySpace.aCategory 6397 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc) 6398 + #getBlogPostsLayout($blogDoc $postsLayout) 6399 + #if (~"$!layout~" == '') 6400 + #set ($layout = $postsLayout) 6401 + #end 6402 + #if ($postsVisiblity == 'recent') 6403 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 6404 + #elseif($postsVisiblity == 'unpublished') 6405 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 6406 + #end 6407 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 6408 + ## Display all posts that are in a category aCategorySpace.% 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.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 6416 + #elseif($postsVisiblity == 'unpublished') 6417 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 6418 + #end 6419 + #else 6420 + ## Display all posts in blog space aBlog 6421 + #getBlogDocument($targetDoc.space $blogDoc) 6422 + #getBlogPostsLayout($blogDoc $postsLayout) 6423 + #if (~"$!layout~" == '') 6424 + #set ($layout = $postsLayout) 6425 + #end 6426 + #if ($postsVisiblity == 'recent') 6427 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 6428 + #elseif($postsVisiblity == 'unpublished') 6429 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 6430 + #end 6431 + #end 6432 +#end 6433 +## 6434 +## 6435 +## 6436 +#** 6437 + * Bind parameters to a query object. 6438 + * 6439 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object) 6440 + * @param queryParams the query parameters. 6441 + *### 6442 +#macro(bindQueryParameters $queryObj $queryParams) 6443 + #set ($output = $queryObj) 6444 + #foreach( $key in $queryParams.keySet() ) 6445 + #set($output = $queryObj.bindValue($key, $queryParams.get($key))) 6446 + #end 6447 + #setVariable(~"$queryObj~" $output) 6448 +#end 6449 +## 6450 +## 6451 +## 6452 +#** 6453 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail 6454 + * 6455 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt> 6456 + * property set. 6457 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default). 6458 + *### 6459 +#macro(getBlogPostsLayout $blogDoc $postsLayout) 6460 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res) 6461 + #set ($postsLayout = $NULL) 6462 + #setVariable (~"$postsLayout~" $res) 6463 +#end 6464 +## 6465 +## 6466 +## 6467 +#** 6468 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space 6469 + * 6470 + * @param categoriesSpace A <tt>String</tt>, the name of the space. 6471 + * @param blogDoc The resulting XDocument. 6472 + *### 6473 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc) 6474 + #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()) 6475 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace) 6476 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0))) 6477 + #else 6478 + ## Fallback to Blog.WebHome, the default blog 6479 + #set($macro.result = $xwiki.getDocument('Blog.WebHome')) 6480 + #end 6481 + #set ($blogDoc = $NULL) 6482 + #setVariable (~"$blogDoc~" $macro.result) 6483 +#end" %) 6484 +((( 6485 +(% class="macro-placeholder hidden" %) 6486 +((( 6487 +macro:velocity 6488 +))) 6489 +))) 6490 +))) 6491 + 6492 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %) 6493 +((( 6494 +(% class="macro-placeholder hidden" %) 6495 +((( 6496 +macro:include 6497 +))) 6498 + 6499 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#** 6500 + * Extract the layout parameters from a string. 6501 + * 6502 + * @param layoutParamsString The string representation of the layout parameters. 6503 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~" 6504 + * @param layoutsParameters The resulting layout parameters Map. 6505 + *### 6506 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters) 6507 + #set ($layoutsParameters = $NULL) 6508 + #set ($macro.layoutParams = \{}) 6509 + #if (~"$!layoutParamsString~" != '') 6510 + #set ($macro.paramsArr = $layoutParamsString.split('\\|')) 6511 + #foreach ($item in $macro.paramsArr) 6512 + #set ($itemSplit = $item.split('=')) 6513 + #if ($itemSplit.size() == 2) 6514 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim())) 6515 + #end 6516 + #end 6517 + #end 6518 + #setVariable(~"$layoutsParameters~" $macro.layoutParams) 6519 +#end" %) 6520 +((( 6521 +(% class="macro-placeholder hidden" %) 6522 +((( 6523 +macro:velocity 6524 +))) 6525 +))) 6526 +))) 6527 + 6528 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj) 6529 + #initLayoutVars($pDoc $pObj) 6530 + <div class=~"col-xs-12 col-sm-6 next_blog~"> 6531 + <a href=~"$pDoc.uRL~" class=~"thumbnail~"> 6532 + <div class=~"row~"> 6533 + <div class=~"col-xs-4~"> 6534 + #if ($imageAtt) 6535 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 6536 + #end 6537 + </div> 6538 + <div class=~"col-xs-8 art_det~"> 6539 + <p class=~"text-left~"> 6540 + #if($displayTitle)$!postTitle #end 6541 + <br/><span class=~"date_info~"> $!dateStr </span> 6542 + </p> 6543 + #displayPostDetails($pDoc) 6544 + </div> 6545 + </div> 6546 + </a> 6547 + </div> 6548 + #end 6549 + ## 6550 + ## 6551 + ## 6552 + #macro(displayPinnedPost $pDoc $pObj) 6553 + #initLayoutVars($pDoc $pObj) 6554 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~"> 6555 + <a href=~"$pDoc.uRL~" class=~"all-post-link~"> 6556 + <div class=~"thumbnail~"> 6557 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts) 6558 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 6559 + #end 6560 + #if ($imageAtt) 6561 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 6562 + #end 6563 + <div class=~"caption~"> 6564 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts) 6565 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 6566 + #end 6567 + #if ($displaySummaryOnPinnedPosts) 6568 + <div class=~"text-left post-summary~"> 6569 + #set ($postContent = $pObj.getProperty('extract').value) 6570 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString()) 6571 + </div> 6572 + #end 6573 + #displayPostDetails($pDoc) 6574 + </div> 6575 + </div> 6576 + </a> 6577 + </div> 6578 + #end 6579 + ## 6580 + ## 6581 + ## 6582 + #macro(formatPostDate $pDoc $pObj) 6583 + #set ($formattedDate = $NULL) 6584 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale)) 6585 + #if (~"$!dateStr~" != '') 6586 + #set ($dateArr = $dateStr.split(' ')) 6587 + #if ($dateArr.size() > 3) 6588 + #set ($dateStr = ~"~") 6589 + #foreach($s in $dateArr.subList(0, 3)) 6590 + #set ($dateStr = ~"$\{dateStr}$\{s} ~") 6591 + #end 6592 + #end 6593 + #end 6594 + #setVariable(~"$formattedDate~" $dateStr) 6595 + #end 6596 + ## 6597 + ## 6598 + ## 6599 + #macro(displayPostDetails $pDoc) 6600 + <div class=~"row post-details~"> 6601 + <div class=~"col-xs-8 detail~"> 6602 + #if ($services.like.displayButton($pDoc.documentReference)) 6603 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference)) 6604 + ## Retrieve the likes number in XWiki 12.9+ 6605 + #set ($likeNumber = $optLikeRecord.get()) 6606 + #if (!$stringtool.isNumeric($likeNumber.toString())) 6607 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9. 6608 + #set ($likeNumber = $optLikeRecord.get().likeNumber) 6609 + #end 6610 + #if ($stringtool.isNumeric($likeNumber.toString())) 6611 + <div class=~"post-likes btn btn-default disabled badge~" 6612 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~"> 6613 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span> 6614 + </div> 6615 + #end 6616 + #elseif ($services.ratings) 6617 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference)) 6618 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1) 6619 + <ul class=~"pull-left note list-inline~"> 6620 + #foreach ($x in [1..5]) 6621 + #set ($cls = ~"~") 6622 + #if ($x > $averageVote) 6623 + #set ($cls = ~"-o~") 6624 + #end 6625 + <li><span class=~"fa fa-star$\{cls}~"></span></li> 6626 + #end 6627 + </ul> 6628 + #end 6629 + #end 6630 + </div> 6631 + #if ($showPostComments) 6632 + <div class=~"col-xs-4 com_det~"> 6633 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p> 6634 + </div> 6635 + #end 6636 + </div> 6637 + #end 6638 + ## 6639 + ## 6640 + ## 6641 + #macro(initLayoutVars $pDoc $pObj) 6642 + #set ($postTitle = $pDoc.display('title', 'view', $pObj)) 6643 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image'))) 6644 + #isPublished($pObj $isPublished) 6645 + #isHidden($pObj $isHidden) 6646 + #getEntryDate($pDoc $pObj $postDate) 6647 + #formatPostDate($postDate $dateStr) 6648 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote())) 6649 + #set ($nbComments = $pDoc.getComments().size()) 6650 + #set ($showPostComments = true) 6651 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0') 6652 + #set ($showPostComments = false) 6653 + #end 6654 + #end 6655 + ## 6656 + ## 6657 + ## 6658 + #macro(displayEditPinnedPostsButton) 6659 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName)) 6660 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet')) 6661 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet')) 6662 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet')) 6663 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~")) 6664 + <div class=~"edit-pinned-posts-container~"> 6665 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~"> 6666 + <a href=~"javascript:;~" class=~"editPinnedPosts~"> 6667 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit') 6668 + </a> 6669 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/> 6670 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/> 6671 + </div> 6672 + </div> 6673 + #if (~"$!pinnedPostsObj~" == '') 6674 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/> 6675 + #end 6676 + #end 6677 + #end" %) 6678 +((( 6679 +(% class="macro-placeholder hidden" %) 6680 +((( 6681 +macro:velocity 6682 +))) 6683 +))) 6684 + 6685 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference)) 6686 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference)) 6687 + #getEntryObject($postDoc $postObj) 6688 + #if (~"$!postObj~" != '') 6689 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams) 6690 + ## 6691 + #set ($displayTitle = true) 6692 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false') 6693 + #set ($displayTitle = false) 6694 + #end 6695 + ## 6696 + #set ($displayTitleFirstOnPinnedPosts = false) 6697 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true') 6698 + #set ($displayTitleFirstOnPinnedPosts = true) 6699 + #end 6700 + ## 6701 + #set ($displaySummaryOnPinnedPosts = true) 6702 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false') 6703 + #set ($displaySummaryOnPinnedPosts = false) 6704 + #end 6705 + ## 6706 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue()) 6707 + #if ($postIndex == 0) 6708 + #set ($stopBlogPostsDisplay = false) 6709 + #end 6710 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue()) 6711 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards')) 6712 + #set($scaleWidth = 600) 6713 + #set($imgQs=~"width=$scaleWidth~") 6714 + ## Display pinned posts 6715 + ## Get the list of pinned posts 6716 + #set ($pinnedPosts = []) 6717 + #set ($pinnedPostsSourceDoc = $NULL) 6718 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '') 6719 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog'))) 6720 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro 6721 + #end 6722 + #if (~"$!pinnedPostsSourceDoc~" != '') 6723 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass')) 6724 + #if (~"$!pinnedPostsObj~" != '') 6725 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value) 6726 + #if (~"$!orderedPinnedPostsJSON~" != '') 6727 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON)) 6728 + #else 6729 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value) 6730 + #end 6731 + #end 6732 + #if ($postIndex == 0 && $pinnedPosts.size() > 0) 6733 + \{\{html clean=~"false~"}} 6734 + #set ($x = 0) 6735 + #set ($showPinnedPostsButton = true) 6736 + #foreach ($pinnedPost in $pinnedPosts) 6737 + #if ($x == 0) 6738 + <div class=~"row flex-container~"> 6739 + #if ($showPinnedPostsButton) 6740 + #displayEditPinnedPostsButton() 6741 + #set($showPinnedPostsButton = false) 6742 + #end 6743 + #end 6744 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost)) 6745 + #getEntryObject($pinnedPostDoc $pinnedPostObj) 6746 + #if (~"$!pinnedPostObj~" != '') 6747 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj) 6748 + #end 6749 + #set ($x = $mathtool.add($x, 1)) 6750 + #if ($x == 3) 6751 + #set ($x = 0) 6752 + </div> 6753 + #end 6754 + #end 6755 + #if ($mathtool.mod($x, 3) != 0) 6756 + </div> 6757 + #end 6758 + \{\{/html}} 6759 + 6760 + ## If the first post is a pinned post : this means that all the posts are pinned 6761 + ## In this case, avoid displaying the posts again after the pinned posts section. 6762 + #if ($pinnedPosts.contains($xcontext.macro.params.reference)) 6763 + #set ($stopBlogPostsDisplay = true) 6764 + #end 6765 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0) 6766 + 6767 + \{\{html}} 6768 + <div class=~"row no-pinnded-posts~"> 6769 + #displayEditPinnedPostsButton() 6770 + </div> 6771 + \{\{/html}} 6772 + 6773 + #end 6774 + #end 6775 + #if (!$stopBlogPostsDisplay) 6776 + \{\{html clean=~"false~"}} 6777 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0) 6778 + #set ($nbDisplayedPosts = 0) 6779 + #end 6780 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0) 6781 + #if ($nbDisplayedPosts != 0) 6782 + </div> 6783 + #set ($lastHtmlTag = 'c') 6784 + #end 6785 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 6786 + <div class=~"row~"> 6787 + #set ($lastHtmlTag = 'o') 6788 + #set ($lastRowClass = ~"~") 6789 + #else 6790 + <div class=~"row flex-container~"> 6791 + #set ($lastHtmlTag = 'o') 6792 + #set ($lastRowClass = ~"flex~") 6793 + #end 6794 + #end 6795 + #displaySmallPost($postDoc $postObj) 6796 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 6797 + </div> 6798 + #set ($lastHtmlTag = 'c') 6799 + #end 6800 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1)) 6801 + #if ($postIndex == $mathtool.sub($listResultsCount, 1)) 6802 + #if (~"$!lastHtmlTag~" == 'o') 6803 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~") 6804 + <div class=~"col-xs-12 col-sm-6~"></div> 6805 + #end 6806 + </div> 6807 + #end 6808 + #end 6809 + \{\{/html}} 6810 + #end 6811 + #else 6812 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}} 6813 + #end 6814 + #else 6815 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}} 6816 + #end" %) 6817 +((( 6818 +(% class="macro-placeholder hidden" %) 6819 +((( 6820 +macro:velocity 6821 +))) 6822 + 6823 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"col-xs-12 col-sm-6 next_blog~"> 6824 +<a href=~"/Nieuws/Nieuwsbrief%20november%202023~" class=~"thumbnail~"> 6825 +<div class=~"row~"> 6826 +<div class=~"col-xs-4~"> 6827 +<img src=~"/download/Nieuws/Nieuwsbrief%20november%202023/man-person-light-bokeh-blur-road-1268120-pxhere.com.jpg?width=600&rev=1.1~" /> 6828 +</div> 6829 +<div class=~"col-xs-8 art_det~"> 6830 +<p class=~"text-left~"> 6831 +Nieuwsbrief november 2023 <br/><span class=~"date_info~"> 18 dec. 2023 </span> 6832 +</p> 6833 +<div class=~"row post-details~"> 6834 +<div class=~"col-xs-8 detail~"> 6835 +<div class=~"post-likes btn btn-default disabled badge~" 6836 +title=~"Number of likes on this page: 0~"> 6837 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">0</span> 6838 +</div> 6839 +</div> 6840 +<div class=~"col-xs-4 com_det~"> 6841 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p> 6842 +</div> 6843 +</div> 6844 +</div> 6845 +</div> 6846 +</a> 6847 +</div>" %) 6848 +((( 6849 +(% class="macro-placeholder hidden" %) 6850 +((( 6851 +macro:html 6852 +))) 6853 + 6854 +(% class="col-xs-12 col-sm-6 next_blog" %) 6855 +((( 6856 +(% class="row" %) 6857 +((( 6858 +(% class="col-xs-4" %) 6859 +((( 6860 +[[~[~[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"]] 6861 +))) 6862 + 6863 +(% class="col-xs-8 art_det" %) 6864 +((( 6865 +(% class="text-left" %) 6866 +[[Nieuwsbrief november 2023 6867 +(% class="date_info" %) 18 dec. 2023>>path:/Nieuws/Nieuwsbrief%20november%202023||class="thumbnail"]] 6868 + 6869 +(% class="row post-details" %) 6870 +((( 6871 +(% class="col-xs-8 detail" %) 6872 +((( 6873 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 0" %) 6874 +((( 6875 +[[(% class="like-number" %)0>>path:/Nieuws/Nieuwsbrief%20november%202023||class="thumbnail"]] 6876 +))) 6877 +))) 6878 + 6879 +(% class="col-xs-4 com_det" %) 6880 +((( 6881 +(% class="text-right" %) 6882 +[[(0)>>path:/Nieuws/Nieuwsbrief%20november%202023||class="thumbnail"]] 6883 +))) 6884 +))) 6885 +))) 6886 +))) 6887 +))) 6888 +))) 6889 +))) 6890 +))) 6891 + 6892 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.Feestelijke afsluiting, keuring materieel en tellen voorraden~" params=~"displayTitle=true|useSummary=true|list-limit=6|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=6|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~"" %) 6893 +((( 6894 +(% class="macro-placeholder hidden" %) 6895 +((( 6896 +macro:blogPostLayoutCards 6897 +))) 6898 + 6899 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %) 6900 +((( 6901 +(% class="macro-placeholder hidden" %) 6902 +((( 6903 +macro:include 6904 +))) 6905 + 6906 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %) 6907 +((( 6908 +(% class="macro-placeholder hidden" %) 6909 +((( 6910 +macro:include 6911 +))) 6912 + 6913 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog 6914 +#set($blogClassname = 'Blog.BlogClass') 6915 +#set($blogTemplate = 'Blog.BlogTemplate') 6916 +#set($blogSheet = 'Blog.BlogSheet') 6917 +## Blog entries 6918 +#set($blogPostClassname = 'Blog.BlogPostClass') 6919 +#set($blogPostTemplate = 'Blog.BlogPostTemplate') 6920 +#set($blogPostSheet = 'Blog.BlogPostSheet') 6921 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number) 6922 +#set($oldArticleClassname = 'XWiki.ArticleClass') 6923 +## Categories 6924 +#set($blogCategoryClassname = 'Blog.CategoryClass') 6925 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate') 6926 +#set($blogCategorySheet = 'Blog.CategorySheet') 6927 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet') 6928 +#set($oldBlogCategoryClassname = 'Blog.Categories') 6929 +#set($defaultCategoryParent = 'Blog.Categories') 6930 +## Style 6931 +#set($blogStyleDocumentName = 'Blog.BlogStyle') 6932 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName)) 6933 +## Clientside scripts 6934 +#set($blogScriptsDocumentName = 'Blog.BlogScripts') 6935 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher')) 6936 +## Misc 6937 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString)) 6938 +#set($isBlogPost = $doc.getObject($blogPostClassname)) 6939 +#set($defaultBlogSpace = 'Blog') 6940 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname)) 6941 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 6942 +## 6943 +## 6944 +## 6945 +#** 6946 + * Displays an image, taken from the blog style document. 6947 + * 6948 + * @param $imgName The name of the icon from icons set to use. 6949 + *# 6950 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %) 6951 +((( 6952 +(% class="macro-placeholder hidden" %) 6953 +((( 6954 +macro:velocity 6955 +))) 6956 +))) 6957 +))) 6958 + 6959 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## 6960 +## 6961 +## 6962 +## Import the blog skin and javascripts. 6963 +$!xwiki.ssx.use($blogStyleDocumentName)## 6964 +$!xwiki.jsx.use($blogScriptsDocumentName)## 6965 +## 6966 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation) 6967 +#template('hierarchy_macros.vm')## 6968 +## 6969 +## 6970 +#** 6971 + * Prints a blog. This is the main macro used in the BlogSheet. 6972 + * 6973 + * @param blogDoc the XDocument holding the blog definition object. 6974 + *### 6975 +#macro(printBlog $blogDoc) 6976 + \{\{include reference='Blog.CreatePost'/}} 6977 + 6978 + ## Use the blogPostList macro to display the blogposts 6979 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro 6980 + ## do not support FTM the monthly and weekly blog display types 6981 + #getBlogDisplayType($blogDoc $displayType) 6982 + #if ($displayType == 'weekly' || $displayType == 'monthly') 6983 + #getBlogEntries($blogDoc $entries) 6984 + #displayBlog($entries 'index' true true) 6985 + #displayNavigationLinks($blogDoc) 6986 + #else 6987 + #getBlogDisplayType($blogDoc $displayType) 6988 + #set ($paginated = 'no') 6989 + #if ($displayType == 'paginated') 6990 + #set ($paginated = 'yes') 6991 + #end 6992 + #getBlogPostsLayout($blogDoc $postsLayout) 6993 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}}))) 6994 + #end 6995 +#end 6996 +## 6997 +## 6998 +## 6999 +#** 7000 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title, 7001 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index, 7002 + * all entries). 7003 + * 7004 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7005 + *### 7006 +#macro(showBlogInfo $blogDoc) 7007 + #if($blogDoc.getObject($blogClassname)) 7008 + ## Keep testing for inline action for backward compatibility with older blogs. 7009 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline') 7010 + #macro(displayProperty $blogDoc $propname) 7011 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)): 7012 + : $blogDoc.display($propname) 7013 + #end 7014 + #displayProperty($blogDoc 'title') 7015 + #displayProperty($blogDoc 'description') 7016 + #displayProperty($blogDoc 'displayType') 7017 + #displayProperty($blogDoc 'itemsPerPage') 7018 + #displayProperty($blogDoc 'postsLayout') 7019 + #displayProperty($blogDoc 'postsLayoutParameters') 7020 + #else 7021 + $blogDoc.display('description') 7022 + #end 7023 + #elseif($doc.fullName == $blogSheet) 7024 += $services.localization.render('blog.code.blogsheet') = 7025 + \{\{translation key='blog.code.sheetexplanation'/}} 7026 + #else 7027 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}} 7028 + #end 7029 +#end 7030 +## 7031 +## 7032 +## 7033 +#** 7034 + * Retrieve the blog document, which usually is either <tt><Space>.WebHome</tt> for whole-spaces blogs, or 7035 + * <tt><Space>.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first 7036 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current 7037 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog. 7038 + * 7039 + * @param space A <tt>String</tt>, the name of the space where to search. 7040 + * @param blogDoc The resulting XDocument. 7041 + *### 7042 +#macro(getBlogDocument $space $blogDoc) 7043 + #set ($result = $NULL) 7044 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object. 7045 + ## 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 7046 + ## identify the right blog based on a configuration object in a WebPreferences page. 7047 + #set ($spaceReference = $services.model.resolveSpace($space)) 7048 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference)) 7049 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef)) 7050 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass')) 7051 + #if ($preferencesObj) 7052 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog'))) 7053 + #end 7054 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy. 7055 + #if (~"$!result~" == '') 7056 + ## First, try the Space.WebHome, for a whole-space blog 7057 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~")) 7058 + #if(!$result.getObject($blogClassname)) 7059 + ## Second, try the Space.Blog document 7060 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~")) 7061 + #if(!$result.getObject($blogClassname)) 7062 + ## Third, try searching for a blog document in the current space 7063 + ## Prevent the query fail when the space contains dots '.' 7064 + #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()) 7065 + #if($blogDocs.size() > 0) 7066 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 7067 + #else 7068 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space 7069 + #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()) 7070 + #if($blogDocs.size() > 0) 7071 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 7072 + #else 7073 + ## Last, fallback to Blog.WebHome, the default blog 7074 + #set($result = $xwiki.getDocument('Blog.WebHome')) 7075 + #end 7076 + #end 7077 + #end 7078 + #end 7079 + #end 7080 + #set ($blogDoc = $NULL) 7081 + #setVariable (~"$blogDoc~" $result) 7082 +#end 7083 +## 7084 +## 7085 +## 7086 +#** 7087 + * Retrieve the blog title. 7088 + * 7089 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set. 7090 + * @param title The resulting title. 7091 + *### 7092 +#macro(getBlogTitle $blogDoc $title) 7093 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them. 7094 + #set ($title = $NULL) 7095 + #setVariable (~"$title~" $!blogDoc.displayTitle) 7096 +#end 7097 +## 7098 +## 7099 +## 7100 +#** 7101 + * Retrieve the blog description. 7102 + * 7103 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt> 7104 + * property set. 7105 + * @param description The resulting description. 7106 + *### 7107 +#macro(getBlogDescription $blogDoc $description) 7108 + #getBlogProperty($blogDoc 'description' '' $result) 7109 + #set ($description = $NULL) 7110 + #setVariable (~"$description~" $result) 7111 +#end 7112 +## 7113 +## 7114 +## 7115 +#** 7116 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog 7117 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on 7118 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a 7119 + * month), or all. 7120 + * 7121 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7122 + * @param entries The resulting list of entries to display, a list of XDocument names. 7123 + *### 7124 +#macro(getBlogEntries $blogDoc $entries) 7125 + #if (!$entries) 7126 + #setVariable (~"$entries~" []) 7127 + #end 7128 + #getAllBlogPostsQuery($query) 7129 + #isDefaultBlog($blogDoc $isDefault) 7130 + #set($queryParams = \{}) 7131 + #if ($isDefault) 7132 + #getCategoryAllBlogPostsQuery($query) 7133 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~") 7134 + #set($discard = $queryParams.put('creator', $xcontext.user)) 7135 + #set($discard = $queryParams.put('space', $blogDoc.space)) 7136 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 7137 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace)) 7138 + #else 7139 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~") 7140 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation) 7141 + #set($discard = $queryParams.put('space', $blogPostsLocation)) 7142 + #set($discard = $queryParams.put('parent', $blogDoc.space)) 7143 + #end 7144 + #getBlogDisplayType($blogDoc $displayType) 7145 + #if($displayType == 'weekly') 7146 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams) 7147 + #elseif($displayType == 'monthly') 7148 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams) 7149 + #elseif($displayType == 'all') 7150 + #getAllBlogEntries($blogDoc $query $entries $queryParams) 7151 + #else 7152 + #getPagedBlogEntries($blogDoc $query $entries $queryParams) 7153 + #end 7154 +#end 7155 +## 7156 +## 7157 +## 7158 +#** 7159 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents 7160 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the 7161 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property 7162 + * (10 if not defined). 7163 + * 7164 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7165 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 7166 + * refined to restrict to a given space, or to a given search criteria, etc. 7167 + * @param entries The resulting list of entries to display, a list of XDocument names. 7168 + * @param queryParams The parameters to bind with the query. 7169 + *### 7170 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams) 7171 + #if (!$entries) 7172 + #setVariable (~"$entries~" []) 7173 + #end 7174 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 7175 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~")) 7176 + #bindQueryParameters($countQueryObj $queryParams) 7177 + #bindQueryParameters($queryObj $queryParams) 7178 + #set($totalEntries = $countQueryObj.count()) 7179 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage) 7180 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue()) 7181 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 7182 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 7183 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute())) 7184 +#end 7185 +## 7186 +## 7187 +## 7188 +#** 7189 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is 7190 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4 7191 + * digit year). Initially the current week is displayed. 7192 + * 7193 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7194 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 7195 + * refined to restrict to a given space, or to a given search criteria, etc. 7196 + * @param entries The resulting list of entries to display, a list of XDocument names. 7197 + * @param queryParams The parameters to bind with the query. 7198 + *### 7199 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams) 7200 + #if (!$entries) 7201 + #setVariable (~"$entries~" []) 7202 + #end 7203 + #getRequestedWeek($weekDate) 7204 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 7205 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor())) 7206 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling())) 7207 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 7208 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 7209 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 7210 + #bindQueryParameters($countQueryObj $queryParams) 7211 + #bindQueryParameters($queryObj $queryParams) 7212 + #set($totalEntries = $countQueryObj.count()) 7213 + #set($discard = $entries.addAll($queryObj.execute())) 7214 +#end 7215 +## 7216 +## 7217 +## 7218 +#** 7219 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is 7220 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4 7221 + * digit year). Initially the current month is displayed. 7222 + * 7223 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7224 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 7225 + * refined to restrict to a given space, or to a given search criteria, etc. 7226 + * @param entries The resulting list of entries to display, a list of XDocument names. 7227 + * @param queryParams The parameters to bind with the query. 7228 + *### 7229 +#macro(getMonthlyBlogEntries $blogDoc $query $entries) 7230 + #if (!$entries) 7231 + #setVariable (~"$entries~" []) 7232 + #end 7233 + #getRequestedMonth($monthDate) 7234 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 7235 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor())) 7236 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling())) 7237 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 7238 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 7239 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 7240 + #bindQueryParameters($countQueryObj $queryParams) 7241 + #bindQueryParameters($queryObj $queryParams) 7242 + #set($totalEntries = $countQueryObj.count()) 7243 + #set($discard = $entries.addAll($queryObj.execute())) 7244 +#end 7245 +## 7246 +## 7247 +## 7248 +#** 7249 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned. 7250 + * 7251 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7252 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 7253 + * refined to restrict to a given space, or to a given search criteria, etc. 7254 + * @param entries The resulting list of entries to display, a list of XDocument names. 7255 + * @param queryParams The parameters to bind with the query. 7256 + *### 7257 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams) 7258 + #if (!$entries) 7259 + #setVariable (~"$entries~" []) 7260 + #end 7261 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 7262 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 7263 + #bindQueryParameters($countQueryObj $queryParams) 7264 + #bindQueryParameters($queryObj $queryParams) 7265 + #set($totalEntries = $countQueryObj.count()) 7266 + #set($discard = $entries.addAll($queryObj.execute())) 7267 +#end 7268 +## 7269 +## 7270 +## 7271 +#** 7272 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned. 7273 + * 7274 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7275 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 7276 + * refined to restrict to a given space, or to a given search criteria, etc. 7277 + * @param queryParams The parameters to bind with the query. 7278 + * @param entries The resulting list of entries to display, a list of XDocument names. 7279 + *### 7280 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries) 7281 + #if (!$entries) 7282 + #setVariable (~"$entries~" []) 7283 + #end 7284 + #set($query = ~"$\{query} and isPublished.value = 0~") 7285 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 7286 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 7287 + #bindQueryParameters($countQueryObj $queryParams) 7288 + #bindQueryParameters($queryObj $queryParams) 7289 + #set($totalEntries = $countQueryObj.count()) 7290 + #set($discard = $entries.addAll($queryObj.execute())) 7291 +#end 7292 +## 7293 +## 7294 +## 7295 +#** 7296 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog. 7297 + * 7298 + * @param entries The resulting list of entries to display, a list of XDocument names. 7299 + *### 7300 +#macro(getGlobalBlogEntries $entries) 7301 + #if (!$entries) 7302 + #setVariable (~"$entries~" []) 7303 + #end 7304 + #getAllBlogPostsQuery($query) 7305 + #set($totalEntries = $services.query.hql($query).count()) 7306 + #set($defaultItemsPerPage = 20) 7307 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 7308 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 7309 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute())) 7310 +#end 7311 +#** 7312 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific 7313 + * blog, nor specify a range or an ordering criteria. 7314 + * 7315 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code. 7316 + * 7317 + * @param query The basic query for selecting blog entries. 7318 + *# 7319 +#macro(getBlogEntriesBaseQuery $query) 7320 + #getAllBlogPostsQuery($query) 7321 +#end 7322 +#** 7323 + * Return the Query for selecting the all wiki blog posts without filtering 7324 + * 7325 + * @param query The basic query for selecting blog entries. 7326 + *# 7327 +#macro(getAllBlogPostsQuery $query) 7328 + #set ($query = $NULL) 7329 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished, 7330 + IntegerProperty hidden, DateProperty publishDate 7331 + where doc.fullName <> '$blogPostTemplate' and 7332 + obj.name=doc.fullName and obj.className='$blogPostClassname' and 7333 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and 7334 + hidden.id.id = obj.id and hidden.id.name='hidden' and 7335 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and 7336 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~") 7337 +#end 7338 +## 7339 +## 7340 +## 7341 +###** 7342 + * Return the Query for selecting the all wiki blog posts with categories filtering 7343 + * 7344 + * @param query The basic query for selecting blog entries. 7345 + *### 7346 +#macro(getCategoryAllBlogPostsQuery $query) 7347 + #set ($query = $NULL) 7348 + #getAllBlogPostsQuery($baseQuery) 7349 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList')) 7350 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~") 7351 +#end 7352 +## 7353 +## 7354 +## 7355 +#** 7356 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a 7357 + * week), monthly (all entries in a month), or all. 7358 + * 7359 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt> 7360 + * property set. 7361 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated. 7362 + *### 7363 +#macro(getBlogDisplayType $blogDoc $displayType) 7364 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result) 7365 + #set ($displayType = $NULL) 7366 + #setVariable (~"$displayType~" $result) 7367 +#end 7368 +## 7369 +## 7370 +## 7371 +#** 7372 + * Displays a list of entries. 7373 + * 7374 + * @param entries The entries to display, a list of XDocument names. 7375 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results, 7376 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently 7377 + * used values: index, single, category, search, unpublished, hidden. 7378 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content. 7379 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're 7380 + * displayed alone on their page since it's the page title which is used in this case) 7381 + *### 7382 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles) 7383 + #set($blogDay = '') 7384 + (% class=~"hfeed $!\{displaying}~" ~%)((( 7385 + (% class=~"blogDay~" ~%)((( 7386 + #foreach ($entryDoc in $xwiki.wrapDocs($entries)) 7387 + #getEntryObject($entryDoc $entryObj) 7388 + ## Although all entries should have one of the two objects, better check to be sure. 7389 + #if(~"$!\{entryObj}~" != '') 7390 + #getEntryDate($entryDoc $entryObj $entryDate) 7391 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet. 7392 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd')) 7393 + #if($blogDay != $entryDateStr) 7394 + #if($blogDay != '') 7395 + ))) 7396 + (% class=~"blogDay~" ~%)((( 7397 + #end 7398 + #displayBlogDate($entryDate) 7399 + #set ($blogDay = $entryDateStr) 7400 + #end 7401 + ## Finally, display the entry. 7402 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true) 7403 + #end 7404 + #end 7405 + )))## blogDay 7406 + )))## hfeed 7407 +#end 7408 +## 7409 +## 7410 +## 7411 +#** 7412 + * Get the entry object, either a new BlogPost or an old Article. 7413 + * 7414 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7415 + * @param entryObj The resulting xobject of the blog post. 7416 + *### 7417 +#macro(getEntryObject $entryDoc $__entryObj) 7418 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~")) 7419 + #if(!$result) 7420 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~")) 7421 + #end 7422 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from 7423 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be 7424 + ## overwritten in this case but it's less likely to have such a variable defined before. 7425 + #set ($__entryObj = $NULL) 7426 + #setVariable (~"$__entryObj~" $result) 7427 +#end 7428 +## 7429 +## 7430 +## 7431 +#** 7432 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is 7433 + * the document creation date, but can be edited by the user. 7434 + * 7435 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7436 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7437 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>. 7438 + *### 7439 +#macro(getEntryDate $entryDoc $entryObj $result) 7440 + #set ($result = $NULL) 7441 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value) 7442 +#end 7443 +## 7444 +## 7445 +## 7446 +#** 7447 + * Displays a date, nicely formatted as a calendar page. 7448 + * 7449 + * @param date The date to display, an instance of <tt>java.util.Date</tt>. 7450 + *### 7451 +#macro(displayBlogDate $date) 7452 + #set($year = $xwiki.formatDate($date, 'yyyy')) 7453 + ## 3 letter month name, like Jan, Dec. 7454 + #set($month = $xwiki.formatDate($date, 'MMM')) 7455 + ## Uncomment to get a full length month name, like January, December. 7456 + ## TODO: this could be defined somewhere in the blog style. 7457 + ## #set($month = $xwiki.formatDate($date, 'MMMM')) 7458 + #set($day = $xwiki.formatDate($date, 'dd')) 7459 + (% class=~"blogdate~" ~%) 7460 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) == 7461 +#end 7462 +## 7463 +## 7464 +## 7465 +#** 7466 + * Displays a blog article: management tools, header, content, footer. 7467 + * 7468 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7469 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7470 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 7471 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title 7472 + * when they're displayed alone on their page since it's the page title which is used in this case) 7473 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons 7474 + *### 7475 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions) 7476 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden 7477 + #isPublished($entryObj $isPublished) 7478 + #isHidden($entryObj $isHidden) 7479 + #if($doc.fullName == $entryDoc.fullName) 7480 + (% class=~"hentry single-article~" ~%)((( 7481 + #else 7482 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)((( 7483 + #end 7484 + #if ($shouldDisplayActions) 7485 + #displayEntryTools($entryDoc $entryObj) 7486 + #end 7487 + #if($shouldDisplayTitle) 7488 + #displayEntryTitle($entryDoc $entryObj) 7489 + #end 7490 + #if($doc.fullName == $entryDoc.fullName) 7491 + #if(!$isPublished) 7492 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}} 7493 + #elseif($isHidden) 7494 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}} 7495 + #end 7496 + #end 7497 + #displayEntryContent($entryDoc $entryObj $onlyExtract) 7498 + #displayEntryFooter($entryDoc $entryObj) 7499 + )))## hentry 7500 +#end 7501 +## 7502 +## 7503 +## 7504 +#** 7505 + * Checks if the provided blog is published or not. 7506 + * 7507 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7508 + * @param isPublished The resulting boolean, true if the entry is considered published. 7509 + *### 7510 +#macro(isPublished $entryObj $isPublished) 7511 + #set ($isPublished = $NULL) 7512 + ## This should work for both old articles, which don't have the 'published' property at all, and 7513 + ## are considered published by default, and new entries, that should have 1 if published. 7514 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0') 7515 + #setVariable (~"$isPublished~" true) 7516 + #else 7517 + #setVariable (~"$isPublished~" false) 7518 + #end 7519 +#end 7520 +## 7521 +## 7522 +## 7523 +#** 7524 + * Checks if the provided blog is hidden or not. 7525 + * 7526 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass. 7527 + * @param isHiddel The resulting boolean, true if the entry is considered hidden. 7528 + *### 7529 +#macro(isHidden $entryObj $isHidden) 7530 + #set ($isHidden = $NULL) 7531 + ## This should work for both old articles, which don't have the 'hidden' property at all, and 7532 + ## are considered visible by default, and new entries, that should have 1 if hidden. 7533 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1') 7534 + #setVariable (~"$isHidden~" true) 7535 + #else 7536 + #setVariable (~"$isHidden~" false) 7537 + #end 7538 +#end 7539 +## 7540 +## 7541 +## 7542 +#** 7543 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit. 7544 + * 7545 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7546 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7547 + *### 7548 +#macro(displayEntryTools $entryDoc $entryObj) 7549 + #if($xcontext.action == 'view') 7550 + (% class=~"blog-entry-toolbox~" ~%)((( 7551 + #displayPublishButton($entryDoc $entryObj) 7552 + #displayHideShowButton($entryDoc $entryObj) 7553 + #displayEditButton($entryDoc $entryObj) 7554 + #displayDeleteButton($entryDoc $entryObj) 7555 + ))) 7556 + #end 7557 +#end 7558 +## 7559 +## 7560 +## 7561 +#** 7562 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet. 7563 + * 7564 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7565 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7566 + * @todo AJAX calls. 7567 + *### 7568 +#macro(displayPublishButton $entryDoc $entryObj) 7569 + #isPublished($entryObj $isPublished) 7570 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 7571 + [[#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')~"]]## 7572 + #end 7573 +#end 7574 +## 7575 +## 7576 +## 7577 +#** 7578 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published. 7579 + * 7580 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7581 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7582 + *### 7583 +#macro(displayHideShowButton $entryDoc $entryObj) 7584 + #isPublished($entryObj $isPublished) 7585 + #isHidden($entryObj $isHidden) 7586 + ## Only published articles can be hidden. Unpublished articles are considered already hidden. 7587 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 7588 + #set ($queryString = \{ 7589 + 'xredirect' : $thisURL, 7590 + 'form_token' : $services.csrf.getToken() 7591 + }) 7592 + #if ($isHidden) 7593 + #set ($discard = $queryString.putAll(\{ 7594 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0, 7595 + 'comment' : $services.localization.render('blog.code.madevisible') 7596 + })) 7597 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 7598 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]## 7599 + #else 7600 + #set ($discard = $queryString.putAll(\{ 7601 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1, 7602 + 'comment' : $services.localization.render('blog.code.hid') 7603 + })) 7604 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 7605 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]## 7606 + #end 7607 + #end 7608 +#end 7609 +## 7610 +## 7611 +## 7612 +#** 7613 + * Displays the edit button to those that can edit the article. 7614 + * 7615 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7616 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7617 + *### 7618 +#macro(displayEditButton $entryDoc $entryObj) 7619 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 7620 + ## Call getDefaultEditMode() for backward compatibility with older blog posts. 7621 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]## 7622 + #end 7623 +#end 7624 +## 7625 +## 7626 +## 7627 +#** 7628 + * Displays the delete button to those that can edit the article. 7629 + * 7630 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7631 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7632 + * @todo AJAX calls. 7633 + *### 7634 +#macro(displayDeleteButton $entryDoc $entryObj) 7635 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName)) 7636 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]## 7637 + #end 7638 +#end 7639 +## 7640 +## 7641 +## 7642 +#** 7643 + * Displays the title of the entry. 7644 + * 7645 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7646 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7647 + *### 7648 +#macro(displayEntryTitle $entryDoc $entryObj) 7649 + #if($doc.fullName == $entryDoc.fullName) 7650 + (% class=~"entry-title~" ~%) 7651 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) = 7652 + #else 7653 + (% class=~"entry-title~" ~%) 7654 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] === 7655 + #end 7656 +#end 7657 +## 7658 +## 7659 +## 7660 +#** 7661 + * Displays the body of the entry. 7662 + * 7663 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7664 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7665 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 7666 + *### 7667 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract) 7668 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)((( 7669 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent) 7670 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328 7671 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content 7672 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}} 7673 + ))) ## entry-content 7674 + (% class=~"clearfloats~" ~%)((())) 7675 +#end 7676 +## 7677 +## 7678 +## 7679 +#** 7680 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content 7681 + * of the <tt>extract</tt> field (if not empty). 7682 + * 7683 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7684 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7685 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 7686 + * @param entryContent The resulting content. 7687 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when 7688 + * <tt>onlyExtract</tt> is <tt>true</tt>) 7689 + *### 7690 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis) 7691 + #if ($onlyExtract) 7692 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead 7693 + ## of the content. 7694 + #set ($macro.result = $entryObj.getProperty('extract').value.trim()) 7695 + #end 7696 + #if(~"$!macro.result~" == '') 7697 + #set($macro.result = $entryObj.getProperty('content').value) 7698 +#* Disabled until the content can be cleanly cut. 7699 +* #if($onlyExtract && $result.length()>$maxchars) 7700 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars)) 7701 +* #set($i = $i + 1) 7702 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~") 7703 +* #end 7704 +## *### 7705 + #elseif (!$removeEllipsis) 7706 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0') 7707 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~") 7708 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1') 7709 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~") 7710 + #end 7711 + #end 7712 + #set ($entryContent = $NULL) 7713 + #setVariable (~"$entryContent~" $macro.result) 7714 +#end 7715 +## 7716 +## 7717 +## 7718 +#** 7719 + * Displays the footer of the entry. 7720 + * 7721 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7722 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7723 + *### 7724 +#macro(displayEntryFooter $entryDoc $entryObj) 7725 + (% class=~"entry-footer~" ~%)((( 7726 + #isPublished($entryObj $isPublished) 7727 + (% class='entry-author-label' ~%) 7728 + #if($isPublished) 7729 + \{\{translation key='blog.code.postedby'/}} ## 7730 + #else 7731 + \{\{translation key='blog.code.createdby'/}} ## 7732 + #end 7733 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ## 7734 + #getEntryDate($entryDoc $entryObj $entryDate) 7735 + #listCategories($entryObj) #* 7736 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that 7737 + ## we assume cannot be more than 3 seconds. 7738 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ## 7739 + #if ($showcomments) 7740 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ## 7741 + #end ## 7742 + #if($entryDoc != $doc) ## 7743 + #displayEntryBlogLocation($entryDoc $entryObj) ## 7744 + #end 7745 + )))## entry-footer 7746 +#end 7747 +## 7748 +## 7749 +#** 7750 + * Display the blog for the entry (if it is not the currently displayed blog) 7751 + * 7752 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 7753 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7754 + *### 7755 +#macro(displayEntryBlogLocation $entryDoc $entryObj) 7756 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ## 7757 + #if(~"$!blogPostsLocation~" != ~"~") ## 7758 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ## 7759 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ## 7760 + #if($doc.documentReference != $blogDocRef) ## 7761 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ## 7762 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ## 7763 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ## 7764 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ## 7765 + )))(%~%)## 7766 + #end 7767 + #end 7768 + #end 7769 +#end 7770 +## 7771 +## 7772 +## 7773 +## 7774 +#** 7775 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>. 7776 + * 7777 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 7778 + *### 7779 +#macro(listCategories $entryObj) 7780 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname) 7781 + #set($categories = $entryObj.getProperty('category').value) 7782 + #set($first = true) 7783 + #if($categories.size() > 0) 7784 + #foreach($category in $categories) 7785 + #set($categoryDoc = $!xwiki.getDocument($category)) 7786 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname})) 7787 + #if($foreach.count == 1) 7788 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ## 7789 + #else 7790 + , ## 7791 + #end## 7792 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]## 7793 + #end## 7794 + #end## 7795 + #end 7796 + #end 7797 +#end 7798 +## 7799 +## 7800 +## 7801 +#** 7802 + * Displays blog pagination links (older and newer entries). 7803 + * 7804 + * @param blogDoc the XDocument holding the blog definition object. 7805 + *### 7806 +#macro(displayNavigationLinks $blogDoc) 7807 + (% class=~"clearfloats~" ~%)((())) 7808 + #getBlogDisplayType($blogDoc $displayType) 7809 + #if($displayType == 'weekly') 7810 + (% class=~"pagingLinks~" ~%)((( 7811 + #getRequestedWeek($weekDate) 7812 + $weekDate.addWeeks(-1)## 7813 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 7814 + #sep() 7815 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above 7816 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 7817 + ))) 7818 + #elseif($displayType == 'monthly') 7819 + (% class=~"pagingLinks~" ~%)((( 7820 + #getRequestedMonth($monthDate) 7821 + $monthDate.addMonths(-1)## 7822 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 7823 + #sep() 7824 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above 7825 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 7826 + ))) 7827 + #elseif($displayType == 'all') 7828 + #else 7829 + ## Paginated 7830 + #if(($totalPages > 1)) 7831 + #set($queryString = '') 7832 + #foreach($p in $request.getParameterNames()) 7833 + #if($p != 'page' && $p != 'ipp') 7834 + #foreach($v in $request.getParameterValues($p)) 7835 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~") 7836 + #end 7837 + #end 7838 + #end 7839 + (% class=~"pagingLinks~" ~%)((( 7840 + #if ($currentPageNumber < $totalPages) 7841 + #set($currentPageNumber = $currentPageNumber + 1) 7842 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 7843 + #set($currentPageNumber = $currentPageNumber - 1) 7844 + #end 7845 + #if ($currentPageNumber > 1) 7846 + #if ($currentPageNumber < $totalPages) 7847 + #sep() 7848 + #end 7849 + #set($currentPageNumber = $currentPageNumber - 1) 7850 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 7851 + #set($currentPageNumber = $currentPageNumber + 1) 7852 + #end 7853 + (% class=~"clear~" ~%)(%~%) 7854 + )))## pagingLinks 7855 + #end 7856 + #end 7857 +#end 7858 +## 7859 +## 7860 +## 7861 +#** 7862 + * Displays a message box with ~"publish~" icon. 7863 + * 7864 + * @param message A text message concerning blog article publishing 7865 + *### 7866 +#macro(publishMessageBox $message) 7867 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message))) 7868 +#end 7869 +#** 7870 + * Displays a message box with ~"show/hide~" icon. 7871 + * 7872 + * @param message A text message concerning blog article hiding 7873 + *### 7874 +#macro(hideMessageBox $message) 7875 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message))) 7876 +#end 7877 +## 7878 +## 7879 +## 7880 +#** 7881 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are 7882 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used. 7883 + * 7884 + * @param monthDate The resulting week, a JODATime MutableDateTime. 7885 + *### 7886 +#macro(getRequestedWeek $weekDate) 7887 + #set ($weekDate = $NULL) 7888 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime) 7889 + #if(~"$!\{request.year}~" != '') 7890 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue())) 7891 + #end 7892 + #if(~"$!\{request.week}~" != '') 7893 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue())) 7894 + #end 7895 +#end 7896 +## 7897 +## 7898 +## 7899 +#** 7900 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are 7901 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used. 7902 + * 7903 + * @param monthDate The resulting month, a JODATime MutableDateTime. 7904 + *### 7905 +#macro(getRequestedMonth $monthDate) 7906 + #set ($monthDate = $NULL) 7907 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime) 7908 + #if(~"$!\{request.year}~" != '') 7909 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue())) 7910 + #end 7911 + #if(~"$!\{request.month}~" != '') 7912 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue())) 7913 + #end 7914 +#end 7915 +## 7916 +## 7917 +## 7918 +#** 7919 + * Retrieve a blog property (title, display type, etc). 7920 + * 7921 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7922 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties. 7923 + * @param defaultValue The default value to use in case the blog object does not define one. 7924 + * @param propertyValue The resulting value. 7925 + *### 7926 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue) 7927 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~") 7928 + #if($result == '') 7929 + #set($result = $defaultValue) 7930 + #end 7931 + #set ($propertyValue = $NULL) 7932 + #setVariable (~"$propertyValue~" $result) 7933 +#end 7934 + 7935 +#** 7936 + * If an error occurs when executing an action, set a specific response status and display an error message. 7937 + * 7938 + * @param status The response status. 7939 + * @param text The user readable error to be displayed. Can be a translation key. 7940 + * @param parameters The parameters to use when decoding the translation key. 7941 + *### 7942 +#macro(blog__actionResponseError $status $text $parameters) 7943 + $response.setStatus($status) 7944 + #if($request.ajax) 7945 + $services.localization.render($text, $!parameters) 7946 + #else 7947 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}} 7948 + #end 7949 +#end 7950 +## 7951 +## 7952 +## 7953 +#** 7954 + * Check if a blog is the Default blog (The one in the 'Blog' space). 7955 + * 7956 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 7957 + * @param isDefault The resulting boolean. 7958 + *### 7959 +#macro(isDefaultBlog $blogDoc $isDefault) 7960 + #set ($result = false) 7961 + #if ($blogDoc.space == 'Blog') 7962 + #set ($result = true) 7963 + #end 7964 + #setVariable(~"$isDefault~" $result) 7965 +#end 7966 +## 7967 +## 7968 +## 7969 +#** 7970 + * Retrieve the blog posts location (space). 7971 + * 7972 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 7973 + * @param postsLocation The resulting location. 7974 + *### 7975 +#macro(getBlogPostsLocation $blogSpace $postsLocation) 7976 + #getBlogDocument($blogSpace $blogDoc) 7977 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result) 7978 + #set ($postsLocation = $NULL) 7979 + #setVariable (~"$postsLocation~" $result) 7980 +#end 7981 +## 7982 +## 7983 +## 7984 +#** 7985 + * Retrieve the blog categories location (space). 7986 + * 7987 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 7988 + * @param categoriesLocation The resulting location. 7989 + *### 7990 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation) 7991 + #getBlogDocument($blogSpace $blogDoc) 7992 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result) 7993 + #set ($postsLocation = $NULL) 7994 + #setVariable (~"$categoriesLocation~" $result) 7995 +#end 7996 +###** 7997 + * Return the Query for selecting the blog posts based on the context where the posts are displayed. 7998 + * for example there is 4 different panel contexts: 7999 + * aBlog.aPost or aBlog.WebHome 8000 + * aCategorySpace.aCategory 8001 + * aCategorySpace.WebHome 8002 + * Blog.aPost or Blog.WebHome 8003 + * 8004 + * @param query The query for selecting blog entries. 8005 + * @param queryParams The parameters to bind with the generated query. 8006 + * @param targetDoc The document in which the articles will be displayed. 8007 + *### 8008 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams) 8009 + #set ($query = $NULL) 8010 + #set ($queryParams = $NULL) 8011 + #getCategoryAllBlogPostsQuery($resultQuery) 8012 + #set ($resultQueryParams = \{}) 8013 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 8014 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 8015 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%' 8016 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space)) 8017 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 8018 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~") 8019 + #elseif($targetDoc.getObject($blogCategoryClassname)) 8020 + ## Get all posts that are in a category aCategorySpace.aCategory 8021 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName)) 8022 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~") 8023 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 8024 + ## Get all posts that are in a category aCategorySpace.% 8025 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 8026 + ## Exclude incategorized posts 8027 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~") 8028 + #if ($targetDoc.space == $defaultBlogSpace) 8029 + #set ($excludedCategory = ~"Blog.Categories.WebHome~") 8030 + #end 8031 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory)) 8032 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~") 8033 + #else 8034 + ## Get all posts in blog space aBlog 8035 + #getAllBlogPostsQuery($resultQuery) 8036 + #getBlogPostsLocation($targetDoc.space $postsLocation) 8037 + #set ($discard = $resultQueryParams.put('space', $postsLocation)) 8038 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~") 8039 + #end 8040 + #setVariable(~"$query~" $resultQuery) 8041 + #setVariable(~"$queryParams~" $resultQueryParams) 8042 +#end 8043 +## 8044 +## 8045 +## 8046 +###** 8047 + * Display blog posts based on the context where the posts are displayed. 8048 + * for example there is 4 different panel contexts: 8049 + * aBlog.aPost or aBlog.WebHome 8050 + * aCategorySpace.aCategory 8051 + * aCategorySpace.WebHome 8052 + * Blog.aPost or Blog.WebHome 8053 + * 8054 + * @param targetDoc The document in which the articles will be displayed. 8055 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ... 8056 + * @param layout Layout of the the posts to display 8057 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN' 8058 + * @param limit the number of posts to display 8059 + *### 8060 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit) 8061 + #if ($postLayout == 'full') 8062 + #set ($macro.paginated = 'yes') 8063 + #end 8064 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 8065 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%' 8066 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout) 8067 + #if (~"$!layout~" == '') 8068 + #set ($layout = $postsLayout) 8069 + #end 8070 + #if ($postsVisiblity == 'recent') 8071 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 8072 + #elseif($postsVisiblity == 'unpublished') 8073 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 8074 + #end 8075 + #elseif($targetDoc.getObject($blogCategoryClassname)) 8076 + ## Display all posts that are in a category aCategorySpace.aCategory 8077 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc) 8078 + #getBlogPostsLayout($blogDoc $postsLayout) 8079 + #if (~"$!layout~" == '') 8080 + #set ($layout = $postsLayout) 8081 + #end 8082 + #if ($postsVisiblity == 'recent') 8083 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 8084 + #elseif($postsVisiblity == 'unpublished') 8085 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 8086 + #end 8087 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 8088 + ## Display all posts that are in a category aCategorySpace.% 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.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 8096 + #elseif($postsVisiblity == 'unpublished') 8097 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 8098 + #end 8099 + #else 8100 + ## Display all posts in blog space aBlog 8101 + #getBlogDocument($targetDoc.space $blogDoc) 8102 + #getBlogPostsLayout($blogDoc $postsLayout) 8103 + #if (~"$!layout~" == '') 8104 + #set ($layout = $postsLayout) 8105 + #end 8106 + #if ($postsVisiblity == 'recent') 8107 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 8108 + #elseif($postsVisiblity == 'unpublished') 8109 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 8110 + #end 8111 + #end 8112 +#end 8113 +## 8114 +## 8115 +## 8116 +#** 8117 + * Bind parameters to a query object. 8118 + * 8119 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object) 8120 + * @param queryParams the query parameters. 8121 + *### 8122 +#macro(bindQueryParameters $queryObj $queryParams) 8123 + #set ($output = $queryObj) 8124 + #foreach( $key in $queryParams.keySet() ) 8125 + #set($output = $queryObj.bindValue($key, $queryParams.get($key))) 8126 + #end 8127 + #setVariable(~"$queryObj~" $output) 8128 +#end 8129 +## 8130 +## 8131 +## 8132 +#** 8133 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail 8134 + * 8135 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt> 8136 + * property set. 8137 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default). 8138 + *### 8139 +#macro(getBlogPostsLayout $blogDoc $postsLayout) 8140 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res) 8141 + #set ($postsLayout = $NULL) 8142 + #setVariable (~"$postsLayout~" $res) 8143 +#end 8144 +## 8145 +## 8146 +## 8147 +#** 8148 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space 8149 + * 8150 + * @param categoriesSpace A <tt>String</tt>, the name of the space. 8151 + * @param blogDoc The resulting XDocument. 8152 + *### 8153 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc) 8154 + #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()) 8155 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace) 8156 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0))) 8157 + #else 8158 + ## Fallback to Blog.WebHome, the default blog 8159 + #set($macro.result = $xwiki.getDocument('Blog.WebHome')) 8160 + #end 8161 + #set ($blogDoc = $NULL) 8162 + #setVariable (~"$blogDoc~" $macro.result) 8163 +#end" %) 8164 +((( 8165 +(% class="macro-placeholder hidden" %) 8166 +((( 8167 +macro:velocity 8168 +))) 8169 +))) 8170 +))) 8171 + 8172 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %) 8173 +((( 8174 +(% class="macro-placeholder hidden" %) 8175 +((( 8176 +macro:include 8177 +))) 8178 + 8179 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#** 8180 + * Extract the layout parameters from a string. 8181 + * 8182 + * @param layoutParamsString The string representation of the layout parameters. 8183 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~" 8184 + * @param layoutsParameters The resulting layout parameters Map. 8185 + *### 8186 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters) 8187 + #set ($layoutsParameters = $NULL) 8188 + #set ($macro.layoutParams = \{}) 8189 + #if (~"$!layoutParamsString~" != '') 8190 + #set ($macro.paramsArr = $layoutParamsString.split('\\|')) 8191 + #foreach ($item in $macro.paramsArr) 8192 + #set ($itemSplit = $item.split('=')) 8193 + #if ($itemSplit.size() == 2) 8194 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim())) 8195 + #end 8196 + #end 8197 + #end 8198 + #setVariable(~"$layoutsParameters~" $macro.layoutParams) 8199 +#end" %) 8200 +((( 8201 +(% class="macro-placeholder hidden" %) 8202 +((( 8203 +macro:velocity 8204 +))) 8205 +))) 8206 +))) 8207 + 8208 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj) 8209 + #initLayoutVars($pDoc $pObj) 8210 + <div class=~"col-xs-12 col-sm-6 next_blog~"> 8211 + <a href=~"$pDoc.uRL~" class=~"thumbnail~"> 8212 + <div class=~"row~"> 8213 + <div class=~"col-xs-4~"> 8214 + #if ($imageAtt) 8215 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 8216 + #end 8217 + </div> 8218 + <div class=~"col-xs-8 art_det~"> 8219 + <p class=~"text-left~"> 8220 + #if($displayTitle)$!postTitle #end 8221 + <br/><span class=~"date_info~"> $!dateStr </span> 8222 + </p> 8223 + #displayPostDetails($pDoc) 8224 + </div> 8225 + </div> 8226 + </a> 8227 + </div> 8228 + #end 8229 + ## 8230 + ## 8231 + ## 8232 + #macro(displayPinnedPost $pDoc $pObj) 8233 + #initLayoutVars($pDoc $pObj) 8234 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~"> 8235 + <a href=~"$pDoc.uRL~" class=~"all-post-link~"> 8236 + <div class=~"thumbnail~"> 8237 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts) 8238 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 8239 + #end 8240 + #if ($imageAtt) 8241 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 8242 + #end 8243 + <div class=~"caption~"> 8244 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts) 8245 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 8246 + #end 8247 + #if ($displaySummaryOnPinnedPosts) 8248 + <div class=~"text-left post-summary~"> 8249 + #set ($postContent = $pObj.getProperty('extract').value) 8250 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString()) 8251 + </div> 8252 + #end 8253 + #displayPostDetails($pDoc) 8254 + </div> 8255 + </div> 8256 + </a> 8257 + </div> 8258 + #end 8259 + ## 8260 + ## 8261 + ## 8262 + #macro(formatPostDate $pDoc $pObj) 8263 + #set ($formattedDate = $NULL) 8264 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale)) 8265 + #if (~"$!dateStr~" != '') 8266 + #set ($dateArr = $dateStr.split(' ')) 8267 + #if ($dateArr.size() > 3) 8268 + #set ($dateStr = ~"~") 8269 + #foreach($s in $dateArr.subList(0, 3)) 8270 + #set ($dateStr = ~"$\{dateStr}$\{s} ~") 8271 + #end 8272 + #end 8273 + #end 8274 + #setVariable(~"$formattedDate~" $dateStr) 8275 + #end 8276 + ## 8277 + ## 8278 + ## 8279 + #macro(displayPostDetails $pDoc) 8280 + <div class=~"row post-details~"> 8281 + <div class=~"col-xs-8 detail~"> 8282 + #if ($services.like.displayButton($pDoc.documentReference)) 8283 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference)) 8284 + ## Retrieve the likes number in XWiki 12.9+ 8285 + #set ($likeNumber = $optLikeRecord.get()) 8286 + #if (!$stringtool.isNumeric($likeNumber.toString())) 8287 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9. 8288 + #set ($likeNumber = $optLikeRecord.get().likeNumber) 8289 + #end 8290 + #if ($stringtool.isNumeric($likeNumber.toString())) 8291 + <div class=~"post-likes btn btn-default disabled badge~" 8292 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~"> 8293 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span> 8294 + </div> 8295 + #end 8296 + #elseif ($services.ratings) 8297 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference)) 8298 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1) 8299 + <ul class=~"pull-left note list-inline~"> 8300 + #foreach ($x in [1..5]) 8301 + #set ($cls = ~"~") 8302 + #if ($x > $averageVote) 8303 + #set ($cls = ~"-o~") 8304 + #end 8305 + <li><span class=~"fa fa-star$\{cls}~"></span></li> 8306 + #end 8307 + </ul> 8308 + #end 8309 + #end 8310 + </div> 8311 + #if ($showPostComments) 8312 + <div class=~"col-xs-4 com_det~"> 8313 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p> 8314 + </div> 8315 + #end 8316 + </div> 8317 + #end 8318 + ## 8319 + ## 8320 + ## 8321 + #macro(initLayoutVars $pDoc $pObj) 8322 + #set ($postTitle = $pDoc.display('title', 'view', $pObj)) 8323 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image'))) 8324 + #isPublished($pObj $isPublished) 8325 + #isHidden($pObj $isHidden) 8326 + #getEntryDate($pDoc $pObj $postDate) 8327 + #formatPostDate($postDate $dateStr) 8328 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote())) 8329 + #set ($nbComments = $pDoc.getComments().size()) 8330 + #set ($showPostComments = true) 8331 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0') 8332 + #set ($showPostComments = false) 8333 + #end 8334 + #end 8335 + ## 8336 + ## 8337 + ## 8338 + #macro(displayEditPinnedPostsButton) 8339 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName)) 8340 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet')) 8341 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet')) 8342 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet')) 8343 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~")) 8344 + <div class=~"edit-pinned-posts-container~"> 8345 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~"> 8346 + <a href=~"javascript:;~" class=~"editPinnedPosts~"> 8347 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit') 8348 + </a> 8349 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/> 8350 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/> 8351 + </div> 8352 + </div> 8353 + #if (~"$!pinnedPostsObj~" == '') 8354 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/> 8355 + #end 8356 + #end 8357 + #end" %) 8358 +((( 8359 +(% class="macro-placeholder hidden" %) 8360 +((( 8361 +macro:velocity 8362 +))) 8363 +))) 8364 + 8365 +(% data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference)) 8366 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference)) 8367 + #getEntryObject($postDoc $postObj) 8368 + #if (~"$!postObj~" != '') 8369 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams) 8370 + ## 8371 + #set ($displayTitle = true) 8372 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false') 8373 + #set ($displayTitle = false) 8374 + #end 8375 + ## 8376 + #set ($displayTitleFirstOnPinnedPosts = false) 8377 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true') 8378 + #set ($displayTitleFirstOnPinnedPosts = true) 8379 + #end 8380 + ## 8381 + #set ($displaySummaryOnPinnedPosts = true) 8382 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false') 8383 + #set ($displaySummaryOnPinnedPosts = false) 8384 + #end 8385 + ## 8386 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue()) 8387 + #if ($postIndex == 0) 8388 + #set ($stopBlogPostsDisplay = false) 8389 + #end 8390 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue()) 8391 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards')) 8392 + #set($scaleWidth = 600) 8393 + #set($imgQs=~"width=$scaleWidth~") 8394 + ## Display pinned posts 8395 + ## Get the list of pinned posts 8396 + #set ($pinnedPosts = []) 8397 + #set ($pinnedPostsSourceDoc = $NULL) 8398 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '') 8399 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog'))) 8400 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro 8401 + #end 8402 + #if (~"$!pinnedPostsSourceDoc~" != '') 8403 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass')) 8404 + #if (~"$!pinnedPostsObj~" != '') 8405 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value) 8406 + #if (~"$!orderedPinnedPostsJSON~" != '') 8407 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON)) 8408 + #else 8409 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value) 8410 + #end 8411 + #end 8412 + #if ($postIndex == 0 && $pinnedPosts.size() > 0) 8413 + \{\{html clean=~"false~"}} 8414 + #set ($x = 0) 8415 + #set ($showPinnedPostsButton = true) 8416 + #foreach ($pinnedPost in $pinnedPosts) 8417 + #if ($x == 0) 8418 + <div class=~"row flex-container~"> 8419 + #if ($showPinnedPostsButton) 8420 + #displayEditPinnedPostsButton() 8421 + #set($showPinnedPostsButton = false) 8422 + #end 8423 + #end 8424 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost)) 8425 + #getEntryObject($pinnedPostDoc $pinnedPostObj) 8426 + #if (~"$!pinnedPostObj~" != '') 8427 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj) 8428 + #end 8429 + #set ($x = $mathtool.add($x, 1)) 8430 + #if ($x == 3) 8431 + #set ($x = 0) 8432 + </div> 8433 + #end 8434 + #end 8435 + #if ($mathtool.mod($x, 3) != 0) 8436 + </div> 8437 + #end 8438 + \{\{/html}} 8439 + 8440 + ## If the first post is a pinned post : this means that all the posts are pinned 8441 + ## In this case, avoid displaying the posts again after the pinned posts section. 8442 + #if ($pinnedPosts.contains($xcontext.macro.params.reference)) 8443 + #set ($stopBlogPostsDisplay = true) 8444 + #end 8445 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0) 8446 + 8447 + \{\{html}} 8448 + <div class=~"row no-pinnded-posts~"> 8449 + #displayEditPinnedPostsButton() 8450 + </div> 8451 + \{\{/html}} 8452 + 8453 + #end 8454 + #end 8455 + #if (!$stopBlogPostsDisplay) 8456 + \{\{html clean=~"false~"}} 8457 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0) 8458 + #set ($nbDisplayedPosts = 0) 8459 + #end 8460 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0) 8461 + #if ($nbDisplayedPosts != 0) 8462 + </div> 8463 + #set ($lastHtmlTag = 'c') 8464 + #end 8465 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 8466 + <div class=~"row~"> 8467 + #set ($lastHtmlTag = 'o') 8468 + #set ($lastRowClass = ~"~") 8469 + #else 8470 + <div class=~"row flex-container~"> 8471 + #set ($lastHtmlTag = 'o') 8472 + #set ($lastRowClass = ~"flex~") 8473 + #end 8474 + #end 8475 + #displaySmallPost($postDoc $postObj) 8476 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 8477 + </div> 8478 + #set ($lastHtmlTag = 'c') 8479 + #end 8480 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1)) 8481 + #if ($postIndex == $mathtool.sub($listResultsCount, 1)) 8482 + #if (~"$!lastHtmlTag~" == 'o') 8483 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~") 8484 + <div class=~"col-xs-12 col-sm-6~"></div> 8485 + #end 8486 + </div> 8487 + #end 8488 + #end 8489 + \{\{/html}} 8490 + #end 8491 + #else 8492 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}} 8493 + #end 8494 + #else 8495 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}} 8496 + #end" class="macro hidden macro-placeholder" %)macro:velocity(% data-macro="startmacro:html|-|clean=~"false~"|-|</div> 8497 +<div class=~"row flex-container~"> 8498 +<div class=~"col-xs-12 col-sm-6 next_blog~"> 8499 +<a href=~"/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden~" class=~"thumbnail~"> 8500 +<div class=~"row~"> 8501 +<div class=~"col-xs-4~"> 8502 +<img src=~"/download/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden/OIP.jpg?width=600&rev=1.1~" /> 8503 +</div> 8504 +<div class=~"col-xs-8 art_det~"> 8505 +<p class=~"text-left~"> 8506 +Feestelijke afsluiting, keuring materieel en tellen voorraden <br/><span class=~"date_info~"> 14 dec. 2023 </span> 8507 +</p> 8508 +<div class=~"row post-details~"> 8509 +<div class=~"col-xs-8 detail~"> 8510 +<div class=~"post-likes btn btn-default disabled badge~" 8511 +title=~"Number of likes on this page: 1~"> 8512 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">1</span> 8513 +</div> 8514 +</div> 8515 +<div class=~"col-xs-4 com_det~"> 8516 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p> 8517 +</div> 8518 +</div> 8519 +</div> 8520 +</div> 8521 +</a> 8522 +</div>" class="macro macro hidden macro-placeholder" %)macro:html 8523 +))) 8524 +))) 8525 + 8526 +(% class="row flex-container" %) 8527 +((( 8528 +(% class="col-xs-12 col-sm-6 next_blog" %) 8529 +((( 8530 +(% class="row" %) 8531 +((( 8532 +(% class="col-xs-4" %) 8533 +((( 8534 +[[~[~[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"]] 8535 +))) 8536 + 8537 +(% class="col-xs-8 art_det" %) 8538 +((( 8539 +(% class="text-left" %) 8540 +[[Feestelijke afsluiting, keuring materieel en tellen voorraden 8541 +(% class="date_info" %) 14 dec. 2023>>path:/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden||class="thumbnail"]] 8542 + 8543 +(% class="row post-details" %) 8544 +((( 8545 +(% class="col-xs-8 detail" %) 8546 +((( 8547 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 1" %) 8548 +((( 8549 +[[(% class="like-number" %)1>>path:/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden||class="thumbnail"]] 8550 +))) 8551 +))) 8552 + 8553 +(% class="col-xs-4 com_det" %) 8554 +((( 8555 +(% class="text-right" %) 8556 +[[(0)>>path:/Nieuws/Feestelijke%20afsluiting%2C%20keuring%20materieel%20en%20tellen%20voorraden||class="thumbnail"]] 8557 +))) 8558 +))) 8559 +))) 8560 +))) 8561 +))) 8562 + 8563 +(% class="macro" data-macro="startmacro:blogPostLayoutCards|-|reference=~"Nieuws.RI&E 2023~" params=~"displayTitle=true|useSummary=true|list-limit=6|list-layout=cards|list-blog=Nieuws.WebHome|list-paginated=no|list-results-count=6|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~"" %) 8564 +((( 8565 +(% class="macro-placeholder hidden" %) 8566 +((( 8567 +macro:blogPostLayoutCards 8568 +))) 8569 + 8570 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogCode~"" %) 8571 +((( 8572 +(% class="macro-placeholder hidden" %) 8573 +((( 8574 +macro:include 8575 +))) 8576 + 8577 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogParameters~"" %) 8578 +((( 8579 +(% class="macro-placeholder hidden" %) 8580 +((( 8581 +macro:include 8582 +))) 8583 + 8584 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## Blog 8585 +#set($blogClassname = 'Blog.BlogClass') 8586 +#set($blogTemplate = 'Blog.BlogTemplate') 8587 +#set($blogSheet = 'Blog.BlogSheet') 8588 +## Blog entries 8589 +#set($blogPostClassname = 'Blog.BlogPostClass') 8590 +#set($blogPostTemplate = 'Blog.BlogPostTemplate') 8591 +#set($blogPostSheet = 'Blog.BlogPostSheet') 8592 +#set($blogPostObjectNumber = $xwiki.getDocument($blogPostTemplate).getObject($blogPostClassname).number) 8593 +#set($oldArticleClassname = 'XWiki.ArticleClass') 8594 +## Categories 8595 +#set($blogCategoryClassname = 'Blog.CategoryClass') 8596 +#set($blogCategoryTemplate = 'Blog.CategoryTemplate') 8597 +#set($blogCategorySheet = 'Blog.CategorySheet') 8598 +#set($blogCategoriesSheet = 'Blog.CategoriesSheet') 8599 +#set($oldBlogCategoryClassname = 'Blog.Categories') 8600 +#set($defaultCategoryParent = 'Blog.Categories') 8601 +## Style 8602 +#set($blogStyleDocumentName = 'Blog.BlogStyle') 8603 +#set($blogStyleDocument = $xwiki.getDocument($blogStyleDocumentName)) 8604 +## Clientside scripts 8605 +#set($blogScriptsDocumentName = 'Blog.BlogScripts') 8606 +#set($blogPublisher = $xwiki.getDocument('Blog.Publisher')) 8607 +## Misc 8608 +#set($thisURL = $doc.getURL($xcontext.action, $request.queryString)) 8609 +#set($isBlogPost = $doc.getObject($blogPostClassname)) 8610 +#set($defaultBlogSpace = 'Blog') 8611 +#set($isCategoryPage = $doc.getObject($blogCategoryClassname)) 8612 +#set($isCategoriesHomePage = $doc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 8613 +## 8614 +## 8615 +## 8616 +#** 8617 + * Displays an image, taken from the blog style document. 8618 + * 8619 + * @param $imgName The name of the icon from icons set to use. 8620 + *# 8621 +#macro(toolImage $imgName)(% class=~"icon-manage~"~%)$services.icon.render($imgName)(%~%)#end" %) 8622 +((( 8623 +(% class="macro-placeholder hidden" %) 8624 +((( 8625 +macro:velocity 8626 +))) 8627 +))) 8628 +))) 8629 + 8630 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|## 8631 +## 8632 +## 8633 +## Import the blog skin and javascripts. 8634 +$!xwiki.ssx.use($blogStyleDocumentName)## 8635 +$!xwiki.jsx.use($blogScriptsDocumentName)## 8636 +## 8637 +## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation) 8638 +#template('hierarchy_macros.vm')## 8639 +## 8640 +## 8641 +#** 8642 + * Prints a blog. This is the main macro used in the BlogSheet. 8643 + * 8644 + * @param blogDoc the XDocument holding the blog definition object. 8645 + *### 8646 +#macro(printBlog $blogDoc) 8647 + \{\{include reference='Blog.CreatePost'/}} 8648 + 8649 + ## Use the blogPostList macro to display the blogposts 8650 + ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro 8651 + ## do not support FTM the monthly and weekly blog display types 8652 + #getBlogDisplayType($blogDoc $displayType) 8653 + #if ($displayType == 'weekly' || $displayType == 'monthly') 8654 + #getBlogEntries($blogDoc $entries) 8655 + #displayBlog($entries 'index' true true) 8656 + #displayNavigationLinks($blogDoc) 8657 + #else 8658 + #getBlogDisplayType($blogDoc $displayType) 8659 + #set ($paginated = 'no') 8660 + #if ($displayType == 'paginated') 8661 + #set ($paginated = 'yes') 8662 + #end 8663 + #getBlogPostsLayout($blogDoc $postsLayout) 8664 + (% class=~"hfeed index~" ~%)(((\{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$paginated~" layout=~"$!postsLayout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" /}}))) 8665 + #end 8666 +#end 8667 +## 8668 +## 8669 +## 8670 +#** 8671 + * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title, 8672 + * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index, 8673 + * all entries). 8674 + * 8675 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 8676 + *### 8677 +#macro(showBlogInfo $blogDoc) 8678 + #if($blogDoc.getObject($blogClassname)) 8679 + ## Keep testing for inline action for backward compatibility with older blogs. 8680 + #if($xcontext.action == 'edit' || $xcontext.action == 'inline') 8681 + #macro(displayProperty $blogDoc $propname) 8682 + ; #displayPropName($xwiki.getClass($blogClassname).get($propname)): 8683 + : $blogDoc.display($propname) 8684 + #end 8685 + #displayProperty($blogDoc 'title') 8686 + #displayProperty($blogDoc 'description') 8687 + #displayProperty($blogDoc 'displayType') 8688 + #displayProperty($blogDoc 'itemsPerPage') 8689 + #displayProperty($blogDoc 'postsLayout') 8690 + #displayProperty($blogDoc 'postsLayoutParameters') 8691 + #else 8692 + $blogDoc.display('description') 8693 + #end 8694 + #elseif($doc.fullName == $blogSheet) 8695 += $services.localization.render('blog.code.blogsheet') = 8696 + \{\{translation key='blog.code.sheetexplanation'/}} 8697 + #else 8698 + \{\{warning}}\{\{translation key='blog.code.notblog'/}}\{\{/warning}} 8699 + #end 8700 +#end 8701 +## 8702 +## 8703 +## 8704 +#** 8705 + * Retrieve the blog document, which usually is either <tt><Space>.WebHome</tt> for whole-spaces blogs, or 8706 + * <tt><Space>.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first 8707 + * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current 8708 + * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog. 8709 + * 8710 + * @param space A <tt>String</tt>, the name of the space where to search. 8711 + * @param blogDoc The resulting XDocument. 8712 + *### 8713 +#macro(getBlogDocument $space $blogDoc) 8714 + #set ($result = $NULL) 8715 + ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object. 8716 + ## 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 8717 + ## identify the right blog based on a configuration object in a WebPreferences page. 8718 + #set ($spaceReference = $services.model.resolveSpace($space)) 8719 + #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference)) 8720 + #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef)) 8721 + #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass')) 8722 + #if ($preferencesObj) 8723 + #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog'))) 8724 + #end 8725 + ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy. 8726 + #if (~"$!result~" == '') 8727 + ## First, try the Space.WebHome, for a whole-space blog 8728 + #set($result = $xwiki.getDocument(~"$\{space}.WebHome~")) 8729 + #if(!$result.getObject($blogClassname)) 8730 + ## Second, try the Space.Blog document 8731 + #set($result = $xwiki.getDocument(~"$\{space}.Blog~")) 8732 + #if(!$result.getObject($blogClassname)) 8733 + ## Third, try searching for a blog document in the current space 8734 + ## Prevent the query fail when the space contains dots '.' 8735 + #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()) 8736 + #if($blogDocs.size() > 0) 8737 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 8738 + #else 8739 + ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space 8740 + #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()) 8741 + #if($blogDocs.size() > 0) 8742 + #set($result = $xwiki.getDocument($blogDocs.get(0))) 8743 + #else 8744 + ## Last, fallback to Blog.WebHome, the default blog 8745 + #set($result = $xwiki.getDocument('Blog.WebHome')) 8746 + #end 8747 + #end 8748 + #end 8749 + #end 8750 + #end 8751 + #set ($blogDoc = $NULL) 8752 + #setVariable (~"$blogDoc~" $result) 8753 +#end 8754 +## 8755 +## 8756 +## 8757 +#** 8758 + * Retrieve the blog title. 8759 + * 8760 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set. 8761 + * @param title The resulting title. 8762 + *### 8763 +#macro(getBlogTitle $blogDoc $title) 8764 + ## Titles can contain velocity code (most commonly translations), so we should evaluate them. 8765 + #set ($title = $NULL) 8766 + #setVariable (~"$title~" $!blogDoc.displayTitle) 8767 +#end 8768 +## 8769 +## 8770 +## 8771 +#** 8772 + * Retrieve the blog description. 8773 + * 8774 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt> 8775 + * property set. 8776 + * @param description The resulting description. 8777 + *### 8778 +#macro(getBlogDescription $blogDoc $description) 8779 + #getBlogProperty($blogDoc 'description' '' $result) 8780 + #set ($description = $NULL) 8781 + #setVariable (~"$description~" $result) 8782 +#end 8783 +## 8784 +## 8785 +## 8786 +#** 8787 + * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog 8788 + * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on 8789 + * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a 8790 + * month), or all. 8791 + * 8792 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 8793 + * @param entries The resulting list of entries to display, a list of XDocument names. 8794 + *### 8795 +#macro(getBlogEntries $blogDoc $entries) 8796 + #if (!$entries) 8797 + #setVariable (~"$entries~" []) 8798 + #end 8799 + #getAllBlogPostsQuery($query) 8800 + #isDefaultBlog($blogDoc $isDefault) 8801 + #set($queryParams = \{}) 8802 + #if ($isDefault) 8803 + #getCategoryAllBlogPostsQuery($query) 8804 + #set($query = ~"$\{query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')~") 8805 + #set($discard = $queryParams.put('creator', $xcontext.user)) 8806 + #set($discard = $queryParams.put('space', $blogDoc.space)) 8807 + #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 8808 + #set($discard = $queryParams.put('catList', $sanitizedBlogSpace)) 8809 + #else 8810 + #set($query = ~"$\{query} and (doc.space = :space or doc.parent = :parent)~") 8811 + #getBlogPostsLocation($blogDoc.space $blogPostsLocation) 8812 + #set($discard = $queryParams.put('space', $blogPostsLocation)) 8813 + #set($discard = $queryParams.put('parent', $blogDoc.space)) 8814 + #end 8815 + #getBlogDisplayType($blogDoc $displayType) 8816 + #if($displayType == 'weekly') 8817 + #getWeeklyBlogEntries($blogDoc $query $entries $queryParams) 8818 + #elseif($displayType == 'monthly') 8819 + #getMonthlyBlogEntries($blogDoc $query $entries $queryParams) 8820 + #elseif($displayType == 'all') 8821 + #getAllBlogEntries($blogDoc $query $entries $queryParams) 8822 + #else 8823 + #getPagedBlogEntries($blogDoc $query $entries $queryParams) 8824 + #end 8825 +#end 8826 +## 8827 +## 8828 +## 8829 +#** 8830 + * Retrieves a list of entries to be displayed. The entries are taken from a ~"page~" of the blog, a sequence of documents 8831 + * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the 8832 + * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property 8833 + * (10 if not defined). 8834 + * 8835 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 8836 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 8837 + * refined to restrict to a given space, or to a given search criteria, etc. 8838 + * @param entries The resulting list of entries to display, a list of XDocument names. 8839 + * @param queryParams The parameters to bind with the query. 8840 + *### 8841 +#macro(getPagedBlogEntries $blogDoc $query $entries $queryParams) 8842 + #if (!$entries) 8843 + #setVariable (~"$entries~" []) 8844 + #end 8845 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 8846 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~")) 8847 + #bindQueryParameters($countQueryObj $queryParams) 8848 + #bindQueryParameters($queryObj $queryParams) 8849 + #set($totalEntries = $countQueryObj.count()) 8850 + #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage) 8851 + #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue()) 8852 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 8853 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 8854 + #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter(~"unique~").execute())) 8855 +#end 8856 +## 8857 +## 8858 +## 8859 +#** 8860 + * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is 8861 + * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4 8862 + * digit year). Initially the current week is displayed. 8863 + * 8864 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 8865 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 8866 + * refined to restrict to a given space, or to a given search criteria, etc. 8867 + * @param entries The resulting list of entries to display, a list of XDocument names. 8868 + * @param queryParams The parameters to bind with the query. 8869 + *### 8870 +#macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams) 8871 + #if (!$entries) 8872 + #setVariable (~"$entries~" []) 8873 + #end 8874 + #getRequestedWeek($weekDate) 8875 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 8876 + #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor())) 8877 + #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling())) 8878 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 8879 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 8880 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 8881 + #bindQueryParameters($countQueryObj $queryParams) 8882 + #bindQueryParameters($queryObj $queryParams) 8883 + #set($totalEntries = $countQueryObj.count()) 8884 + #set($discard = $entries.addAll($queryObj.execute())) 8885 +#end 8886 +## 8887 +## 8888 +## 8889 +#** 8890 + * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is 8891 + * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4 8892 + * digit year). Initially the current month is displayed. 8893 + * 8894 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 8895 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 8896 + * refined to restrict to a given space, or to a given search criteria, etc. 8897 + * @param entries The resulting list of entries to display, a list of XDocument names. 8898 + * @param queryParams The parameters to bind with the query. 8899 + *### 8900 +#macro(getMonthlyBlogEntries $blogDoc $query $entries) 8901 + #if (!$entries) 8902 + #setVariable (~"$entries~" []) 8903 + #end 8904 + #getRequestedMonth($monthDate) 8905 + #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) 8906 + #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor())) 8907 + #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling())) 8908 + #set($query = ~"$\{query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'~") 8909 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 8910 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 8911 + #bindQueryParameters($countQueryObj $queryParams) 8912 + #bindQueryParameters($queryObj $queryParams) 8913 + #set($totalEntries = $countQueryObj.count()) 8914 + #set($discard = $entries.addAll($queryObj.execute())) 8915 +#end 8916 +## 8917 +## 8918 +## 8919 +#** 8920 + * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned. 8921 + * 8922 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 8923 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 8924 + * refined to restrict to a given space, or to a given search criteria, etc. 8925 + * @param entries The resulting list of entries to display, a list of XDocument names. 8926 + * @param queryParams The parameters to bind with the query. 8927 + *### 8928 +#macro(getAllBlogEntries $blogDoc $query $entries $queryParams) 8929 + #if (!$entries) 8930 + #setVariable (~"$entries~" []) 8931 + #end 8932 + #set($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 8933 + #set($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 8934 + #bindQueryParameters($countQueryObj $queryParams) 8935 + #bindQueryParameters($queryObj $queryParams) 8936 + #set($totalEntries = $countQueryObj.count()) 8937 + #set($discard = $entries.addAll($queryObj.execute())) 8938 +#end 8939 +## 8940 +## 8941 +## 8942 +#** 8943 + * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned. 8944 + * 8945 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 8946 + * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be 8947 + * refined to restrict to a given space, or to a given search criteria, etc. 8948 + * @param queryParams The parameters to bind with the query. 8949 + * @param entries The resulting list of entries to display, a list of XDocument names. 8950 + *### 8951 +#macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries) 8952 + #if (!$entries) 8953 + #setVariable (~"$entries~" []) 8954 + #end 8955 + #set($query = ~"$\{query} and isPublished.value = 0~") 8956 + #set ($countQueryObj = $services.query.hql($query).addFilter(~"unique~")) 8957 + #set ($queryObj = $services.query.hql(~"$\{query} order by publishDate.value desc~").addFilter(~"unique~")) 8958 + #bindQueryParameters($countQueryObj $queryParams) 8959 + #bindQueryParameters($queryObj $queryParams) 8960 + #set($totalEntries = $countQueryObj.count()) 8961 + #set($discard = $entries.addAll($queryObj.execute())) 8962 +#end 8963 +## 8964 +## 8965 +## 8966 +#** 8967 + * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog. 8968 + * 8969 + * @param entries The resulting list of entries to display, a list of XDocument names. 8970 + *### 8971 +#macro(getGlobalBlogEntries $entries) 8972 + #if (!$entries) 8973 + #setVariable (~"$entries~" []) 8974 + #end 8975 + #getAllBlogPostsQuery($query) 8976 + #set($totalEntries = $services.query.hql($query).count()) 8977 + #set($defaultItemsPerPage = 20) 8978 + ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. 8979 + #preparePagedViewParams($totalEntries $defaultItemsPerPage) 8980 + #set($discard = $entries.addAll($services.query.hql(~"$\{query} order by publishDate.value desc~").setLimit($itemsPerPage).setOffset($startAt).execute())) 8981 +#end 8982 +#** 8983 + * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific 8984 + * blog, nor specify a range or an ordering criteria. 8985 + * 8986 + * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code. 8987 + * 8988 + * @param query The basic query for selecting blog entries. 8989 + *# 8990 +#macro(getBlogEntriesBaseQuery $query) 8991 + #getAllBlogPostsQuery($query) 8992 +#end 8993 +#** 8994 + * Return the Query for selecting the all wiki blog posts without filtering 8995 + * 8996 + * @param query The basic query for selecting blog entries. 8997 + *# 8998 +#macro(getAllBlogPostsQuery $query) 8999 + #set ($query = $NULL) 9000 + #setVariable(~"$query~" ~", BaseObject as obj, IntegerProperty isPublished, 9001 + IntegerProperty hidden, DateProperty publishDate 9002 + where doc.fullName <> '$blogPostTemplate' and 9003 + obj.name=doc.fullName and obj.className='$blogPostClassname' and 9004 + isPublished.id.id = obj.id and isPublished.id.name = 'published' and 9005 + hidden.id.id = obj.id and hidden.id.name='hidden' and 9006 + publishDate.id.id = obj.id and publishDate.id.name='publishDate' and 9007 + (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))~") 9008 +#end 9009 +## 9010 +## 9011 +## 9012 +###** 9013 + * Return the Query for selecting the all wiki blog posts with categories filtering 9014 + * 9015 + * @param query The basic query for selecting blog entries. 9016 + *### 9017 +#macro(getCategoryAllBlogPostsQuery $query) 9018 + #set ($query = $NULL) 9019 + #getAllBlogPostsQuery($baseQuery) 9020 + #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList')) 9021 + #setVariable(~"$query~" ~"$\{baseQuery} and obj.id=category.id.id and category.id.name='category'~") 9022 +#end 9023 +## 9024 +## 9025 +## 9026 +#** 9027 + * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a 9028 + * week), monthly (all entries in a month), or all. 9029 + * 9030 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt> 9031 + * property set. 9032 + * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated. 9033 + *### 9034 +#macro(getBlogDisplayType $blogDoc $displayType) 9035 + #getBlogProperty($blogDoc 'displayType' 'paginated' $result) 9036 + #set ($displayType = $NULL) 9037 + #setVariable (~"$displayType~" $result) 9038 +#end 9039 +## 9040 +## 9041 +## 9042 +#** 9043 + * Displays a list of entries. 9044 + * 9045 + * @param entries The entries to display, a list of XDocument names. 9046 + * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results, 9047 + * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently 9048 + * used values: index, single, category, search, unpublished, hidden. 9049 + * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content. 9050 + * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're 9051 + * displayed alone on their page since it's the page title which is used in this case) 9052 + *### 9053 +#macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles) 9054 + #set($blogDay = '') 9055 + (% class=~"hfeed $!\{displaying}~" ~%)((( 9056 + (% class=~"blogDay~" ~%)((( 9057 + #foreach ($entryDoc in $xwiki.wrapDocs($entries)) 9058 + #getEntryObject($entryDoc $entryObj) 9059 + ## Although all entries should have one of the two objects, better check to be sure. 9060 + #if(~"$!\{entryObj}~" != '') 9061 + #getEntryDate($entryDoc $entryObj $entryDate) 9062 + ## Display a ~"calendar sheet~" for each day. All entries posted on the same day share one such sheet. 9063 + #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd')) 9064 + #if($blogDay != $entryDateStr) 9065 + #if($blogDay != '') 9066 + ))) 9067 + (% class=~"blogDay~" ~%)((( 9068 + #end 9069 + #displayBlogDate($entryDate) 9070 + #set ($blogDay = $entryDateStr) 9071 + #end 9072 + ## Finally, display the entry. 9073 + #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true) 9074 + #end 9075 + #end 9076 + )))## blogDay 9077 + )))## hfeed 9078 +#end 9079 +## 9080 +## 9081 +## 9082 +#** 9083 + * Get the entry object, either a new BlogPost or an old Article. 9084 + * 9085 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9086 + * @param entryObj The resulting xobject of the blog post. 9087 + *### 9088 +#macro(getEntryObject $entryDoc $__entryObj) 9089 + #set($result = $entryDoc.getObject(~"$\{blogPostClassname}~")) 9090 + #if(!$result) 9091 + #set($result = $entryDoc.getObject(~"$\{oldArticleClassname}~")) 9092 + #end 9093 + ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from 9094 + ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be 9095 + ## overwritten in this case but it's less likely to have such a variable defined before. 9096 + #set ($__entryObj = $NULL) 9097 + #setVariable (~"$__entryObj~" $result) 9098 +#end 9099 +## 9100 +## 9101 +## 9102 +#** 9103 + * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is 9104 + * the document creation date, but can be edited by the user. 9105 + * 9106 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9107 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9108 + * @param result The resulting date, an instance of <tt>java.util.Date</tt>. 9109 + *### 9110 +#macro(getEntryDate $entryDoc $entryObj $result) 9111 + #set ($result = $NULL) 9112 + #setVariable (~"$result~" $entryObj.getProperty('publishDate').value) 9113 +#end 9114 +## 9115 +## 9116 +## 9117 +#** 9118 + * Displays a date, nicely formatted as a calendar page. 9119 + * 9120 + * @param date The date to display, an instance of <tt>java.util.Date</tt>. 9121 + *### 9122 +#macro(displayBlogDate $date) 9123 + #set($year = $xwiki.formatDate($date, 'yyyy')) 9124 + ## 3 letter month name, like Jan, Dec. 9125 + #set($month = $xwiki.formatDate($date, 'MMM')) 9126 + ## Uncomment to get a full length month name, like January, December. 9127 + ## TODO: this could be defined somewhere in the blog style. 9128 + ## #set($month = $xwiki.formatDate($date, 'MMMM')) 9129 + #set($day = $xwiki.formatDate($date, 'dd')) 9130 + (% class=~"blogdate~" ~%) 9131 + == (% class=~"month~" ~%)$month(%~%) (% class=~"day~" ~%)$day(%~%) (% class=~"year~" ~%)$year(%~%) == 9132 +#end 9133 +## 9134 +## 9135 +## 9136 +#** 9137 + * Displays a blog article: management tools, header, content, footer. 9138 + * 9139 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9140 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9141 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 9142 + * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title 9143 + * when they're displayed alone on their page since it's the page title which is used in this case) 9144 + * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons 9145 + *### 9146 +#macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions) 9147 + ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden 9148 + #isPublished($entryObj $isPublished) 9149 + #isHidden($entryObj $isHidden) 9150 + #if($doc.fullName == $entryDoc.fullName) 9151 + (% class=~"hentry single-article~" ~%)((( 9152 + #else 9153 + (% class=~"hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end~" ~%)((( 9154 + #end 9155 + #if ($shouldDisplayActions) 9156 + #displayEntryTools($entryDoc $entryObj) 9157 + #end 9158 + #if($shouldDisplayTitle) 9159 + #displayEntryTitle($entryDoc $entryObj) 9160 + #end 9161 + #if($doc.fullName == $entryDoc.fullName) 9162 + #if(!$isPublished) 9163 + \{\{warning}}\{\{translation key='blog.code.published'/}}\{\{/warning}} 9164 + #elseif($isHidden) 9165 + \{\{warning}}\{\{translation key='blog.code.hidden'/}}\{\{/warning}} 9166 + #end 9167 + #end 9168 + #displayEntryContent($entryDoc $entryObj $onlyExtract) 9169 + #displayEntryFooter($entryDoc $entryObj) 9170 + )))## hentry 9171 +#end 9172 +## 9173 +## 9174 +## 9175 +#** 9176 + * Checks if the provided blog is published or not. 9177 + * 9178 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9179 + * @param isPublished The resulting boolean, true if the entry is considered published. 9180 + *### 9181 +#macro(isPublished $entryObj $isPublished) 9182 + #set ($isPublished = $NULL) 9183 + ## This should work for both old articles, which don't have the 'published' property at all, and 9184 + ## are considered published by default, and new entries, that should have 1 if published. 9185 + #if (~"$!\{entryObj.getProperty('published').value}~" != '0') 9186 + #setVariable (~"$isPublished~" true) 9187 + #else 9188 + #setVariable (~"$isPublished~" false) 9189 + #end 9190 +#end 9191 +## 9192 +## 9193 +## 9194 +#** 9195 + * Checks if the provided blog is hidden or not. 9196 + * 9197 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass. 9198 + * @param isHiddel The resulting boolean, true if the entry is considered hidden. 9199 + *### 9200 +#macro(isHidden $entryObj $isHidden) 9201 + #set ($isHidden = $NULL) 9202 + ## This should work for both old articles, which don't have the 'hidden' property at all, and 9203 + ## are considered visible by default, and new entries, that should have 1 if hidden. 9204 + #if (~"$!\{entryObj.getProperty('hidden').value}~" == '1') 9205 + #setVariable (~"$isHidden~" true) 9206 + #else 9207 + #setVariable (~"$isHidden~" false) 9208 + #end 9209 +#end 9210 +## 9211 +## 9212 +## 9213 +#** 9214 + * Displays several ~"tools~" for manipulating blog posts: hide/show, publish, edit. 9215 + * 9216 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9217 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9218 + *### 9219 +#macro(displayEntryTools $entryDoc $entryObj) 9220 + #if($xcontext.action == 'view') 9221 + (% class=~"blog-entry-toolbox~" ~%)((( 9222 + #displayPublishButton($entryDoc $entryObj) 9223 + #displayHideShowButton($entryDoc $entryObj) 9224 + #displayEditButton($entryDoc $entryObj) 9225 + #displayDeleteButton($entryDoc $entryObj) 9226 + ))) 9227 + #end 9228 +#end 9229 +## 9230 +## 9231 +## 9232 +#** 9233 + * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet. 9234 + * 9235 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9236 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9237 + * @todo AJAX calls. 9238 + *### 9239 +#macro(displayPublishButton $entryDoc $entryObj) 9240 + #isPublished($entryObj $isPublished) 9241 + #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 9242 + [[#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')~"]]## 9243 + #end 9244 +#end 9245 +## 9246 +## 9247 +## 9248 +#** 9249 + * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published. 9250 + * 9251 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9252 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9253 + *### 9254 +#macro(displayHideShowButton $entryDoc $entryObj) 9255 + #isPublished($entryObj $isPublished) 9256 + #isHidden($entryObj $isHidden) 9257 + ## Only published articles can be hidden. Unpublished articles are considered already hidden. 9258 + #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 9259 + #set ($queryString = \{ 9260 + 'xredirect' : $thisURL, 9261 + 'form_token' : $services.csrf.getToken() 9262 + }) 9263 + #if ($isHidden) 9264 + #set ($discard = $queryString.putAll(\{ 9265 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 0, 9266 + 'comment' : $services.localization.render('blog.code.madevisible') 9267 + })) 9268 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 9269 + [[#toolImage('unlock')>>path:$lockURL||class=~"blog-tool-show~" title=~"$services.localization.render('blog.code.makevisible')~"]]## 9270 + #else 9271 + #set ($discard = $queryString.putAll(\{ 9272 + ~"$\{entryObj.getxWikiClass().getName()}_$\{entryObj.number}_hidden~" : 1, 9273 + 'comment' : $services.localization.render('blog.code.hid') 9274 + })) 9275 + #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString))) 9276 + [[#toolImage('lock')>>path:$lockURL||class=~"blog-tool-hide~" title=~"$services.localization.render('blog.code.hide')~"]]## 9277 + #end 9278 + #end 9279 +#end 9280 +## 9281 +## 9282 +## 9283 +#** 9284 + * Displays the edit button to those that can edit the article. 9285 + * 9286 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9287 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9288 + *### 9289 +#macro(displayEditButton $entryDoc $entryObj) 9290 + #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) 9291 + ## Call getDefaultEditMode() for backward compatibility with older blog posts. 9292 + [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title=~"$services.localization.render('blog.code.editpost')~"]]## 9293 + #end 9294 +#end 9295 +## 9296 +## 9297 +## 9298 +#** 9299 + * Displays the delete button to those that can edit the article. 9300 + * 9301 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9302 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9303 + * @todo AJAX calls. 9304 + *### 9305 +#macro(displayDeleteButton $entryDoc $entryObj) 9306 + #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName)) 9307 + [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title=~"$services.localization.render('blog.code.deletepost')~"]]## 9308 + #end 9309 +#end 9310 +## 9311 +## 9312 +## 9313 +#** 9314 + * Displays the title of the entry. 9315 + * 9316 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9317 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9318 + *### 9319 +#macro(displayEntryTitle $entryDoc $entryObj) 9320 + #if($doc.fullName == $entryDoc.fullName) 9321 + (% class=~"entry-title~" ~%) 9322 + = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) = 9323 + #else 9324 + (% class=~"entry-title~" ~%) 9325 + === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] === 9326 + #end 9327 +#end 9328 +## 9329 +## 9330 +## 9331 +#** 9332 + * Displays the body of the entry. 9333 + * 9334 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9335 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9336 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 9337 + *### 9338 +#macro(displayEntryContent $entryDoc $entryObj $onlyExtract) 9339 + (% class=~"#if($onlyExtract)entry-summary#\{else}entry-content#end~" ~%)((( 9340 + #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent) 9341 + ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328 9342 + ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content 9343 + \{\{html wiki=~"false~"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString())\{\{/html}} 9344 + ))) ## entry-content 9345 + (% class=~"clearfloats~" ~%)((())) 9346 +#end 9347 +## 9348 +## 9349 +## 9350 +#** 9351 + * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content 9352 + * of the <tt>extract</tt> field (if not empty). 9353 + * 9354 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9355 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9356 + * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. 9357 + * @param entryContent The resulting content. 9358 + * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when 9359 + * <tt>onlyExtract</tt> is <tt>true</tt>) 9360 + *### 9361 +#macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis) 9362 + #if ($onlyExtract) 9363 + ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead 9364 + ## of the content. 9365 + #set ($macro.result = $entryObj.getProperty('extract').value.trim()) 9366 + #end 9367 + #if(~"$!macro.result~" == '') 9368 + #set($macro.result = $entryObj.getProperty('content').value) 9369 +#* Disabled until the content can be cleanly cut. 9370 +* #if($onlyExtract && $result.length()>$maxchars) 9371 +* #set($i = $macro.result.lastIndexOf(~" ~", $maxchars)) 9372 +* #set($i = $i + 1) 9373 +* #set($macro.result = ~"$\{macro.result.substring(0,$i)} *[...>$\{entryDoc.fullName}]*~") 9374 +* #end 9375 +## *### 9376 + #elseif (!$removeEllipsis) 9377 + #if($entryDoc.syntax.toIdString() == 'xwiki/1.0') 9378 + #set($macro.result = ~"$\{macro.result} <a href='$\{entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>~") 9379 + #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1') 9380 + #set($macro.result = ~"$\{macro.result} [[...>>$\{services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]~") 9381 + #end 9382 + #end 9383 + #set ($entryContent = $NULL) 9384 + #setVariable (~"$entryContent~" $macro.result) 9385 +#end 9386 +## 9387 +## 9388 +## 9389 +#** 9390 + * Displays the footer of the entry. 9391 + * 9392 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9393 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9394 + *### 9395 +#macro(displayEntryFooter $entryDoc $entryObj) 9396 + (% class=~"entry-footer~" ~%)((( 9397 + #isPublished($entryObj $isPublished) 9398 + (% class='entry-author-label' ~%) 9399 + #if($isPublished) 9400 + \{\{translation key='blog.code.postedby'/}} ## 9401 + #else 9402 + \{\{translation key='blog.code.createdby'/}} ## 9403 + #end 9404 + \{\{html wiki=~"false~" clean=~"false~"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>\{\{/html}} ## 9405 + #getEntryDate($entryDoc $entryObj $entryDate) 9406 + #listCategories($entryObj) #* 9407 + ## Since the publish date and update date are not set at the exact same time, there could be a small difference that 9408 + ## we assume cannot be more than 3 seconds. 9409 + *#(% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel=~"bookmark~"]] ## 9410 + #if ($showcomments) 9411 + (% class=~"separator~" ~%)·(%~%) [[\{\{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor=~"Comments~"]] (% class=~"itemCount~" ~%)($entryDoc.comments.size())(%~%) ## 9412 + #end ## 9413 + #if($entryDoc != $doc) ## 9414 + #displayEntryBlogLocation($entryDoc $entryObj) ## 9415 + #end 9416 + )))## entry-footer 9417 +#end 9418 +## 9419 +## 9420 +#** 9421 + * Display the blog for the entry (if it is not the currently displayed blog) 9422 + * 9423 + * @param entryDoc The xdocument of the blog post. Each post resides in its own document. 9424 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9425 + *### 9426 +#macro(displayEntryBlogLocation $entryDoc $entryObj) 9427 + #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ## 9428 + #if(~"$!blogPostsLocation~" != ~"~") ## 9429 + #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ## 9430 + #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ## 9431 + #if($doc.documentReference != $blogDocRef) ## 9432 + #set($blogDoc = $xwiki.getDocument($blogDocRef)) ## 9433 + #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ## 9434 + #if($blogObj) (% class=~"blogrefpath~" ~%)((( ## 9435 + $services.localization.render('blog.code.postedin') \{\{html clean=~"false~" wiki=~"false~"}} #hierarchy($blogDocRef, \{'selfIsActive' : true, 'local': true}) \{\{/html}} ## 9436 + )))(%~%)## 9437 + #end 9438 + #end 9439 + #end 9440 +#end 9441 +## 9442 +## 9443 +## 9444 +## 9445 +#** 9446 + * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>. 9447 + * 9448 + * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. 9449 + *### 9450 +#macro(listCategories $entryObj) 9451 + #if($entryObj.getxWikiClass().getName() == $blogPostClassname) 9452 + #set($categories = $entryObj.getProperty('category').value) 9453 + #set($first = true) 9454 + #if($categories.size() > 0) 9455 + #foreach($category in $categories) 9456 + #set($categoryDoc = $!xwiki.getDocument($category)) 9457 + #if(!$categoryDoc.isNew() && $categoryDoc.getObject($\{blogCategoryClassname})) 9458 + #if($foreach.count == 1) 9459 + (% class='separator' ~%)·(%~%) $services.localization.render('blog.code.categories') ## 9460 + #else 9461 + , ## 9462 + #end## 9463 + [[$!\{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>$\{category}||rel='tag']]## 9464 + #end## 9465 + #end## 9466 + #end 9467 + #end 9468 +#end 9469 +## 9470 +## 9471 +## 9472 +#** 9473 + * Displays blog pagination links (older and newer entries). 9474 + * 9475 + * @param blogDoc the XDocument holding the blog definition object. 9476 + *### 9477 +#macro(displayNavigationLinks $blogDoc) 9478 + (% class=~"clearfloats~" ~%)((())) 9479 + #getBlogDisplayType($blogDoc $displayType) 9480 + #if($displayType == 'weekly') 9481 + (% class=~"pagingLinks~" ~%)((( 9482 + #getRequestedWeek($weekDate) 9483 + $weekDate.addWeeks(-1)## 9484 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 9485 + #sep() 9486 + $weekDate.addWeeks(2)## 2 because we already subtracted 1 above 9487 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString=~"year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear~" class=~"button~"]]**(%~%) 9488 + ))) 9489 + #elseif($displayType == 'monthly') 9490 + (% class=~"pagingLinks~" ~%)((( 9491 + #getRequestedMonth($monthDate) 9492 + $monthDate.addMonths(-1)## 9493 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 9494 + #sep() 9495 + $monthDate.addMonths(2)## 2 because we already subtracted 1 above 9496 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"year=$monthDate.year&month=$monthDate.monthOfYear~" class=~"button~"]]**(%~%) 9497 + ))) 9498 + #elseif($displayType == 'all') 9499 + #else 9500 + ## Paginated 9501 + #if(($totalPages > 1)) 9502 + #set($queryString = '') 9503 + #foreach($p in $request.getParameterNames()) 9504 + #if($p != 'page' && $p != 'ipp') 9505 + #foreach($v in $request.getParameterValues($p)) 9506 + #set($queryString = ~"$\{queryString}&$\{escapetool.url($p)}=$\{escapetool.url($v)}~") 9507 + #end 9508 + #end 9509 + #end 9510 + (% class=~"pagingLinks~" ~%)((( 9511 + #if ($currentPageNumber < $totalPages) 9512 + #set($currentPageNumber = $currentPageNumber + 1) 9513 + (% class=~"prevPage~" ~%)**[[« \{\{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 9514 + #set($currentPageNumber = $currentPageNumber - 1) 9515 + #end 9516 + #if ($currentPageNumber > 1) 9517 + #if ($currentPageNumber < $totalPages) 9518 + #sep() 9519 + #end 9520 + #set($currentPageNumber = $currentPageNumber - 1) 9521 + (% class=~"nextPage~" ~%)**[[\{\{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString=~"page=$\{currentPageNumber}&ipp=$\{itemsPerPage}$queryString~" class=~"button~"]]**(%~%) 9522 + #set($currentPageNumber = $currentPageNumber + 1) 9523 + #end 9524 + (% class=~"clear~" ~%)(%~%) 9525 + )))## pagingLinks 9526 + #end 9527 + #end 9528 +#end 9529 +## 9530 +## 9531 +## 9532 +#** 9533 + * Displays a message box with ~"publish~" icon. 9534 + * 9535 + * @param message A text message concerning blog article publishing 9536 + *### 9537 +#macro(publishMessageBox $message) 9538 +(% class=~"plainmessage publish-message~" ~%)((($services.icon.render('world') $message))) 9539 +#end 9540 +#** 9541 + * Displays a message box with ~"show/hide~" icon. 9542 + * 9543 + * @param message A text message concerning blog article hiding 9544 + *### 9545 +#macro(hideMessageBox $message) 9546 +(% class=~"plainmessage hide-message~" ~%)((($services.icon.render('unlock') $message))) 9547 +#end 9548 +## 9549 +## 9550 +## 9551 +#** 9552 + * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are 9553 + * <tt>year</tt> and <tt>week</tt>. By default, the current week is used. 9554 + * 9555 + * @param monthDate The resulting week, a JODATime MutableDateTime. 9556 + *### 9557 +#macro(getRequestedWeek $weekDate) 9558 + #set ($weekDate = $NULL) 9559 + #setVariable (~"$weekDate~" $xwiki.jodatime.mutableDateTime) 9560 + #if(~"$!\{request.year}~" != '') 9561 + #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue())) 9562 + #end 9563 + #if(~"$!\{request.week}~" != '') 9564 + #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue())) 9565 + #end 9566 +#end 9567 +## 9568 +## 9569 +## 9570 +#** 9571 + * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are 9572 + * <tt>year</tt> and <tt>month</tt>. By default, the current month is used. 9573 + * 9574 + * @param monthDate The resulting month, a JODATime MutableDateTime. 9575 + *### 9576 +#macro(getRequestedMonth $monthDate) 9577 + #set ($monthDate = $NULL) 9578 + #setVariable (~"$monthDate~" $xwiki.jodatime.mutableDateTime) 9579 + #if(~"$!\{request.year}~" != '') 9580 + #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue())) 9581 + #end 9582 + #if(~"$!\{request.month}~" != '') 9583 + #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue())) 9584 + #end 9585 +#end 9586 +## 9587 +## 9588 +## 9589 +#** 9590 + * Retrieve a blog property (title, display type, etc). 9591 + * 9592 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 9593 + * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties. 9594 + * @param defaultValue The default value to use in case the blog object does not define one. 9595 + * @param propertyValue The resulting value. 9596 + *### 9597 +#macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue) 9598 + #set($result = ~"$!\{blogDoc.getObject($\{blogClassname}).getProperty($propertyName).value}~") 9599 + #if($result == '') 9600 + #set($result = $defaultValue) 9601 + #end 9602 + #set ($propertyValue = $NULL) 9603 + #setVariable (~"$propertyValue~" $result) 9604 +#end 9605 + 9606 +#** 9607 + * If an error occurs when executing an action, set a specific response status and display an error message. 9608 + * 9609 + * @param status The response status. 9610 + * @param text The user readable error to be displayed. Can be a translation key. 9611 + * @param parameters The parameters to use when decoding the translation key. 9612 + *### 9613 +#macro(blog__actionResponseError $status $text $parameters) 9614 + $response.setStatus($status) 9615 + #if($request.ajax) 9616 + $services.localization.render($text, $!parameters) 9617 + #else 9618 + \{\{error}}$services.localization.render($text, $!parameters)\{\{/error}} 9619 + #end 9620 +#end 9621 +## 9622 +## 9623 +## 9624 +#** 9625 + * Check if a blog is the Default blog (The one in the 'Blog' space). 9626 + * 9627 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. 9628 + * @param isDefault The resulting boolean. 9629 + *### 9630 +#macro(isDefaultBlog $blogDoc $isDefault) 9631 + #set ($result = false) 9632 + #if ($blogDoc.space == 'Blog') 9633 + #set ($result = true) 9634 + #end 9635 + #setVariable(~"$isDefault~" $result) 9636 +#end 9637 +## 9638 +## 9639 +## 9640 +#** 9641 + * Retrieve the blog posts location (space). 9642 + * 9643 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 9644 + * @param postsLocation The resulting location. 9645 + *### 9646 +#macro(getBlogPostsLocation $blogSpace $postsLocation) 9647 + #getBlogDocument($blogSpace $blogDoc) 9648 + #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result) 9649 + #set ($postsLocation = $NULL) 9650 + #setVariable (~"$postsLocation~" $result) 9651 +#end 9652 +## 9653 +## 9654 +## 9655 +#** 9656 + * Retrieve the blog categories location (space). 9657 + * 9658 + * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object 9659 + * @param categoriesLocation The resulting location. 9660 + *### 9661 +#macro(getBlogCategoriesLocation $blogSpace $categoriesLocation) 9662 + #getBlogDocument($blogSpace $blogDoc) 9663 + #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result) 9664 + #set ($postsLocation = $NULL) 9665 + #setVariable (~"$categoriesLocation~" $result) 9666 +#end 9667 +###** 9668 + * Return the Query for selecting the blog posts based on the context where the posts are displayed. 9669 + * for example there is 4 different panel contexts: 9670 + * aBlog.aPost or aBlog.WebHome 9671 + * aCategorySpace.aCategory 9672 + * aCategorySpace.WebHome 9673 + * Blog.aPost or Blog.WebHome 9674 + * 9675 + * @param query The query for selecting blog entries. 9676 + * @param queryParams The parameters to bind with the generated query. 9677 + * @param targetDoc The document in which the articles will be displayed. 9678 + *### 9679 +#macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams) 9680 + #set ($query = $NULL) 9681 + #set ($queryParams = $NULL) 9682 + #getCategoryAllBlogPostsQuery($resultQuery) 9683 + #set ($resultQueryParams = \{}) 9684 + #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%')) 9685 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 9686 + ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%' 9687 + #set ($discard = $resultQueryParams.put('space', $targetDoc.space)) 9688 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 9689 + #set($resultQuery = ~"$\{resultQuery} and (doc.space = :space or catList like :catList escape '!')~") 9690 + #elseif($targetDoc.getObject($blogCategoryClassname)) 9691 + ## Get all posts that are in a category aCategorySpace.aCategory 9692 + #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName)) 9693 + #set($resultQuery = ~"$\{resultQuery} and (catList=:catList)~") 9694 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 9695 + ## Get all posts that are in a category aCategorySpace.% 9696 + #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace)) 9697 + ## Exclude incategorized posts 9698 + #set ($excludedCategory = ~"$\{targetDoc.space}.WebHome~") 9699 + #if ($targetDoc.space == $defaultBlogSpace) 9700 + #set ($excludedCategory = ~"Blog.Categories.WebHome~") 9701 + #end 9702 + #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory)) 9703 + #set($resultQuery = ~"$\{resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')~") 9704 + #else 9705 + ## Get all posts in blog space aBlog 9706 + #getAllBlogPostsQuery($resultQuery) 9707 + #getBlogPostsLocation($targetDoc.space $postsLocation) 9708 + #set ($discard = $resultQueryParams.put('space', $postsLocation)) 9709 + #set($resultQuery = ~"$\{resultQuery} and doc.space = :space~") 9710 + #end 9711 + #setVariable(~"$query~" $resultQuery) 9712 + #setVariable(~"$queryParams~" $resultQueryParams) 9713 +#end 9714 +## 9715 +## 9716 +## 9717 +###** 9718 + * Display blog posts based on the context where the posts are displayed. 9719 + * for example there is 4 different panel contexts: 9720 + * aBlog.aPost or aBlog.WebHome 9721 + * aCategorySpace.aCategory 9722 + * aCategorySpace.WebHome 9723 + * Blog.aPost or Blog.WebHome 9724 + * 9725 + * @param targetDoc The document in which the articles will be displayed. 9726 + * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ... 9727 + * @param layout Layout of the the posts to display 9728 + * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN' 9729 + * @param limit the number of posts to display 9730 + *### 9731 +#macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit) 9732 + #if ($postLayout == 'full') 9733 + #set ($macro.paginated = 'yes') 9734 + #end 9735 + #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname)) 9736 + ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%' 9737 + #getBlogPostsLayout($xwiki.getDocument(~"$\{defaultBlogSpace}.WebHome~") $postsLayout) 9738 + #if (~"$!layout~" == '') 9739 + #set ($layout = $postsLayout) 9740 + #end 9741 + #if ($postsVisiblity == 'recent') 9742 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 9743 + #elseif($postsVisiblity == 'unpublished') 9744 + \{\{blogpostlist blog=~"$\{defaultBlogSpace.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')}.WebHome~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 9745 + #end 9746 + #elseif($targetDoc.getObject($blogCategoryClassname)) 9747 + ## Display all posts that are in a category aCategorySpace.aCategory 9748 + #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc) 9749 + #getBlogPostsLayout($blogDoc $postsLayout) 9750 + #if (~"$!layout~" == '') 9751 + #set ($layout = $postsLayout) 9752 + #end 9753 + #if ($postsVisiblity == 'recent') 9754 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 9755 + #elseif($postsVisiblity == 'unpublished') 9756 + \{\{blogpostlist category=~"$targetDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 9757 + #end 9758 + #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') 9759 + ## Display all posts that are in a category aCategorySpace.% 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.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 9767 + #elseif($postsVisiblity == 'unpublished') 9768 + \{\{blogpostlist category=~"$targetDoc.space.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 9769 + #end 9770 + #else 9771 + ## Display all posts in blog space aBlog 9772 + #getBlogDocument($targetDoc.space $blogDoc) 9773 + #getBlogPostsLayout($blogDoc $postsLayout) 9774 + #if (~"$!layout~" == '') 9775 + #set ($layout = $postsLayout) 9776 + #end 9777 + #if ($postsVisiblity == 'recent') 9778 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='yes' hidden='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" limit=~"$limit~" /}} 9779 + #elseif($postsVisiblity == 'unpublished') 9780 + \{\{blogpostlist blog=~"$blogDoc.fullName.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" published='no' layout=~"$!layout.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" layoutParams=~"$!layoutParams.replaceAll('~~', '~~~~').replaceAll('~"', '~~~"')~" paginated=~"$!macro.paginated~" limit=~"$limit~" /}} 9781 + #end 9782 + #end 9783 +#end 9784 +## 9785 +## 9786 +## 9787 +#** 9788 + * Bind parameters to a query object. 9789 + * 9790 + * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object) 9791 + * @param queryParams the query parameters. 9792 + *### 9793 +#macro(bindQueryParameters $queryObj $queryParams) 9794 + #set ($output = $queryObj) 9795 + #foreach( $key in $queryParams.keySet() ) 9796 + #set($output = $queryObj.bindValue($key, $queryParams.get($key))) 9797 + #end 9798 + #setVariable(~"$queryObj~" $output) 9799 +#end 9800 +## 9801 +## 9802 +## 9803 +#** 9804 + * Determines the blogposts layout: Default layout (Calendar), Image thumbnail 9805 + * 9806 + * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt> 9807 + * property set. 9808 + * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default). 9809 + *### 9810 +#macro(getBlogPostsLayout $blogDoc $postsLayout) 9811 + #getBlogProperty($blogDoc 'postsLayout' 'full' $res) 9812 + #set ($postsLayout = $NULL) 9813 + #setVariable (~"$postsLayout~" $res) 9814 +#end 9815 +## 9816 +## 9817 +## 9818 +#** 9819 + * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space 9820 + * 9821 + * @param categoriesSpace A <tt>String</tt>, the name of the space. 9822 + * @param blogDoc The resulting XDocument. 9823 + *### 9824 +#macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc) 9825 + #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()) 9826 + #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace) 9827 + #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0))) 9828 + #else 9829 + ## Fallback to Blog.WebHome, the default blog 9830 + #set($macro.result = $xwiki.getDocument('Blog.WebHome')) 9831 + #end 9832 + #set ($blogDoc = $NULL) 9833 + #setVariable (~"$blogDoc~" $macro.result) 9834 +#end" %) 9835 +((( 9836 +(% class="macro-placeholder hidden" %) 9837 +((( 9838 +macro:velocity 9839 +))) 9840 +))) 9841 +))) 9842 + 9843 +(% class="macro" data-macro="startmacro:include|-|reference=~"Blog.BlogPostLayoutMacros~"" %) 9844 +((( 9845 +(% class="macro-placeholder hidden" %) 9846 +((( 9847 +macro:include 9848 +))) 9849 + 9850 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-|#** 9851 + * Extract the layout parameters from a string. 9852 + * 9853 + * @param layoutParamsString The string representation of the layout parameters. 9854 + * It should contain a String following this format ~"paramName1=Value1|paramName2=Value2|...|paramNameK=ValueK~" 9855 + * @param layoutsParameters The resulting layout parameters Map. 9856 + *### 9857 +#macro(extractLayoutParametersFromString $layoutParamsString $layoutsParameters) 9858 + #set ($layoutsParameters = $NULL) 9859 + #set ($macro.layoutParams = \{}) 9860 + #if (~"$!layoutParamsString~" != '') 9861 + #set ($macro.paramsArr = $layoutParamsString.split('\\|')) 9862 + #foreach ($item in $macro.paramsArr) 9863 + #set ($itemSplit = $item.split('=')) 9864 + #if ($itemSplit.size() == 2) 9865 + #set ($discard = $macro.layoutParams.put($itemSplit[0].trim(), $itemSplit[1].trim())) 9866 + #end 9867 + #end 9868 + #end 9869 + #setVariable(~"$layoutsParameters~" $macro.layoutParams) 9870 +#end" %) 9871 +((( 9872 +(% class="macro-placeholder hidden" %) 9873 +((( 9874 +macro:velocity 9875 +))) 9876 +))) 9877 +))) 9878 + 9879 +(% class="macro" data-macro="startmacro:velocity|-|output=~"false~"|-| #macro(displaySmallPost $pDoc $pObj) 9880 + #initLayoutVars($pDoc $pObj) 9881 + <div class=~"col-xs-12 col-sm-6 next_blog~"> 9882 + <a href=~"$pDoc.uRL~" class=~"thumbnail~"> 9883 + <div class=~"row~"> 9884 + <div class=~"col-xs-4~"> 9885 + #if ($imageAtt) 9886 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 9887 + #end 9888 + </div> 9889 + <div class=~"col-xs-8 art_det~"> 9890 + <p class=~"text-left~"> 9891 + #if($displayTitle)$!postTitle #end 9892 + <br/><span class=~"date_info~"> $!dateStr </span> 9893 + </p> 9894 + #displayPostDetails($pDoc) 9895 + </div> 9896 + </div> 9897 + </a> 9898 + </div> 9899 + #end 9900 + ## 9901 + ## 9902 + ## 9903 + #macro(displayPinnedPost $pDoc $pObj) 9904 + #initLayoutVars($pDoc $pObj) 9905 + <div class=~"col-xs-12 col-sm-4 col-md-4 blog_pin~"> 9906 + <a href=~"$pDoc.uRL~" class=~"all-post-link~"> 9907 + <div class=~"thumbnail~"> 9908 + #if ($displayTitle && $displayTitleFirstOnPinnedPosts) 9909 + <h5 class=~"title-top~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 9910 + #end 9911 + #if ($imageAtt) 9912 + <img src=~"$escapetool.xml($pDoc.getAttachmentURL($pObj.getValue('image'),'download',$imgQs))~" /> 9913 + #end 9914 + <div class=~"caption~"> 9915 + #if ($displayTitle && !$displayTitleFirstOnPinnedPosts) 9916 + <h5 class=~"text-left~">$!postTitle <br/> <span class=~"date_info~"> $!dateStr </span> </h5> 9917 + #end 9918 + #if ($displaySummaryOnPinnedPosts) 9919 + <div class=~"text-left post-summary~"> 9920 + #set ($postContent = $pObj.getProperty('extract').value) 9921 + $!pDoc.getRenderedContent($postContent, $pDoc.syntax.toIdString()) 9922 + </div> 9923 + #end 9924 + #displayPostDetails($pDoc) 9925 + </div> 9926 + </div> 9927 + </a> 9928 + </div> 9929 + #end 9930 + ## 9931 + ## 9932 + ## 9933 + #macro(formatPostDate $pDoc $pObj) 9934 + #set ($formattedDate = $NULL) 9935 + #set($dateStr = $datetool.format('medium', $postDate, $xcontext.locale)) 9936 + #if (~"$!dateStr~" != '') 9937 + #set ($dateArr = $dateStr.split(' ')) 9938 + #if ($dateArr.size() > 3) 9939 + #set ($dateStr = ~"~") 9940 + #foreach($s in $dateArr.subList(0, 3)) 9941 + #set ($dateStr = ~"$\{dateStr}$\{s} ~") 9942 + #end 9943 + #end 9944 + #end 9945 + #setVariable(~"$formattedDate~" $dateStr) 9946 + #end 9947 + ## 9948 + ## 9949 + ## 9950 + #macro(displayPostDetails $pDoc) 9951 + <div class=~"row post-details~"> 9952 + <div class=~"col-xs-8 detail~"> 9953 + #if ($services.like.displayButton($pDoc.documentReference)) 9954 + #set ($optLikeRecord = $services.like.getLikes($pDoc.documentReference)) 9955 + ## Retrieve the likes number in XWiki 12.9+ 9956 + #set ($likeNumber = $optLikeRecord.get()) 9957 + #if (!$stringtool.isNumeric($likeNumber.toString())) 9958 + ## Retrieve the likes number in XWiki versions greater than 12.7 and lower than 12.9. 9959 + #set ($likeNumber = $optLikeRecord.get().likeNumber) 9960 + #end 9961 + #if ($stringtool.isNumeric($likeNumber.toString())) 9962 + <div class=~"post-likes btn btn-default disabled badge~" 9963 + title=~"$escapetool.xml($services.localization.render('like.button.title', [$likeNumber]))~"> 9964 + $services.icon.renderHTML('heart') <span class=~"like-number~">$likeNumber</span> 9965 + </div> 9966 + #end 9967 + #elseif ($services.ratings) 9968 + #set ($ratingsConfigDoc = $services.ratings.getConfigurationDocument($pDoc.documentReference)) 9969 + #if ($ratingsConfigDoc.getValue('displayRatings') == 1) 9970 + <ul class=~"pull-left note list-inline~"> 9971 + #foreach ($x in [1..5]) 9972 + #set ($cls = ~"~") 9973 + #if ($x > $averageVote) 9974 + #set ($cls = ~"-o~") 9975 + #end 9976 + <li><span class=~"fa fa-star$\{cls}~"></span></li> 9977 + #end 9978 + </ul> 9979 + #end 9980 + #end 9981 + </div> 9982 + #if ($showPostComments) 9983 + <div class=~"col-xs-4 com_det~"> 9984 + <p class=~"text-right~">$services.icon.renderHTML('comments') ($!nbComments)</p> 9985 + </div> 9986 + #end 9987 + </div> 9988 + #end 9989 + ## 9990 + ## 9991 + ## 9992 + #macro(initLayoutVars $pDoc $pObj) 9993 + #set ($postTitle = $pDoc.display('title', 'view', $pObj)) 9994 + #set ($imageAtt = $pDoc.getAttachment($pObj.getValue('image'))) 9995 + #isPublished($pObj $isPublished) 9996 + #isHidden($pObj $isHidden) 9997 + #getEntryDate($pDoc $pObj $postDate) 9998 + #formatPostDate($postDate $dateStr) 9999 + #set ($averageVote = $mathtool.round($services.ratings.getAverageRating($pDoc.documentReference).getAverageVote())) 10000 + #set ($nbComments = $pDoc.getComments().size()) 10001 + #set ($showPostComments = true) 10002 + #if ($xwiki.getSpacePreferenceFor('showcomments', $pDoc.documentReference.lastSpaceReference, '1') == '0') 10003 + #set ($showPostComments = false) 10004 + #end 10005 + #end 10006 + ## 10007 + ## 10008 + ## 10009 + #macro(displayEditPinnedPostsButton) 10010 + #if (~"$!macroAdditionalParams.get('postIndex')~" == '0' && $services.security.authorization.hasAccess('edit', $pinnedPostsSourceDoc.fullName)) 10011 + #set ($discard = $xwiki.ssx.use('Blog.PinnedPostsSheet')) 10012 + #set ($discard = $xwiki.jsx.use('Blog.PinnedPostsSheet')) 10013 + #set ($editPinnedPostsURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'get', 'sheet=Blog.PinnedPostsSheet')) 10014 + #set ($newPinnedPostsObjectURL = $xwiki.getURL($pinnedPostsSourceDoc.fullName, 'objectadd', ~"classname=Blog.PinnedPostsClass&form_token=$!\{services.csrf.getToken()}~")) 10015 + <div class=~"edit-pinned-posts-container~"> 10016 + <div class=~"col-xs-12 col-sm-12 col-md-12 text-right edit-pinned-posts~"> 10017 + <a href=~"javascript:;~" class=~"editPinnedPosts~"> 10018 + <span class=~"glyphicon glyphicon-edit~" aria-hidden=~"true~"></span> $services.localization.render('blog.post.layout.cards.pinnedposts.edit') 10019 + </a> 10020 + <input type=~"hidden~" id=~"editPinnedPostsURL~" value=~"$escapetool.xml($editPinnedPostsURL)~"/> 10021 + <input type=~"hidden~" id=~"newPinnedPostsObjectURL~" value=~"$escapetool.xml($newPinnedPostsObjectURL)~"/> 10022 + </div> 10023 + </div> 10024 + #if (~"$!pinnedPostsObj~" == '') 10025 + <input type=~"hidden~" name=~"createPinnedPostsObject~" value=~"1~"/> 10026 + #end 10027 + #end 10028 + #end" %) 10029 +((( 10030 +(% class="macro-placeholder hidden" %) 10031 +((( 10032 +macro:velocity 10033 +))) 10034 +))) 10035 + 10036 +(% class="macro" data-macro="startmacro:velocity|-||-| #if ($services.security.authorization.hasAccess('view', $xcontext.macro.params.reference)) 10037 + #set ($postDoc = $xwiki.getDocument($xcontext.macro.params.reference)) 10038 + #getEntryObject($postDoc $postObj) 10039 + #if (~"$!postObj~" != '') 10040 + #extractLayoutParametersFromString($xcontext.macro.params.params $macroAdditionalParams) 10041 + ## 10042 + #set ($displayTitle = true) 10043 + #if (~"$!macroAdditionalParams.get('displayTitle')~" == 'false') 10044 + #set ($displayTitle = false) 10045 + #end 10046 + ## 10047 + #set ($displayTitleFirstOnPinnedPosts = false) 10048 + #if (~"$!macroAdditionalParams.get('displayTitleFirstOnPinnedPosts')~" == 'true') 10049 + #set ($displayTitleFirstOnPinnedPosts = true) 10050 + #end 10051 + ## 10052 + #set ($displaySummaryOnPinnedPosts = true) 10053 + #if (~"$!macroAdditionalParams.get('displaySummaryOnPinnedPosts')~" == 'false') 10054 + #set ($displaySummaryOnPinnedPosts = false) 10055 + #end 10056 + ## 10057 + #set ($postIndex = $numbertool.toNumber($macroAdditionalParams.get('postIndex')).intValue()) 10058 + #if ($postIndex == 0) 10059 + #set ($stopBlogPostsDisplay = false) 10060 + #end 10061 + #set ($listResultsCount = $numbertool.toNumber($macroAdditionalParams.get('list-results-count')).intValue()) 10062 + #set($discard = $xwiki.ssx.use('Blog.BlogPostLayoutCards')) 10063 + #set($scaleWidth = 600) 10064 + #set($imgQs=~"width=$scaleWidth~") 10065 + ## Display pinned posts 10066 + ## Get the list of pinned posts 10067 + #set ($pinnedPosts = []) 10068 + #set ($pinnedPostsSourceDoc = $NULL) 10069 + #if (~"$!macroAdditionalParams.get('forceDisplayPinnedPosts')~" == 'true' && ~"$!macroAdditionalParams.get('list-blog')~" != '') 10070 + #set ($pinnedPostsSourceDoc = $xwiki.getDocument($macroAdditionalParams.get('list-blog'))) 10071 + ## Note that the 'list-blog' parameter contains the value of the 'blog' parameter of the blogpostlist macro passed to the current layout macro 10072 + #end 10073 + #if (~"$!pinnedPostsSourceDoc~" != '') 10074 + #set ($pinnedPostsObj = $pinnedPostsSourceDoc.getObject('Blog.PinnedPostsClass')) 10075 + #if (~"$!pinnedPostsObj~" != '') 10076 + #set ($orderedPinnedPostsJSON = $pinnedPostsObj.getProperty('orderedPosts').value) 10077 + #if (~"$!orderedPinnedPostsJSON~" != '') 10078 + #set ($pinnedPosts = $jsontool.parse($orderedPinnedPostsJSON)) 10079 + #else 10080 + #set ($pinnedPosts = $pinnedPostsObj.getProperty('posts').value) 10081 + #end 10082 + #end 10083 + #if ($postIndex == 0 && $pinnedPosts.size() > 0) 10084 + \{\{html clean=~"false~"}} 10085 + #set ($x = 0) 10086 + #set ($showPinnedPostsButton = true) 10087 + #foreach ($pinnedPost in $pinnedPosts) 10088 + #if ($x == 0) 10089 + <div class=~"row flex-container~"> 10090 + #if ($showPinnedPostsButton) 10091 + #displayEditPinnedPostsButton() 10092 + #set($showPinnedPostsButton = false) 10093 + #end 10094 + #end 10095 + #set ($pinnedPostDoc = $xwiki.getDocument($pinnedPost)) 10096 + #getEntryObject($pinnedPostDoc $pinnedPostObj) 10097 + #if (~"$!pinnedPostObj~" != '') 10098 + #displayPinnedPost($pinnedPostDoc $pinnedPostObj) 10099 + #end 10100 + #set ($x = $mathtool.add($x, 1)) 10101 + #if ($x == 3) 10102 + #set ($x = 0) 10103 + </div> 10104 + #end 10105 + #end 10106 + #if ($mathtool.mod($x, 3) != 0) 10107 + </div> 10108 + #end 10109 + \{\{/html}} 10110 + 10111 + ## If the first post is a pinned post : this means that all the posts are pinned 10112 + ## In this case, avoid displaying the posts again after the pinned posts section. 10113 + #if ($pinnedPosts.contains($xcontext.macro.params.reference)) 10114 + #set ($stopBlogPostsDisplay = true) 10115 + #end 10116 + #elseif($postIndex == 0 && $pinnedPosts.size() == 0) 10117 + 10118 + \{\{html}} 10119 + <div class=~"row no-pinnded-posts~"> 10120 + #displayEditPinnedPostsButton() 10121 + </div> 10122 + \{\{/html}} 10123 + 10124 + #end 10125 + #end 10126 + #if (!$stopBlogPostsDisplay) 10127 + \{\{html clean=~"false~"}} 10128 + #if (~"$!nbDisplayedPosts~" == '' || $postIndex == 0) 10129 + #set ($nbDisplayedPosts = 0) 10130 + #end 10131 + #if($mathtool.mod($nbDisplayedPosts, 2) == 0) 10132 + #if ($nbDisplayedPosts != 0) 10133 + </div> 10134 + #set ($lastHtmlTag = 'c') 10135 + #end 10136 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 10137 + <div class=~"row~"> 10138 + #set ($lastHtmlTag = 'o') 10139 + #set ($lastRowClass = ~"~") 10140 + #else 10141 + <div class=~"row flex-container~"> 10142 + #set ($lastHtmlTag = 'o') 10143 + #set ($lastRowClass = ~"flex~") 10144 + #end 10145 + #end 10146 + #displaySmallPost($postDoc $postObj) 10147 + #if ($nbDisplayedPosts == $mathtool.sub($listResultsCount, 1)) 10148 + </div> 10149 + #set ($lastHtmlTag = 'c') 10150 + #end 10151 + #set ($nbDisplayedPosts = $mathtool.add($nbDisplayedPosts, 1)) 10152 + #if ($postIndex == $mathtool.sub($listResultsCount, 1)) 10153 + #if (~"$!lastHtmlTag~" == 'o') 10154 + #if ($mathtool.mod($nbDisplayedPosts, 2) == 1 && $lastRowClass == ~"flex~") 10155 + <div class=~"col-xs-12 col-sm-6~"></div> 10156 + #end 10157 + </div> 10158 + #end 10159 + #end 10160 + \{\{/html}} 10161 + #end 10162 + #else 10163 + \{\{error}}$services.localization.render('blog.blogpostlayout.notpost', [$xcontext.macro.params.reference])\{\{/error}} 10164 + #end 10165 + #else 10166 + \{\{error}}$services.localization.render('blog.blogpostlayout.post_view_not_allowed', [$xcontext.macro.params.reference])\{\{/error}} 10167 + #end" %) 10168 +((( 10169 +(% class="macro-placeholder hidden" %) 10170 +((( 10171 +macro:velocity 10172 +))) 10173 + 10174 +(% class="macro" data-macro="startmacro:html|-|clean=~"false~"|-|<div class=~"col-xs-12 col-sm-6 next_blog~"> 10175 +<a href=~"/Nieuws/RI%26E%202023~" class=~"thumbnail~"> 10176 +<div class=~"row~"> 10177 +<div class=~"col-xs-4~"> 10178 +<img src=~"/download/Nieuws/RI%26E%202023/Knipsel.JPG?width=600&rev=1.1~" /> 10179 +</div> 10180 +<div class=~"col-xs-8 art_det~"> 10181 +<p class=~"text-left~"> 10182 +RI en E 2023 <br/><span class=~"date_info~"> 13 dec. 2023 </span> 10183 +</p> 10184 +<div class=~"row post-details~"> 10185 +<div class=~"col-xs-8 detail~"> 10186 +<div class=~"post-likes btn btn-default disabled badge~" 10187 +title=~"Number of likes on this page: 1~"> 10188 +<span class=~"fa fa-heart~"></span> <span class=~"like-number~">1</span> 10189 +</div> 10190 +</div> 10191 +<div class=~"col-xs-4 com_det~"> 10192 +<p class=~"text-right~"><span class=~"fa fa-comments~"></span> (0)</p> 10193 +</div> 10194 +</div> 10195 +</div> 10196 +</div> 10197 +</a> 10198 +</div> 10199 +</div>" %) 10200 +((( 10201 +(% class="macro-placeholder hidden" %) 10202 +((( 10203 +macro:html 10204 +))) 10205 + 10206 +(% class="col-xs-12 col-sm-6 next_blog" %) 10207 +((( 10208 +(% class="row" %) 10209 +((( 10210 +(% class="col-xs-4" %) 10211 +((( 10212 +[[~[~[image:/download/Nieuws/RI%26E%202023/Knipsel.JPG?width=600&rev=1.1~]~]>>path:/Nieuws/RI%26E%202023||class="thumbnail"]] 10213 +))) 10214 + 10215 +(% class="col-xs-8 art_det" %) 10216 +((( 10217 +(% class="text-left" %) 10218 +[[RI en E 2023 10219 +(% class="date_info" %) 13 dec. 2023>>path:/Nieuws/RI%26E%202023||class="thumbnail"]] 10220 + 10221 +(% class="row post-details" %) 10222 +((( 10223 +(% class="col-xs-8 detail" %) 10224 +((( 10225 +(% class="post-likes btn btn-default disabled badge" title="Number of likes on this page: 1" %) 10226 +((( 10227 +[[(% class="like-number" %)1>>path:/Nieuws/RI%26E%202023||class="thumbnail"]] 10228 +))) 10229 +))) 10230 + 10231 +(% class="col-xs-4 com_det" %) 10232 +((( 10233 +(% class="text-right" %) 10234 +[[(0)>>path:/Nieuws/RI%26E%202023||class="thumbnail"]] 10235 +))) 10236 +))) 10237 +))) 10238 +))) 10239 +))) 10240 +))) 10241 +))) 10242 +))) 10243 +))) 10244 +))) 10245 +))) 10246 +))) 10247 +))) 10248 +))) 10249 + 10250 +(% 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="Klik en sleep om te verplaatsen" width="15"]] 10251 +))) 10252 + 10253 + 10254 + 10255 +))) 10256 + 10257 +(% aria-label="macro:velocity widget" contenteditable="false" role="region" tabindex="-1" %) 10258 +((( 10259 +(% class="macro" data-macro="startmacro:velocity|-||-|#if (!$hasEdit) 55 55 ## Verstop tabs 56 56 #set($displayDocExtra = false) 57 57 ## En de balken onderin 58 58 #set ($displayShortcuts = false) 59 -#end 60 -{{/velocity}} 10264 +#end" data-widget="xwiki-macro" data-xwiki-dom-updated="true" %) 10265 +((( 10266 +(% class="macro-placeholder" %) 10267 +((( 10268 +macro:velocity 10269 +))) 10270 +))) 10271 + 10272 +(% 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="Klik en sleep om te verplaatsen" width="15"]] 10273 +)))