Last modified by Vincent Massol on 2023/05/16

Show last authors
1 {{include reference="Blog.BlogParameters"/}}
2
3 {{velocity output="false"}}
4 ##
5 ##
6 ##
7 ## Import the blog skin and javascripts.
8 $!xwiki.ssx.use($blogStyleDocumentName)##
9 $!xwiki.jsx.use($blogScriptsDocumentName)##
10 ##
11 ## import the hierarchy for the path the blog post footer (in displayEntryBlogLocation)
12 #template('hierarchy_macros.vm')##
13 ##
14 ##
15 #**
16 * Prints a blog. This is the main macro used in the BlogSheet.
17 *
18 * @param blogDoc the XDocument holding the blog definition object.
19 *###
20 #macro(printBlog $blogDoc)
21 {{include reference='Blog.CreatePost'/}}
22
23 ## Use the blogPostList macro to display the blogposts
24 ## The blogPostList is used only in case of 'all' or 'paged' blog display type because the blogPostList macro
25 ## do not support FTM the monthly and weekly blog display types
26 #getBlogDisplayType($blogDoc $displayType)
27 #if ($displayType == 'weekly' || $displayType == 'monthly')
28 #getBlogEntries($blogDoc $entries)
29 #displayBlog($entries 'index' true true)
30 #displayNavigationLinks($blogDoc)
31 #else
32 #getBlogDisplayType($blogDoc $displayType)
33 #set ($paginated = 'no')
34 #if ($displayType == 'paginated')
35 #set ($paginated = 'yes')
36 #end
37 #getBlogPostsLayout($blogDoc $postsLayout)
38 (% class="hfeed index" %)((({{blogpostlist blog="$blogDoc.fullName.replaceAll('~', '~~').replaceAll('"', '~"')" paginated="$paginated" layout="$!postsLayout.replaceAll('~', '~~').replaceAll('"', '~"')" /}})))
39 #end
40 #end
41 ##
42 ##
43 ##
44 #**
45 * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
46 * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
47 * all entries).
48 *
49 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
50 *###
51 #macro(showBlogInfo $blogDoc)
52 #if($blogDoc.getObject($blogClassname))
53 ## Keep testing for inline action for backward compatibility with older blogs.
54 #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
55 #macro(displayProperty $blogDoc $propname)
56 ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
57 : $blogDoc.display($propname)
58 #end
59 #displayProperty($blogDoc 'title')
60 #displayProperty($blogDoc 'description')
61 #displayProperty($blogDoc 'displayType')
62 #displayProperty($blogDoc 'itemsPerPage')
63 #displayProperty($blogDoc 'postsLayout')
64 #displayProperty($blogDoc 'postsLayoutParameters')
65 #else
66 $blogDoc.display('description')
67 #end
68 #elseif($doc.fullName == $blogSheet)
69 = $services.localization.render('blog.code.blogsheet') =
70 {{translation key='blog.code.sheetexplanation'/}}
71 #else
72 {{warning}}{{translation key='blog.code.notblog'/}}{{/warning}}
73 #end
74 #end
75 ##
76 ##
77 ##
78 #**
79 * Retrieve the blog document, which usually is either <tt>&lt;Space&gt;.WebHome</tt> for whole-spaces blogs, or
80 * <tt>&lt;Space&gt;.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first
81 * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
82 * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog.
83 *
84 * @param space A <tt>String</tt>, the name of the space where to search.
85 * @param blogDoc The resulting XDocument.
86 *###
87 #macro(getBlogDocument $space $blogDoc)
88 #set ($result = $NULL)
89 ## Check if the current space has a WebPreferences page that contains a Blog.EnablePanelsConfigurationClass object.
90 ## 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
91 ## identify the right blog based on a configuration object in a WebPreferences page.
92 #set ($spaceReference = $services.model.resolveSpace($space))
93 #set ($preferencesDocRef = $services.model.createDocumentReference('WebPreferences', $spaceReference))
94 #set ($preferencesDoc = $xwiki.getDocument($preferencesDocRef))
95 #set ($preferencesObj = $preferencesDoc.getObject('Blog.EnablePanelsConfigurationClass'))
96 #if ($preferencesObj)
97 #set ($result = $xwiki.getDocument( $preferencesObj.getValue('blog')))
98 #end
99 ## If no special case occurs (like the previous one), identify a blog by checking the current location from its hierarchy.
100 #if ("$!result" == '')
101 ## First, try the Space.WebHome, for a whole-space blog
102 #set($result = $xwiki.getDocument("${space}.WebHome"))
103 #if(!$result.getObject($blogClassname))
104 ## Second, try the Space.Blog document
105 #set($result = $xwiki.getDocument("${space}.Blog"))
106 #if(!$result.getObject($blogClassname))
107 ## Third, try searching for a blog document in the current space
108 ## Prevent the query fail when the space contains dots '.'
109 #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())
110 #if($blogDocs.size() > 0)
111 #set($result = $xwiki.getDocument($blogDocs.get(0)))
112 #else
113 ## Fourth, try searching for a blog document that have the its 'postsLocation' set to the current space
114 #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())
115 #if($blogDocs.size() > 0)
116 #set($result = $xwiki.getDocument($blogDocs.get(0)))
117 #else
118 ## Last, fallback to Blog.WebHome, the default blog
119 #set($result = $xwiki.getDocument('Blog.WebHome'))
120 #end
121 #end
122 #end
123 #end
124 #end
125 #set ($blogDoc = $NULL)
126 #setVariable ("$blogDoc" $result)
127 #end
128 ##
129 ##
130 ##
131 #**
132 * Retrieve the blog title.
133 *
134 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set.
135 * @param title The resulting title.
136 *###
137 #macro(getBlogTitle $blogDoc $title)
138 ## Titles can contain velocity code (most commonly translations), so we should evaluate them.
139 #set ($title = $NULL)
140 #setVariable ("$title" $!blogDoc.displayTitle)
141 #end
142 ##
143 ##
144 ##
145 #**
146 * Retrieve the blog description.
147 *
148 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt>
149 * property set.
150 * @param description The resulting description.
151 *###
152 #macro(getBlogDescription $blogDoc $description)
153 #getBlogProperty($blogDoc 'description' '' $result)
154 #set ($description = $NULL)
155 #setVariable ("$description" $result)
156 #end
157 ##
158 ##
159 ##
160 #**
161 * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
162 * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
163 * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
164 * month), or all.
165 *
166 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
167 * @param entries The resulting list of entries to display, a list of XDocument names.
168 *###
169 #macro(getBlogEntries $blogDoc $entries)
170 #if (!$entries)
171 #setVariable ("$entries" [])
172 #end
173 #getAllBlogPostsQuery($query)
174 #isDefaultBlog($blogDoc $isDefault)
175 #set($queryParams = {})
176 #if ($isDefault)
177 #getCategoryAllBlogPostsQuery($query)
178 #set($query = "${query} and (doc.creator = :creator or (isPublished.value = 1 and hidden.value = 0)) and (doc.space = :space or catList like :catList escape '!')")
179 #set($discard = $queryParams.put('creator', $xcontext.user))
180 #set($discard = $queryParams.put('space', $blogDoc.space))
181 #set($sanitizedBlogSpace = $blogDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
182 #set($discard = $queryParams.put('catList', $sanitizedBlogSpace))
183 #else
184 #set($query = "${query} and (doc.space = :space or doc.parent = :parent)")
185 #getBlogPostsLocation($blogDoc.space $blogPostsLocation)
186 #set($discard = $queryParams.put('space', $blogPostsLocation))
187 #set($discard = $queryParams.put('parent', $blogDoc.space))
188 #end
189 #getBlogDisplayType($blogDoc $displayType)
190 #if($displayType == 'weekly')
191 #getWeeklyBlogEntries($blogDoc $query $entries $queryParams)
192 #elseif($displayType == 'monthly')
193 #getMonthlyBlogEntries($blogDoc $query $entries $queryParams)
194 #elseif($displayType == 'all')
195 #getAllBlogEntries($blogDoc $query $entries $queryParams)
196 #else
197 #getPagedBlogEntries($blogDoc $query $entries $queryParams)
198 #end
199 #end
200 ##
201 ##
202 ##
203 #**
204 * Retrieves a list of entries to be displayed. The entries are taken from a "page" of the blog, a sequence of documents
205 * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the
206 * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property
207 * (10 if not defined).
208 *
209 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
210 * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
211 * refined to restrict to a given space, or to a given search criteria, etc.
212 * @param entries The resulting list of entries to display, a list of XDocument names.
213 * @param queryParams The parameters to bind with the query.
214 *###
215 #macro(getPagedBlogEntries $blogDoc $query $entries $queryParams)
216 #if (!$entries)
217 #setVariable ("$entries" [])
218 #end
219 #set($countQueryObj = $services.query.hql($query).addFilter("unique"))
220 #set($queryObj = $services.query.hql("${query} order by publishDate.value desc"))
221 #bindQueryParameters($countQueryObj $queryParams)
222 #bindQueryParameters($queryObj $queryParams)
223 #set($totalEntries = $countQueryObj.count())
224 #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
225 #set($defaultItemsPerPage = $numbertool.toNumber($defaultItemsPerPage).intValue())
226 ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
227 #preparePagedViewParams($totalEntries $defaultItemsPerPage)
228 #set($discard = $entries.addAll($queryObj.setLimit($itemsPerPage).setOffset($startAt).addFilter("unique").execute()))
229 #end
230 ##
231 ##
232 ##
233 #**
234 * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
235 * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4
236 * digit year). Initially the current week is displayed.
237 *
238 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
239 * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
240 * refined to restrict to a given space, or to a given search criteria, etc.
241 * @param entries The resulting list of entries to display, a list of XDocument names.
242 * @param queryParams The parameters to bind with the query.
243 *###
244 #macro(getWeeklyBlogEntries $blogDoc $query $entries $queryParams)
245 #if (!$entries)
246 #setVariable ("$entries" [])
247 #end
248 #getRequestedWeek($weekDate)
249 #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
250 #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
251 #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
252 #set($query = "${query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'")
253 #set($countQueryObj = $services.query.hql($query).addFilter("unique"))
254 #set($queryObj = $services.query.hql("${query} order by publishDate.value desc").addFilter("unique"))
255 #bindQueryParameters($countQueryObj $queryParams)
256 #bindQueryParameters($queryObj $queryParams)
257 #set($totalEntries = $countQueryObj.count())
258 #set($discard = $entries.addAll($queryObj.execute()))
259 #end
260 ##
261 ##
262 ##
263 #**
264 * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
265 * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4
266 * digit year). Initially the current month is displayed.
267 *
268 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
269 * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
270 * refined to restrict to a given space, or to a given search criteria, etc.
271 * @param entries The resulting list of entries to display, a list of XDocument names.
272 * @param queryParams The parameters to bind with the query.
273 *###
274 #macro(getMonthlyBlogEntries $blogDoc $query $entries)
275 #if (!$entries)
276 #setVariable ("$entries" [])
277 #end
278 #getRequestedMonth($monthDate)
279 #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
280 #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
281 #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
282 #set($query = "${query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'")
283 #set($countQueryObj = $services.query.hql($query).addFilter("unique"))
284 #set($queryObj = $services.query.hql("${query} order by publishDate.value desc").addFilter("unique"))
285 #bindQueryParameters($countQueryObj $queryParams)
286 #bindQueryParameters($queryObj $queryParams)
287 #set($totalEntries = $countQueryObj.count())
288 #set($discard = $entries.addAll($queryObj.execute()))
289 #end
290 ##
291 ##
292 ##
293 #**
294 * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
295 *
296 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
297 * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
298 * refined to restrict to a given space, or to a given search criteria, etc.
299 * @param entries The resulting list of entries to display, a list of XDocument names.
300 * @param queryParams The parameters to bind with the query.
301 *###
302 #macro(getAllBlogEntries $blogDoc $query $entries $queryParams)
303 #if (!$entries)
304 #setVariable ("$entries" [])
305 #end
306 #set($countQueryObj = $services.query.hql($query).addFilter("unique"))
307 #set($queryObj = $services.query.hql("${query} order by publishDate.value desc").addFilter("unique"))
308 #bindQueryParameters($countQueryObj $queryParams)
309 #bindQueryParameters($queryObj $queryParams)
310 #set($totalEntries = $countQueryObj.count())
311 #set($discard = $entries.addAll($queryObj.execute()))
312 #end
313 ##
314 ##
315 ##
316 #**
317 * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
318 *
319 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
320 * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
321 * refined to restrict to a given space, or to a given search criteria, etc.
322 * @param queryParams The parameters to bind with the query.
323 * @param entries The resulting list of entries to display, a list of XDocument names.
324 *###
325 #macro(getUnpublishedBlogEntries $blogDoc $query $queryParams $entries)
326 #if (!$entries)
327 #setVariable ("$entries" [])
328 #end
329 #set($query = "${query} and isPublished.value = 0")
330 #set ($countQueryObj = $services.query.hql($query).addFilter("unique"))
331 #set ($queryObj = $services.query.hql("${query} order by publishDate.value desc").addFilter("unique"))
332 #bindQueryParameters($countQueryObj $queryParams)
333 #bindQueryParameters($queryObj $queryParams)
334 #set($totalEntries = $countQueryObj.count())
335 #set($discard = $entries.addAll($queryObj.execute()))
336 #end
337 ##
338 ##
339 ##
340 #**
341 * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
342 *
343 * @param entries The resulting list of entries to display, a list of XDocument names.
344 *###
345 #macro(getGlobalBlogEntries $entries)
346 #if (!$entries)
347 #setVariable ("$entries" [])
348 #end
349 #getAllBlogPostsQuery($query)
350 #set($totalEntries = $services.query.hql($query).count())
351 #set($defaultItemsPerPage = 20)
352 ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
353 #preparePagedViewParams($totalEntries $defaultItemsPerPage)
354 #set($discard = $entries.addAll($services.query.hql("${query} order by publishDate.value desc").setLimit($itemsPerPage).setOffset($startAt).execute()))
355 #end
356 #**
357 * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
358 * blog, nor specify a range or an ordering criteria.
359 *
360 * This macro is a duplicate of #getAllBlogPostsQuery($query). Keep it in case it's used outside, in custom code.
361 *
362 * @param query The basic query for selecting blog entries.
363 *#
364 #macro(getBlogEntriesBaseQuery $query)
365 #getAllBlogPostsQuery($query)
366 #end
367 #**
368 * Return the Query for selecting the all wiki blog posts without filtering
369 *
370 * @param query The basic query for selecting blog entries.
371 *#
372 #macro(getAllBlogPostsQuery $query)
373 #set ($query = $NULL)
374 #setVariable("$query" ", BaseObject as obj, IntegerProperty isPublished,
375 IntegerProperty hidden, DateProperty publishDate
376 where doc.fullName <> '$blogPostTemplate' and
377 obj.name=doc.fullName and obj.className='$blogPostClassname' and
378 isPublished.id.id = obj.id and isPublished.id.name = 'published' and
379 hidden.id.id = obj.id and hidden.id.name='hidden' and
380 publishDate.id.id = obj.id and publishDate.id.name='publishDate' and
381 (doc.creator = '$escapetool.sql($xcontext.user)' or (isPublished.value = 1 and hidden.value = 0))")
382 #end
383 ##
384 ##
385 ##
386 ###**
387 * Return the Query for selecting the all wiki blog posts with categories filtering
388 *
389 * @param query The basic query for selecting blog entries.
390 *###
391 #macro(getCategoryAllBlogPostsQuery $query)
392 #set ($query = $NULL)
393 #getAllBlogPostsQuery($baseQuery)
394 #set ($baseQuery = $baseQuery.replace('DateProperty publishDate', 'DateProperty publishDate, DBStringListProperty as category left join category.list catList'))
395 #setVariable("$query" "${baseQuery} and obj.id=category.id.id and category.id.name='category'")
396 #end
397 ##
398 ##
399 ##
400 #**
401 * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
402 * week), monthly (all entries in a month), or all.
403 *
404 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt>
405 * property set.
406 * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
407 *###
408 #macro(getBlogDisplayType $blogDoc $displayType)
409 #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
410 #set ($displayType = $NULL)
411 #setVariable ("$displayType" $result)
412 #end
413 ##
414 ##
415 ##
416 #**
417 * Displays a list of entries.
418 *
419 * @param entries The entries to display, a list of XDocument names.
420 * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
421 * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
422 * used values: index, single, category, search, unpublished, hidden.
423 * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content.
424 * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're
425 * displayed alone on their page since it's the page title which is used in this case)
426 *###
427 #macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
428 #set($blogDay = '')
429 (% class="hfeed $!{displaying}" %)(((
430 (% class="blogDay" %)(((
431 #foreach ($entryDoc in $xwiki.wrapDocs($entries))
432 #getEntryObject($entryDoc $entryObj)
433 ## Although all entries should have one of the two objects, better check to be sure.
434 #if("$!{entryObj}" != '')
435 #getEntryDate($entryDoc $entryObj $entryDate)
436 ## Display a "calendar sheet" for each day. All entries posted on the same day share one such sheet.
437 #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
438 #if($blogDay != $entryDateStr)
439 #if($blogDay != '')
440 )))
441 (% class="blogDay" %)(((
442 #end
443 #displayBlogDate($entryDate)
444 #set ($blogDay = $entryDateStr)
445 #end
446 ## Finally, display the entry.
447 #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles true)
448 #end
449 #end
450 )))## blogDay
451 )))## hfeed
452 #end
453 ##
454 ##
455 ##
456 #**
457 * Get the entry object, either a new BlogPost or an old Article.
458 *
459 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
460 * @param entryObj The resulting xobject of the blog post.
461 *###
462 #macro(getEntryObject $entryDoc $__entryObj)
463 #set($result = $entryDoc.getObject("${blogPostClassname}"))
464 #if(!$result)
465 #set($result = $entryDoc.getObject("${oldArticleClassname}"))
466 #end
467 ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from
468 ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be
469 ## overwritten in this case but it's less likely to have such a variable defined before.
470 #set ($__entryObj = $NULL)
471 #setVariable ("$__entryObj" $result)
472 #end
473 ##
474 ##
475 ##
476 #**
477 * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
478 * the document creation date, but can be edited by the user.
479 *
480 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
481 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
482 * @param result The resulting date, an instance of <tt>java.util.Date</tt>.
483 *###
484 #macro(getEntryDate $entryDoc $entryObj $result)
485 #set ($result = $NULL)
486 #setVariable ("$result" $entryObj.getProperty('publishDate').value)
487 #end
488 ##
489 ##
490 ##
491 #**
492 * Displays a date, nicely formatted as a calendar page.
493 *
494 * @param date The date to display, an instance of <tt>java.util.Date</tt>.
495 *###
496 #macro(displayBlogDate $date)
497 #set($year = $xwiki.formatDate($date, 'yyyy'))
498 ## 3 letter month name, like Jan, Dec.
499 #set($month = $xwiki.formatDate($date, 'MMM'))
500 ## Uncomment to get a full length month name, like January, December.
501 ## TODO: this could be defined somewhere in the blog style.
502 ## #set($month = $xwiki.formatDate($date, 'MMMM'))
503 #set($day = $xwiki.formatDate($date, 'dd'))
504 (% class="blogdate" %)
505 == (% class="month" %)$month(%%) (% class="day" %)$day(%%) (% class="year" %)$year(%%) ==
506 #end
507 ##
508 ##
509 ##
510 #**
511 * Displays a blog article: management tools, header, content, footer.
512 *
513 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
514 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
515 * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
516 * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title
517 * when they're displayed alone on their page since it's the page title which is used in this case)
518 * @param shouldDisplayActions If <tt>true</tt>, display the blog post actions buttons
519 *###
520 #macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle $shouldDisplayActions)
521 ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
522 #isPublished($entryObj $isPublished)
523 #isHidden($entryObj $isHidden)
524 #if($doc.fullName == $entryDoc.fullName)
525 (% class="hentry single-article" %)(((
526 #else
527 (% class="hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end" %)(((
528 #end
529 #if ($shouldDisplayActions)
530 #displayEntryTools($entryDoc $entryObj)
531 #end
532 #if($shouldDisplayTitle)
533 #displayEntryTitle($entryDoc $entryObj)
534 #end
535 #if($doc.fullName == $entryDoc.fullName)
536 #if(!$isPublished)
537 {{warning}}{{translation key='blog.code.published'/}}{{/warning}}
538 #elseif($isHidden)
539 {{warning}}{{translation key='blog.code.hidden'/}}{{/warning}}
540 #end
541 #end
542 #displayEntryContent($entryDoc $entryObj $onlyExtract)
543 #displayEntryFooter($entryDoc $entryObj)
544 )))## hentry
545 #end
546 ##
547 ##
548 ##
549 #**
550 * Checks if the provided blog is published or not.
551 *
552 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
553 * @param isPublished The resulting boolean, true if the entry is considered published.
554 *###
555 #macro(isPublished $entryObj $isPublished)
556 #set ($isPublished = $NULL)
557 ## This should work for both old articles, which don't have the 'published' property at all, and
558 ## are considered published by default, and new entries, that should have 1 if published.
559 #if ("$!{entryObj.getProperty('published').value}" != '0')
560 #setVariable ("$isPublished" true)
561 #else
562 #setVariable ("$isPublished" false)
563 #end
564 #end
565 ##
566 ##
567 ##
568 #**
569 * Checks if the provided blog is hidden or not.
570 *
571 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass.
572 * @param isHiddel The resulting boolean, true if the entry is considered hidden.
573 *###
574 #macro(isHidden $entryObj $isHidden)
575 #set ($isHidden = $NULL)
576 ## This should work for both old articles, which don't have the 'hidden' property at all, and
577 ## are considered visible by default, and new entries, that should have 1 if hidden.
578 #if ("$!{entryObj.getProperty('hidden').value}" == '1')
579 #setVariable ("$isHidden" true)
580 #else
581 #setVariable ("$isHidden" false)
582 #end
583 #end
584 ##
585 ##
586 ##
587 #**
588 * Displays several "tools" for manipulating blog posts: hide/show, publish, edit.
589 *
590 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
591 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
592 *###
593 #macro(displayEntryTools $entryDoc $entryObj)
594 #if($xcontext.action == 'view')
595 (% class="blog-entry-toolbox" %)(((
596 #displayPublishButton($entryDoc $entryObj)
597 #displayHideShowButton($entryDoc $entryObj)
598 #displayEditButton($entryDoc $entryObj)
599 #displayDeleteButton($entryDoc $entryObj)
600 )))
601 #end
602 #end
603 ##
604 ##
605 ##
606 #**
607 * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet.
608 *
609 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
610 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
611 * @todo AJAX calls.
612 *###
613 #macro(displayPublishButton $entryDoc $entryObj)
614 #isPublished($entryObj $isPublished)
615 #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
616 [[#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')"]]##
617 #end
618 #end
619 ##
620 ##
621 ##
622 #**
623 * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published.
624 *
625 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
626 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
627 *###
628 #macro(displayHideShowButton $entryDoc $entryObj)
629 #isPublished($entryObj $isPublished)
630 #isHidden($entryObj $isHidden)
631 ## Only published articles can be hidden. Unpublished articles are considered already hidden.
632 #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
633 #set ($queryString = {
634 'xredirect' : $thisURL,
635 'form_token' : $services.csrf.getToken()
636 })
637 #if ($isHidden)
638 #set ($discard = $queryString.putAll({
639 "${entryObj.getxWikiClass().getName()}_${entryObj.number}_hidden" : 0,
640 'comment' : $services.localization.render('blog.code.madevisible')
641 }))
642 #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
643 [[#toolImage('unlock')>>path:$lockURL||class="blog-tool-show" title="$services.localization.render('blog.code.makevisible')"]]##
644 #else
645 #set ($discard = $queryString.putAll({
646 "${entryObj.getxWikiClass().getName()}_${entryObj.number}_hidden" : 1,
647 'comment' : $services.localization.render('blog.code.hid')
648 }))
649 #set ($lockURL = $entryDoc.getURL('save', $escapetool.url($queryString)))
650 [[#toolImage('lock')>>path:$lockURL||class="blog-tool-hide" title="$services.localization.render('blog.code.hide')"]]##
651 #end
652 #end
653 #end
654 ##
655 ##
656 ##
657 #**
658 * Displays the edit button to those that can edit the article.
659 *
660 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
661 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
662 *###
663 #macro(displayEditButton $entryDoc $entryObj)
664 #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
665 ## Call getDefaultEditMode() for backward compatibility with older blog posts.
666 [[#toolImage('pencil')>>path:$entryDoc.getURL('edit')||title="$services.localization.render('blog.code.editpost')"]]##
667 #end
668 #end
669 ##
670 ##
671 ##
672 #**
673 * Displays the delete button to those that can edit the article.
674 *
675 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
676 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
677 * @todo AJAX calls.
678 *###
679 #macro(displayDeleteButton $entryDoc $entryObj)
680 #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
681 [[#toolImage('cross')>>path:$entryDoc.getURL('delete')||title="$services.localization.render('blog.code.deletepost')"]]##
682 #end
683 #end
684 ##
685 ##
686 ##
687 #**
688 * Displays the title of the entry.
689 *
690 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
691 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
692 *###
693 #macro(displayEntryTitle $entryDoc $entryObj)
694 #if($doc.fullName == $entryDoc.fullName)
695 (% class="entry-title" %)
696 = $services.rendering.escape($entryDoc.display('title', 'view', $entryObj), $xwiki.getCurrentContentSyntaxId()) =
697 #else
698 (% class="entry-title" %)
699 === [[$services.rendering.escape($entryDoc.display('title', 'view', $entryObj),$xwiki.getCurrentContentSyntaxId())>>doc:$services.rendering.escape($services.model.serialize($entryDoc.getDocumentReference(),'default'),$xwiki.getCurrentContentSyntaxId())]] ===
700 #end
701 #end
702 ##
703 ##
704 ##
705 #**
706 * Displays the body of the entry.
707 *
708 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
709 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
710 * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
711 *###
712 #macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
713 (% class="#if($onlyExtract)entry-summary#{else}entry-content#end" %)(((
714 #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
715 ## FIXME: This causes the blog's content to not be annotatable. See http://jira.xwiki.org/browse/XWIKI-6328
716 ## Should probably be replaced by a display macro call with a reference to the object property holding the post's content
717 {{html wiki="false"}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString()){{/html}}
718 ))) ## entry-content
719 (% class="clearfloats" %)((()))
720 #end
721 ##
722 ##
723 ##
724 #**
725 * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content
726 * of the <tt>extract</tt> field (if not empty).
727 *
728 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
729 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
730 * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content.
731 * @param entryContent The resulting content.
732 * @param removeEllipsis If <tt>true</tt>, then don't display an ellipsis at the end of the content (only used when
733 * <tt>onlyExtract</tt> is <tt>true</tt>)
734 *###
735 #macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent $removeEllipsis)
736 #if ($onlyExtract)
737 ## Note: We trim the summary so that if there's some white space it won't cause the summary to be used instead
738 ## of the content.
739 #set ($macro.result = $entryObj.getProperty('extract').value.trim())
740 #end
741 #if("$!macro.result" == '')
742 #set($macro.result = $entryObj.getProperty('content').value)
743 #* Disabled until the content can be cleanly cut.
744 * #if($onlyExtract && $result.length()>$maxchars)
745 * #set($i = $macro.result.lastIndexOf(" ", $maxchars))
746 * #set($i = $i + 1)
747 * #set($macro.result = "${macro.result.substring(0,$i)} *[...>${entryDoc.fullName}]*")
748 * #end
749 ## *###
750 #elseif (!$removeEllipsis)
751 #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
752 #set($macro.result = "${macro.result} <a href='${entryDoc.getExternalURL()}' title='$services.localization.render('blog.code.readpost')'>...</a>")
753 #elseif($entryDoc.syntax.toIdString() == 'xwiki/2.0' || $entryDoc.syntax.toIdString() == 'xwiki/2.1')
754 #set($macro.result = "${macro.result} [[...>>${services.rendering.escape($entryDoc.getFullName(), $entryDoc.getSyntax())}||title='$services.localization.render('blog.code.readpost')']]")
755 #end
756 #end
757 #set ($entryContent = $NULL)
758 #setVariable ("$entryContent" $macro.result)
759 #end
760 ##
761 ##
762 ##
763 #**
764 * Displays the footer of the entry.
765 *
766 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
767 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
768 *###
769 #macro(displayEntryFooter $entryDoc $entryObj)
770 (% class="entry-footer" %)(((
771 #isPublished($entryObj $isPublished)
772 (% class='entry-author-label' %)
773 #if($isPublished)
774 {{translation key='blog.code.postedby'/}} ##
775 #else
776 {{translation key='blog.code.createdby'/}} ##
777 #end
778 {{html wiki="false" clean="false"}}<span class='author vcard'>#userfn($entryDoc.creator)</span>{{/html}} ##
779 #getEntryDate($entryDoc $entryObj $entryDate)
780 #listCategories($entryObj) #*
781 ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
782 ## we assume cannot be more than 3 seconds.
783 *#(% class="separator" %)·(%%) [[{{translation key='blog.code.permalink'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||rel="bookmark"]] ##
784 #if ($showcomments)
785 (% class="separator" %)·(%%) [[{{translation key='blog.code.comments'/}}>>$services.rendering.escape($entryDoc,'xwiki/2.0')||anchor="Comments"]] (% class="itemCount" %)($entryDoc.comments.size())(%%) ##
786 #end ##
787 #if($entryDoc != $doc) ##
788 #displayEntryBlogLocation($entryDoc $entryObj) ##
789 #end
790 )))## entry-footer
791 #end
792 ##
793 ##
794 #**
795 * Display the blog for the entry (if it is not the currently displayed blog)
796 *
797 * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
798 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
799 *###
800 #macro(displayEntryBlogLocation $entryDoc $entryObj)
801 #getBlogPostsLocation($entryDoc.getSpace() $blogPostsLocation) ##
802 #if("$!blogPostsLocation" != "") ##
803 #set($blogSpaceRef = $services.model.resolveSpace($blogPostsLocation)) ##
804 #set($blogDocRef = $services.model.createDocumentReference($services.model.getEntityReference('DOCUMENT', 'default').getName(), $blogSpaceRef)) ##
805 #if($doc.documentReference != $blogDocRef) ##
806 #set($blogDoc = $xwiki.getDocument($blogDocRef)) ##
807 #set($blogObj = $blogDoc.getObject('Blog.BlogClass')) ##
808 #if($blogObj) (% class="blogrefpath" %)((( ##
809 $services.localization.render('blog.code.postedin') {{html clean="false" wiki="false"}} #hierarchy($blogDocRef, {'selfIsActive' : true, 'local': true}) {{/html}} ##
810 )))(%%)##
811 #end
812 #end
813 #end
814 #end
815 ##
816 ##
817 ##
818 ##
819 #**
820 * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>.
821 *
822 * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass.
823 *###
824 #macro(listCategories $entryObj)
825 #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
826 #set($categories = $entryObj.getProperty('category').value)
827 #set($first = true)
828 #if($categories.size() > 0)
829 #foreach($category in $categories)
830 #set($categoryDoc = $!xwiki.getDocument($category))
831 #if(!$categoryDoc.isNew() && $categoryDoc.getObject(${blogCategoryClassname}))
832 #if($foreach.count == 1)
833 (% class='separator' %)·(%%) $services.localization.render('blog.code.categories') ##
834 #else
835 , ##
836 #end##
837 [[$!{categoryDoc.getObject($blogCategoryClassname).getValue('name')}>>${category}||rel='tag']]##
838 #end##
839 #end##
840 #end
841 #end
842 #end
843 ##
844 ##
845 ##
846 #**
847 * Displays blog pagination links (older and newer entries).
848 *
849 * @param blogDoc the XDocument holding the blog definition object.
850 *###
851 #macro(displayNavigationLinks $blogDoc)
852 (% class="clearfloats" %)((()))
853 #getBlogDisplayType($blogDoc $displayType)
854 #if($displayType == 'weekly')
855 (% class="pagingLinks" %)(((
856 #getRequestedWeek($weekDate)
857 $weekDate.addWeeks(-1)##
858 (% class="prevPage" %)**[[« {{translation key='blog.code.previousweek'/}}>>$doc.documentReference.name||queryString="year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear" class="button"]]**(%%)
859 #sep()
860 $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
861 (% class="nextPage" %)**[[{{translation key='blog.code.nextweek'/}} »>>$doc.documentReference.name||queryString="year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear" class="button"]]**(%%)
862 )))
863 #elseif($displayType == 'monthly')
864 (% class="pagingLinks" %)(((
865 #getRequestedMonth($monthDate)
866 $monthDate.addMonths(-1)##
867 (% class="prevPage" %)**[[« {{translation key='blog.code.previousmonth'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString="year=$monthDate.year&month=$monthDate.monthOfYear" class="button"]]**(%%)
868 #sep()
869 $monthDate.addMonths(2)## 2 because we already subtracted 1 above
870 (% class="nextPage" %)**[[{{translation key='blog.code.nextmonth'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString="year=$monthDate.year&month=$monthDate.monthOfYear" class="button"]]**(%%)
871 )))
872 #elseif($displayType == 'all')
873 #else
874 ## Paginated
875 #if(($totalPages > 1))
876 #set($queryString = '')
877 #foreach($p in $request.getParameterNames())
878 #if($p != 'page' && $p != 'ipp')
879 #foreach($v in $request.getParameterValues($p))
880 #set($queryString = "${queryString}&${escapetool.url($p)}=${escapetool.url($v)}")
881 #end
882 #end
883 #end
884 (% class="pagingLinks" %)(((
885 #if ($currentPageNumber < $totalPages)
886 #set($currentPageNumber = $currentPageNumber + 1)
887 (% class="prevPage" %)**[[« {{translation key='blog.code.olderposts'/}}>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString="page=${currentPageNumber}&ipp=${itemsPerPage}$queryString" class="button"]]**(%%)
888 #set($currentPageNumber = $currentPageNumber - 1)
889 #end
890 #if ($currentPageNumber > 1)
891 #if ($currentPageNumber < $totalPages)
892 #sep()
893 #end
894 #set($currentPageNumber = $currentPageNumber - 1)
895 (% class="nextPage" %)**[[{{translation key='blog.code.newerposts'/}} »>>$services.rendering.escape($doc.documentReference.name,$doc.syntax)||queryString="page=${currentPageNumber}&ipp=${itemsPerPage}$queryString" class="button"]]**(%%)
896 #set($currentPageNumber = $currentPageNumber + 1)
897 #end
898 (% class="clear" %)(%%)
899 )))## pagingLinks
900 #end
901 #end
902 #end
903 ##
904 ##
905 ##
906 #**
907 * Displays a message box with "publish" icon.
908 *
909 * @param message A text message concerning blog article publishing
910 *###
911 #macro(publishMessageBox $message)
912 (% class="plainmessage publish-message" %)((($services.icon.render('world') $message)))
913 #end
914 #**
915 * Displays a message box with "show/hide" icon.
916 *
917 * @param message A text message concerning blog article hiding
918 *###
919 #macro(hideMessageBox $message)
920 (% class="plainmessage hide-message" %)((($services.icon.render('unlock') $message)))
921 #end
922 ##
923 ##
924 ##
925 #**
926 * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
927 * <tt>year</tt> and <tt>week</tt>. By default, the current week is used.
928 *
929 * @param monthDate The resulting week, a JODATime MutableDateTime.
930 *###
931 #macro(getRequestedWeek $weekDate)
932 #set ($weekDate = $NULL)
933 #setVariable ("$weekDate" $xwiki.jodatime.mutableDateTime)
934 #if("$!{request.year}" != '')
935 #set ($discard = $weekDate.setYear($numbertool.toNumber($request.year).intValue()))
936 #end
937 #if("$!{request.week}" != '')
938 #set ($discard = $weekDate.setWeekOfWeekyear($numbertool.toNumber($request.week).intValue()))
939 #end
940 #end
941 ##
942 ##
943 ##
944 #**
945 * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
946 * <tt>year</tt> and <tt>month</tt>. By default, the current month is used.
947 *
948 * @param monthDate The resulting month, a JODATime MutableDateTime.
949 *###
950 #macro(getRequestedMonth $monthDate)
951 #set ($monthDate = $NULL)
952 #setVariable ("$monthDate" $xwiki.jodatime.mutableDateTime)
953 #if("$!{request.year}" != '')
954 #set ($discard = $monthDate.setYear($numbertool.toNumber($request.year).intValue()))
955 #end
956 #if("$!{request.month}" != '')
957 #set ($discard = $monthDate.setMonthOfYear($numbertool.toNumber($request.month).intValue()))
958 #end
959 #end
960 ##
961 ##
962 ##
963 #**
964 * Retrieve a blog property (title, display type, etc).
965 *
966 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
967 * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties.
968 * @param defaultValue The default value to use in case the blog object does not define one.
969 * @param propertyValue The resulting value.
970 *###
971 #macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
972 #set($result = "$!{blogDoc.getObject(${blogClassname}).getProperty($propertyName).value}")
973 #if($result == '')
974 #set($result = $defaultValue)
975 #end
976 #set ($propertyValue = $NULL)
977 #setVariable ("$propertyValue" $result)
978 #end
979
980 #**
981 * If an error occurs when executing an action, set a specific response status and display an error message.
982 *
983 * @param status The response status.
984 * @param text The user readable error to be displayed. Can be a translation key.
985 * @param parameters The parameters to use when decoding the translation key.
986 *###
987 #macro(blog__actionResponseError $status $text $parameters)
988 $response.setStatus($status)
989 #if($request.ajax)
990 $services.localization.render($text, $!parameters)
991 #else
992 {{error}}$services.localization.render($text, $!parameters){{/error}}
993 #end
994 #end
995 ##
996 ##
997 ##
998 #**
999 * Check if a blog is the Default blog (The one in the 'Blog' space).
1000 *
1001 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object.
1002 * @param isDefault The resulting boolean.
1003 *###
1004 #macro(isDefaultBlog $blogDoc $isDefault)
1005 #set ($result = false)
1006 #if ($blogDoc.space == 'Blog')
1007 #set ($result = true)
1008 #end
1009 #setVariable("$isDefault" $result)
1010 #end
1011 ##
1012 ##
1013 ##
1014 #**
1015 * Retrieve the blog posts location (space).
1016 *
1017 * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
1018 * @param postsLocation The resulting location.
1019 *###
1020 #macro(getBlogPostsLocation $blogSpace $postsLocation)
1021 #getBlogDocument($blogSpace $blogDoc)
1022 #getBlogProperty($blogDoc 'postsLocation' $blogDoc.space $result)
1023 #set ($postsLocation = $NULL)
1024 #setVariable ("$postsLocation" $result)
1025 #end
1026 ##
1027 ##
1028 ##
1029 #**
1030 * Retrieve the blog categories location (space).
1031 *
1032 * @param blogSpace The blog space. It should contain a document with a <tt>Blog.BlogClass</tt> object
1033 * @param categoriesLocation The resulting location.
1034 *###
1035 #macro(getBlogCategoriesLocation $blogSpace $categoriesLocation)
1036 #getBlogDocument($blogSpace $blogDoc)
1037 #getBlogProperty($blogDoc 'categoriesLocation' 'Blog' $result)
1038 #set ($postsLocation = $NULL)
1039 #setVariable ("$categoriesLocation" $result)
1040 #end
1041 ###**
1042 * Return the Query for selecting the blog posts based on the context where the posts are displayed.
1043 * for example there is 4 different panel contexts:
1044 * aBlog.aPost or aBlog.WebHome
1045 * aCategorySpace.aCategory
1046 * aCategorySpace.WebHome
1047 * Blog.aPost or Blog.WebHome
1048 *
1049 * @param query The query for selecting blog entries.
1050 * @param queryParams The parameters to bind with the generated query.
1051 * @param targetDoc The document in which the articles will be displayed.
1052 *###
1053 #macro(getAllBlogPostsQueryBasedOnDisplayContext $targetDoc $query $queryParams)
1054 #set ($query = $NULL)
1055 #set ($queryParams = $NULL)
1056 #getCategoryAllBlogPostsQuery($resultQuery)
1057 #set ($resultQueryParams = {})
1058 #set($sanitizedSpace = $targetDoc.space.replaceAll('([%_!])', '!$1').concat('.%'))
1059 #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
1060 ## Get all posts that are in the default blog space('Blog') or in category 'Blog.%'
1061 #set ($discard = $resultQueryParams.put('space', $targetDoc.space))
1062 #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
1063 #set($resultQuery = "${resultQuery} and (doc.space = :space or catList like :catList escape '!')")
1064 #elseif($targetDoc.getObject($blogCategoryClassname))
1065 ## Get all posts that are in a category aCategorySpace.aCategory
1066 #set ($discard = $resultQueryParams.put('catList', $targetDoc.fullName))
1067 #set($resultQuery = "${resultQuery} and (catList=:catList)")
1068 #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
1069 ## Get all posts that are in a category aCategorySpace.%
1070 #set ($discard = $resultQueryParams.put('catList', $sanitizedSpace))
1071 ## Exclude incategorized posts
1072 #set ($excludedCategory = "${targetDoc.space}.WebHome")
1073 #if ($targetDoc.space == $defaultBlogSpace)
1074 #set ($excludedCategory = "Blog.Categories.WebHome")
1075 #end
1076 #set ($discard = $resultQueryParams.put('excludedCategory', $excludedCategory))
1077 #set($resultQuery = "${resultQuery} and (catList<>:excludedCategory) and (catList like :catList escape '!')")
1078 #else
1079 ## Get all posts in blog space aBlog
1080 #getAllBlogPostsQuery($resultQuery)
1081 #getBlogPostsLocation($targetDoc.space $postsLocation)
1082 #set ($discard = $resultQueryParams.put('space', $postsLocation))
1083 #set($resultQuery = "${resultQuery} and doc.space = :space")
1084 #end
1085 #setVariable("$query" $resultQuery)
1086 #setVariable("$queryParams" $resultQueryParams)
1087 #end
1088 ##
1089 ##
1090 ##
1091 ###**
1092 * Display blog posts based on the context where the posts are displayed.
1093 * for example there is 4 different panel contexts:
1094 * aBlog.aPost or aBlog.WebHome
1095 * aCategorySpace.aCategory
1096 * aCategorySpace.WebHome
1097 * Blog.aPost or Blog.WebHome
1098 *
1099 * @param targetDoc The document in which the articles will be displayed.
1100 * @param postsVisiblity The visibility of the posts to display: recent, unpublished, ...
1101 * @param layout Layout of the the posts to display
1102 * @param layoutParams additional layout parameters, it is a string like 'param1=val1|...|paramN=valueN'
1103 * @param limit the number of posts to display
1104 *###
1105 #macro(displayBlogPostsBasedOnContext $targetDoc $postsVisiblity $layout $layoutParams $limit)
1106 #if ($postLayout == 'full')
1107 #set ($macro.paginated = 'yes')
1108 #end
1109 #if ($targetDoc.space == $defaultBlogSpace && !$targetDoc.getObject($blogCategoryClassname))
1110 ## Display all posts that are in the default blog space('Blog') or in category 'Blog.%'
1111 #getBlogPostsLayout($xwiki.getDocument("${defaultBlogSpace}.WebHome") $postsLayout)
1112 #if ("$!layout" == '')
1113 #set ($layout = $postsLayout)
1114 #end
1115 #if ($postsVisiblity == 'recent')
1116 {{blogpostlist blog="${defaultBlogSpace.replaceAll('~', '~~').replaceAll('"', '~"')}.WebHome" published='yes' hidden='no' layout="$!layout.replaceAll('~', '~~').replaceAll('"', '~"')" layoutParams="$!layoutParams.replaceAll('~', '~~').replaceAll('"', '~"')" limit="$limit" /}}
1117 #elseif($postsVisiblity == 'unpublished')
1118 {{blogpostlist blog="${defaultBlogSpace.replaceAll('~', '~~').replaceAll('"', '~"')}.WebHome" published='no' layout="$!layout.replaceAll('~', '~~').replaceAll('"', '~"')" layoutParams="$!layoutParams.replaceAll('~', '~~').replaceAll('"', '~"')" paginated="$!macro.paginated" limit="$limit" /}}
1119 #end
1120 #elseif($targetDoc.getObject($blogCategoryClassname))
1121 ## Display all posts that are in a category aCategorySpace.aCategory
1122 #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
1123 #getBlogPostsLayout($blogDoc $postsLayout)
1124 #if ("$!layout" == '')
1125 #set ($layout = $postsLayout)
1126 #end
1127 #if ($postsVisiblity == 'recent')
1128 {{blogpostlist category="$targetDoc.fullName.replaceAll('~', '~~').replaceAll('"', '~"')" published='yes' hidden='no' layout="$!layout.replaceAll('~', '~~').replaceAll('"', '~"')" layoutParams="$!layoutParams.replaceAll('~', '~~').replaceAll('"', '~"')" limit="$limit" /}}
1129 #elseif($postsVisiblity == 'unpublished')
1130 {{blogpostlist category="$targetDoc.fullName.replaceAll('~', '~~').replaceAll('"', '~"')" published='no' layout="$!layout.replaceAll('~', '~~').replaceAll('"', '~"')" layoutParams="$!layoutParams.replaceAll('~', '~~').replaceAll('"', '~"')" paginated="$!macro.paginated" limit="$limit" /}}
1131 #end
1132 #elseif($targetDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet')
1133 ## Display all posts that are in a category aCategorySpace.%
1134 #getBlogDocumentForCategoriesSpace($targetDoc.space $blogDoc)
1135 #getBlogPostsLayout($blogDoc $postsLayout)
1136 #if ("$!layout" == '')
1137 #set ($layout = $postsLayout)
1138 #end
1139 #if ($postsVisiblity == 'recent')
1140 {{blogpostlist category="$targetDoc.space.replaceAll('~', '~~').replaceAll('"', '~"')" published='yes' hidden='no' layout="$!layout.replaceAll('~', '~~').replaceAll('"', '~"')" layoutParams="$!layoutParams.replaceAll('~', '~~').replaceAll('"', '~"')" limit="$limit" /}}
1141 #elseif($postsVisiblity == 'unpublished')
1142 {{blogpostlist category="$targetDoc.space.replaceAll('~', '~~').replaceAll('"', '~"')" published='no' layout="$!layout.replaceAll('~', '~~').replaceAll('"', '~"')" layoutParams="$!layoutParams.replaceAll('~', '~~').replaceAll('"', '~"')" paginated="$!macro.paginated" limit="$limit" /}}
1143 #end
1144 #else
1145 ## Display all posts in blog space aBlog
1146 #getBlogDocument($targetDoc.space $blogDoc)
1147 #getBlogPostsLayout($blogDoc $postsLayout)
1148 #if ("$!layout" == '')
1149 #set ($layout = $postsLayout)
1150 #end
1151 #if ($postsVisiblity == 'recent')
1152 {{blogpostlist blog="$blogDoc.fullName.replaceAll('~', '~~').replaceAll('"', '~"')" published='yes' hidden='no' layout="$!layout.replaceAll('~', '~~').replaceAll('"', '~"')" limit="$limit" /}}
1153 #elseif($postsVisiblity == 'unpublished')
1154 {{blogpostlist blog="$blogDoc.fullName.replaceAll('~', '~~').replaceAll('"', '~"')" published='no' layout="$!layout.replaceAll('~', '~~').replaceAll('"', '~"')" layoutParams="$!layoutParams.replaceAll('~', '~~').replaceAll('"', '~"')" paginated="$!macro.paginated" limit="$limit" /}}
1155 #end
1156 #end
1157 #end
1158 ##
1159 ##
1160 ##
1161 #**
1162 * Bind parameters to a query object.
1163 *
1164 * @param queryObj The query object (org.xwiki.query.internal.ScriptQuery object)
1165 * @param queryParams the query parameters.
1166 *###
1167 #macro(bindQueryParameters $queryObj $queryParams)
1168 #set ($output = $queryObj)
1169 #foreach( $key in $queryParams.keySet() )
1170 #set($output = $queryObj.bindValue($key, $queryParams.get($key)))
1171 #end
1172 #setVariable("$queryObj" $output)
1173 #end
1174 ##
1175 ##
1176 ##
1177 #**
1178 * Determines the blogposts layout: Default layout (Calendar), Image thumbnail
1179 *
1180 * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>postsLayout</tt>
1181 * property set.
1182 * @param postsLayout The resulting string. If the blog object does not define anything, it is considered full (default).
1183 *###
1184 #macro(getBlogPostsLayout $blogDoc $postsLayout)
1185 #getBlogProperty($blogDoc 'postsLayout' 'full' $res)
1186 #set ($postsLayout = $NULL)
1187 #setVariable ("$postsLayout" $res)
1188 #end
1189 ##
1190 ##
1191 ##
1192 #**
1193 * Retrieve the blog document of a categories space, which is the blog descriptor that have its categoriesLocation property set to the categories space
1194 *
1195 * @param categoriesSpace A <tt>String</tt>, the name of the space.
1196 * @param blogDoc The resulting XDocument.
1197 *###
1198 #macro(getBlogDocumentForCategoriesSpace $categoriesSpace $blogDoc)
1199 #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())
1200 #if($macro.blogDocs.size() > 0 && $categoriesSpace != $defaultBlogSpace)
1201 #set($macro.result = $xwiki.getDocument($macro.blogDocs.get(0)))
1202 #else
1203 ## Fallback to Blog.WebHome, the default blog
1204 #set($macro.result = $xwiki.getDocument('Blog.WebHome'))
1205 #end
1206 #set ($blogDoc = $NULL)
1207 #setVariable ("$blogDoc" $macro.result)
1208 #end
1209 {{/velocity}}

Get Connected