Código fuente wiki de Macros for the Blog application
Última modificación por Administrator el 2014/10/29 07:38
Mostrar los últimos autores
author | version | line-number | content |
---|---|---|---|
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 | ## | ||
12 | ## | ||
13 | #** | ||
14 | * Prints a blog. This is the main macro used in the BlogSheet. | ||
15 | * | ||
16 | * @param blogDoc the XDocument holding the blog definition object. | ||
17 | *### | ||
18 | #macro(printBlog $blogDoc) | ||
19 | {{include reference='Blog.CreatePost'/}} | ||
20 | #getBlogEntries($blogDoc $entries) | ||
21 | #displayBlog($entries 'index' true true) | ||
22 | #displayNavigationLinks($blogDoc) | ||
23 | #end | ||
24 | ## | ||
25 | ## | ||
26 | ## | ||
27 | #** | ||
28 | * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title, | ||
29 | * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index, | ||
30 | * all entries). | ||
31 | * | ||
32 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. | ||
33 | *### | ||
34 | #macro(showBlogInfo $blogDoc) | ||
35 | #if($blogDoc.getObject($blogClassname)) | ||
36 | ## Keep testing for inline action for backward compatibility with older blogs. | ||
37 | #if($xcontext.action == 'edit' || $xcontext.action == 'inline') | ||
38 | #macro(displayProperty $blogDoc $propname) | ||
39 | ; #displayPropName($xwiki.getClass($blogClassname).get($propname)): | ||
40 | : $blogDoc.display($propname) | ||
41 | #end | ||
42 | #displayProperty($blogDoc 'title') | ||
43 | #displayProperty($blogDoc 'description') | ||
44 | #displayProperty($blogDoc 'blogType') | ||
45 | #displayProperty($blogDoc 'displayType') | ||
46 | #displayProperty($blogDoc 'itemsPerPage') | ||
47 | #else | ||
48 | $blogDoc.display('description') | ||
49 | #end | ||
50 | #elseif($doc.fullName == $blogSheet) | ||
51 | = $services.localization.render('xe.blog.code.blogsheet') = | ||
52 | {{translation key='xe.blog.code.sheetexplanation'/}} | ||
53 | #else | ||
54 | {{warning}}{{translation key='xe.blog.code.notblog'/}}{{/warning}} | ||
55 | #end | ||
56 | #end | ||
57 | ## | ||
58 | ## | ||
59 | ## | ||
60 | #** | ||
61 | * Retrieve the blog document, which usually is either <tt><Space>.WebHome</tt> for whole-spaces blogs, or | ||
62 | * <tt><Space>.Blog</tt> for in-space blogs. If none of these documents contains a blog object, then the first | ||
63 | * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current | ||
64 | * space contains a blog object, then <tt>Blog.WebHome</tt> is returned as the default blog. | ||
65 | * | ||
66 | * @param space A <tt>String</tt>, the name of the space where to search. | ||
67 | * @param blogDoc The resulting XDocument. | ||
68 | *### | ||
69 | #macro(getBlogDocument $space $blogDoc) | ||
70 | ## First, try the Space.WebHome, for a whole-space blog | ||
71 | #set($result = $xwiki.getDocument("${space}.WebHome")) | ||
72 | #if(!$result.getObject($blogClassname)) | ||
73 | ## Second, try the Space.Blog document | ||
74 | #set($result = $xwiki.getDocument("${space}.Blog")) | ||
75 | #if(!$result.getObject($blogClassname)) | ||
76 | ## Third, try searching for a blog document in the current space | ||
77 | #set($blogDocs = $services.query.hql(", BaseObject obj where doc.space = ? and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name").setLimit(1).setOffset(0).bindValues([${space}]).execute()) | ||
78 | #if($blogDocs.size() > 0) | ||
79 | #set($result = $xwiki.getDocument($blogDocs.get(0))) | ||
80 | #else | ||
81 | ## Last, fallback to Blog.WebHome, the default blog | ||
82 | #set($result = $xwiki.getDocument('Blog.WebHome')) | ||
83 | #end | ||
84 | #end | ||
85 | #end | ||
86 | #set ($blogDoc = $NULL) | ||
87 | #setVariable ("$blogDoc" $result) | ||
88 | #end | ||
89 | ## | ||
90 | ## | ||
91 | ## | ||
92 | #** | ||
93 | * Retrieve the blog title. | ||
94 | * | ||
95 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass<tt> object with the <tt>title</tt> property set. | ||
96 | * @param title The resulting title. | ||
97 | *### | ||
98 | #macro(getBlogTitle $blogDoc $title) | ||
99 | #getBlogProperty($blogDoc 'title' $!blogDoc.displayTitle $result) | ||
100 | #set ($title = $NULL) | ||
101 | #setVariable ("$title" $result) | ||
102 | #end | ||
103 | ## | ||
104 | ## | ||
105 | ## | ||
106 | #** | ||
107 | * Retrieve the blog description. | ||
108 | * | ||
109 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>description</tt> | ||
110 | * property set. | ||
111 | * @param description The resulting description. | ||
112 | *### | ||
113 | #macro(getBlogDescription $blogDoc $description) | ||
114 | #getBlogProperty($blogDoc 'description' '' $result) | ||
115 | #set ($description = $NULL) | ||
116 | #setVariable ("$description" $result) | ||
117 | #end | ||
118 | ## | ||
119 | ## | ||
120 | ## | ||
121 | #** | ||
122 | * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog | ||
123 | * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on | ||
124 | * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a | ||
125 | * month), or all. | ||
126 | * | ||
127 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. | ||
128 | * @param entries The resulting list of entries to display, a list of XDocument names. | ||
129 | *### | ||
130 | #macro(getBlogEntries $blogDoc $entries) | ||
131 | #if (!$entries) | ||
132 | #setVariable ("$entries" []) | ||
133 | #end | ||
134 | #getBlogEntriesBaseQuery($query) | ||
135 | #isBlogGlobal($blogDoc $isGlobal) | ||
136 | #if(!$isGlobal) | ||
137 | #set($query = "${query} and (doc.space = '${blogDoc.space}' or doc.parent = '${blogDoc.fullName}')") | ||
138 | #end | ||
139 | #getBlogDisplayType($blogDoc $displayType) | ||
140 | #if($displayType == 'weekly') | ||
141 | #getWeeklyBlogEntries($blogDoc $query $entries) | ||
142 | #elseif($displayType == 'monthly') | ||
143 | #getMonthlyBlogEntries($blogDoc $query $entries) | ||
144 | #elseif($displayType == 'all') | ||
145 | #getAllBlogEntries($blogDoc $query $entries) | ||
146 | #else | ||
147 | #getPagedBlogEntries($blogDoc $query $entries) | ||
148 | #end | ||
149 | #end | ||
150 | ## | ||
151 | ## | ||
152 | ## | ||
153 | #** | ||
154 | * Retrieves a list of entries to be displayed. The entries are taken from a "page" of the blog, a sequence of documents | ||
155 | * defined by the request parameters <tt>ipp</tt> (items per page) and <tt>page</tt> (the current page). Initially the | ||
156 | * first page is displayed, with the number of entries defined in the blog object in the <tt>itemsPerPage</tt> property | ||
157 | * (10 if not defined). | ||
158 | * | ||
159 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. | ||
160 | * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be | ||
161 | * refined to restrict to a given space, or to a given search criteria, etc. | ||
162 | * @param entries The resulting list of entries to display, a list of XDocument names. | ||
163 | *### | ||
164 | #macro(getPagedBlogEntries $blogDoc $query $entries) | ||
165 | #if (!$entries) | ||
166 | #setVariable ("$entries" []) | ||
167 | #end | ||
168 | #set($totalEntries = $services.query.hql($query).count()) | ||
169 | #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage) | ||
170 | #set($defaultItemsPerPage = $mathtool.toInteger($defaultItemsPerPage)) | ||
171 | ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. | ||
172 | #preparePagedViewParams($totalEntries $defaultItemsPerPage) | ||
173 | #set($discard = $entries.addAll($services.query.hql("${query} order by publishDate.value desc").setLimit($itemsPerPage).setOffset($startAt).execute())) | ||
174 | #end | ||
175 | ## | ||
176 | ## | ||
177 | ## | ||
178 | #** | ||
179 | * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is | ||
180 | * defined by the request parameters <tt>week</tt> (the week number in the year, from 1 to 52) and <tt>year</tt> (4 | ||
181 | * digit year). Initially the current week is displayed. | ||
182 | * | ||
183 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. | ||
184 | * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be | ||
185 | * refined to restrict to a given space, or to a given search criteria, etc. | ||
186 | * @param entries The resulting list of entries to display, a list of XDocument names. | ||
187 | *### | ||
188 | #macro(getWeeklyBlogEntries $blogDoc $query $entries) | ||
189 | #if (!$entries) | ||
190 | #setVariable ("$entries" []) | ||
191 | #end | ||
192 | #getRequestedWeek($weekDate) | ||
193 | #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) | ||
194 | #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor())) | ||
195 | #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling())) | ||
196 | #set($query = "${query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'") | ||
197 | #set($totalEntries = $services.query.hql($query).count()) | ||
198 | #set($discard = $entries.addAll($services.query.hql("${query} order by publishDate.value desc").execute())) | ||
199 | #end | ||
200 | ## | ||
201 | ## | ||
202 | ## | ||
203 | #** | ||
204 | * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is | ||
205 | * defined by the request parameters <tt>month</tt> (the month number, from 1 to 12) and <tt>year</tt> (4 | ||
206 | * digit year). Initially the current month is displayed. | ||
207 | * | ||
208 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. | ||
209 | * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be | ||
210 | * refined to restrict to a given space, or to a given search criteria, etc. | ||
211 | * @param entries The resulting list of entries to display, a list of XDocument names. | ||
212 | *### | ||
213 | #macro(getMonthlyBlogEntries $blogDoc $query $entries) | ||
214 | #if (!$entries) | ||
215 | #setVariable ("$entries" []) | ||
216 | #end | ||
217 | #getRequestedMonth($monthDate) | ||
218 | #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd')) | ||
219 | #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor())) | ||
220 | #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling())) | ||
221 | #set($query = "${query} and publishDate.value >= '$minDay' and publishDate.value < '$maxDay'") | ||
222 | #set($totalEntries = $services.query.hql($query).count()) | ||
223 | #set($discard = $entries.addAll($services.query.hql("${query} order by publishDate.value desc").execute())) | ||
224 | #end | ||
225 | ## | ||
226 | ## | ||
227 | ## | ||
228 | #** | ||
229 | * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned. | ||
230 | * | ||
231 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. | ||
232 | * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be | ||
233 | * refined to restrict to a given space, or to a given search criteria, etc. | ||
234 | * @param entries The resulting list of entries to display, a list of XDocument names. | ||
235 | *### | ||
236 | #macro(getAllBlogEntries $blogDoc $query $entries) | ||
237 | #if (!$entries) | ||
238 | #setVariable ("$entries" []) | ||
239 | #end | ||
240 | #set($totalEntries = $services.query.hql($query).count()) | ||
241 | #set($discard = $entries.addAll($services.query.hql("${query} order by publishDate.value desc").execute())) | ||
242 | #end | ||
243 | ## | ||
244 | ## | ||
245 | ## | ||
246 | #** | ||
247 | * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned. | ||
248 | * | ||
249 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. | ||
250 | * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be | ||
251 | * refined to restrict to a given space, or to a given search criteria, etc. | ||
252 | * @param entries The resulting list of entries to display, a list of XDocument names. | ||
253 | *### | ||
254 | #macro(getUnpublishedBlogEntries $blogDoc $query $entries) | ||
255 | #if (!$entries) | ||
256 | #setVariable ("$entries" []) | ||
257 | #end | ||
258 | #set($query = "${query} and isPublished.value = 0") | ||
259 | #set($totalEntries = $services.query.hql($query).count()) | ||
260 | #set($discard = $entries.addAll($services.query.hql("${query} order by publishDate.value desc").execute())) | ||
261 | #end | ||
262 | ## | ||
263 | ## | ||
264 | ## | ||
265 | #** | ||
266 | * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog. | ||
267 | * | ||
268 | * @param entries The resulting list of entries to display, a list of XDocument names. | ||
269 | *### | ||
270 | #macro(getGlobalBlogEntries $entries) | ||
271 | #if (!$entries) | ||
272 | #setVariable ("$entries" []) | ||
273 | #end | ||
274 | #getBlogEntriesBaseQuery($query) | ||
275 | #set($totalEntries = $services.query.hql($query).count()) | ||
276 | #set($defaultItemsPerPage = 20) | ||
277 | ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt. | ||
278 | #preparePagedViewParams($totalEntries $defaultItemsPerPage) | ||
279 | #set($discard = $entries.addAll($services.query.hql("${query} order by publishDate.value desc").setLimit($itemsPerPage).setOffset($startAt).execute())) | ||
280 | #end | ||
281 | ## | ||
282 | ## | ||
283 | ## | ||
284 | #** | ||
285 | * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific | ||
286 | * blog, nor specify a range or an ordering criteria. | ||
287 | * | ||
288 | * @param query The basic query for selecting blog entries. | ||
289 | *### | ||
290 | #macro(getBlogEntriesBaseQuery $query) | ||
291 | #set ($query = $NULL) | ||
292 | #setVariable ("$query" ", BaseObject obj, IntegerProperty isPublished, IntegerProperty hidden, DateProperty publishDate | ||
293 | where doc.fullName <> '${blogPostTemplate}' and | ||
294 | obj.name = doc.fullName and obj.className = '${blogPostClassname}' and | ||
295 | publishDate.id.id = obj.id and publishDate.id.name = 'publishDate' and | ||
296 | isPublished.id.id = obj.id and isPublished.id.name = 'published' and | ||
297 | hidden.id.id = obj.id and hidden.id.name = 'hidden' and | ||
298 | (doc.creator = '$xcontext.user' or (isPublished.value = 1 and hidden.value = 0))") | ||
299 | #end | ||
300 | ## | ||
301 | ## | ||
302 | ## | ||
303 | #** | ||
304 | * Checks if the provided blog is global or in-space. | ||
305 | * | ||
306 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>blogType</tt> property set. | ||
307 | * @param isGlobal The resulting boolean. If the blog object does not define anything, it is considered in-space. | ||
308 | *### | ||
309 | #macro(isBlogGlobal $blogDoc $isGlobal) | ||
310 | #getBlogProperty($blogDoc 'blogType' '' $discard) | ||
311 | #set ($result = false) | ||
312 | #if($discard == 'global') | ||
313 | #set($result = true) | ||
314 | #end | ||
315 | #set ($isGlobal = $NULL) | ||
316 | #setVariable ("$isGlobal" $result) | ||
317 | #end | ||
318 | ## | ||
319 | ## | ||
320 | ## | ||
321 | #** | ||
322 | * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a | ||
323 | * week), monthly (all entries in a month), or all. | ||
324 | * | ||
325 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object with the <tt>displayType</tt> | ||
326 | * property set. | ||
327 | * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated. | ||
328 | *### | ||
329 | #macro(getBlogDisplayType $blogDoc $displayType) | ||
330 | #getBlogProperty($blogDoc 'displayType' 'paginated' $result) | ||
331 | #set ($displayType = $NULL) | ||
332 | #setVariable ("$displayType" $result) | ||
333 | #end | ||
334 | ## | ||
335 | ## | ||
336 | ## | ||
337 | #** | ||
338 | * Displays a list of entries. | ||
339 | * | ||
340 | * @param entries The entries to display, a list of XDocument names. | ||
341 | * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results, | ||
342 | * unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently | ||
343 | * used values: index, single, category, search, unpublished, hidden. | ||
344 | * @param onlyExtract If <tt>true</tt>, only display the extract of articles where available, otherwise display the full content. | ||
345 | * @param shouldDisplayTitles If <tt>true</tt>, display the blog title (blog posts shouldn't display the title when they're | ||
346 | * displayed alone on their page since it's the page title which is used in this case) | ||
347 | *### | ||
348 | #macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles) | ||
349 | #set($blogDay = '') | ||
350 | (% class="hfeed $!{displaying}" %)((( | ||
351 | (% class="blogDay" %)((( | ||
352 | #foreach ($entryDoc in $xwiki.wrapDocs($entries)) | ||
353 | #getEntryObject($entryDoc $entryObj) | ||
354 | ## Although all entries should have one of the two objects, better check to be sure. | ||
355 | #if("$!{entryObj}" != '') | ||
356 | #getEntryDate($entryDoc $entryObj $entryDate) | ||
357 | ## Display a "calendar sheet" for each day. All entries posted on the same day share one such sheet. | ||
358 | #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd')) | ||
359 | #if($blogDay != $entryDateStr) | ||
360 | #if($blogDay != '') | ||
361 | ))) | ||
362 | (% class="blogDay" %)((( | ||
363 | #end | ||
364 | #displayBlogDate($entryDate) | ||
365 | #set ($blogDay = $entryDateStr) | ||
366 | #end | ||
367 | ## Finally, display the entry. | ||
368 | #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles) | ||
369 | #end | ||
370 | #end | ||
371 | )))## blogDay | ||
372 | )))## hfeed | ||
373 | #end | ||
374 | ## | ||
375 | ## | ||
376 | ## | ||
377 | #** | ||
378 | * Get the entry object, either a new BlogPost or an old Article. | ||
379 | * | ||
380 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
381 | * @param entryObj The resulting xobject of the blog post. | ||
382 | *### | ||
383 | #macro(getEntryObject $entryDoc $__entryObj) | ||
384 | #set($result = $entryDoc.getObject("${blogPostClassname}")) | ||
385 | #if(!$result) | ||
386 | #set($result = $entryDoc.getObject("${oldArticleClassname}")) | ||
387 | #end | ||
388 | ## NOTE: The reason we put an underscore in front of the variable name is to prevent the following line from | ||
389 | ## overwriting the $entryObj variable that may be defined before this macro is called. Of course, $__entryObj may be | ||
390 | ## overwritten in this case but it's less likely to have such a variable defined before. | ||
391 | #set ($__entryObj = $NULL) | ||
392 | #setVariable ("$__entryObj" $result) | ||
393 | #end | ||
394 | ## | ||
395 | ## | ||
396 | ## | ||
397 | #** | ||
398 | * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is | ||
399 | * the document creation date, but can be edited by the user. | ||
400 | * | ||
401 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
402 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
403 | * @param result The resulting date, an instance of <tt>java.util.Date</tt>. | ||
404 | *### | ||
405 | #macro(getEntryDate $entryDoc $entryObj $result) | ||
406 | #set ($result = $NULL) | ||
407 | #setVariable ("$result" $entryObj.getProperty('publishDate').value) | ||
408 | #end | ||
409 | ## | ||
410 | ## | ||
411 | ## | ||
412 | #** | ||
413 | * Displays a date, nicely formatted as a calendar page. | ||
414 | * | ||
415 | * @param date The date to display, an instance of <tt>java.util.Date</tt>. | ||
416 | *### | ||
417 | #macro(displayBlogDate $date) | ||
418 | #set($year = $xwiki.formatDate($date, 'yyyy')) | ||
419 | ## 3 letter month name, like Jan, Dec. | ||
420 | #set($month = $xwiki.formatDate($date, 'MMM')) | ||
421 | ## Uncomment to get a full length month name, like January, December. | ||
422 | ## TODO: this could be defined somewhere in the blog style. | ||
423 | ## #set($month = $xwiki.formatDate($date, 'MMMM')) | ||
424 | #set($day = $xwiki.formatDate($date, 'dd')) | ||
425 | (% class="blogdate" %) | ||
426 | == (% class="month" %)$month(%%) (% class="day" %)$day(%%) (% class="year" %)$year(%%) == | ||
427 | #end | ||
428 | ## | ||
429 | ## | ||
430 | ## | ||
431 | #** | ||
432 | * Displays a blog article: management tools, header, content, footer. | ||
433 | * | ||
434 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
435 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
436 | * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. | ||
437 | * @param shouldDisplayTitle If <tt>true</tt>, display the blog title (blog posts shouldn't display the title | ||
438 | * when they're displayed alone on their page since it's the page title which is used in this case) | ||
439 | *### | ||
440 | #macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle) | ||
441 | ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden | ||
442 | #isPublished($entryObj $isPublished) | ||
443 | #isHidden($entryObj $isHidden) | ||
444 | #if($doc.fullName == $entryDoc.fullName) | ||
445 | (% class="hentry single-article" %)((( | ||
446 | #else | ||
447 | (% class="hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end" %)((( | ||
448 | #end | ||
449 | #displayEntryTools($entryDoc $entryObj) | ||
450 | #if($shouldDisplayTitle) | ||
451 | #displayEntryTitle($entryDoc $entryObj) | ||
452 | #end | ||
453 | #if($doc.fullName == $entryDoc.fullName) | ||
454 | #if(!$isPublished) | ||
455 | {{warning}}{{translation key='xe.blog.code.published'/}}{{/warning}} | ||
456 | #elseif($isHidden) | ||
457 | {{warning}}{{translation key='xe.blog.code.hidden'/}}{{/warning}} | ||
458 | #end | ||
459 | #end | ||
460 | #displayEntryContent($entryDoc $entryObj $onlyExtract) | ||
461 | #displayEntryFooter($entryDoc $entryObj) | ||
462 | )))## hentry | ||
463 | #end | ||
464 | ## | ||
465 | ## | ||
466 | ## | ||
467 | #** | ||
468 | * Checks if the provided blog is published or not. | ||
469 | * | ||
470 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
471 | * @param isPublished The resulting boolean, true if the entry is considered published. | ||
472 | *### | ||
473 | #macro(isPublished $entryObj $isPublished) | ||
474 | #set ($isPublished = $NULL) | ||
475 | ## This should work for both old articles, which don't have the 'published' property at all, and | ||
476 | ## are considered published by default, and new entries, that should have 1 if published. | ||
477 | #if ("$!{entryObj.getProperty('published').value}" != '0') | ||
478 | #setVariable ("$isPublished" true) | ||
479 | #else | ||
480 | #setVariable ("$isPublished" false) | ||
481 | #end | ||
482 | #end | ||
483 | ## | ||
484 | ## | ||
485 | ## | ||
486 | #** | ||
487 | * Checks if the provided blog is hidden or not. | ||
488 | * | ||
489 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass<tt> xclass. | ||
490 | * @param isHiddel The resulting boolean, true if the entry is considered hidden. | ||
491 | *### | ||
492 | #macro(isHidden $entryObj $isHidden) | ||
493 | #set ($isHidden = $NULL) | ||
494 | ## This should work for both old articles, which don't have the 'hidden' property at all, and | ||
495 | ## are considered visible by default, and new entries, that should have 1 if hidden. | ||
496 | #if ("$!{entryObj.getProperty('hidden').value}" == '1') | ||
497 | #setVariable ("$isHidden" true) | ||
498 | #else | ||
499 | #setVariable ("$isHidden" false) | ||
500 | #end | ||
501 | #end | ||
502 | ## | ||
503 | ## | ||
504 | ## | ||
505 | #** | ||
506 | * Displays several "tools" for manipulating blog posts: hide/show, publish, edit. | ||
507 | * | ||
508 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
509 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
510 | *### | ||
511 | #macro(displayEntryTools $entryDoc $entryObj) | ||
512 | #if($xcontext.action == 'view') | ||
513 | (% class="blog-entry-toolbox" %)((( | ||
514 | #displayPublishButton($entryDoc $entryObj) | ||
515 | #displayHideShowButton($entryDoc $entryObj) | ||
516 | #displayEditButton($entryDoc $entryObj) | ||
517 | #displayDeleteButton($entryDoc $entryObj) | ||
518 | ))) | ||
519 | #end | ||
520 | #end | ||
521 | ## | ||
522 | ## | ||
523 | ## | ||
524 | #** | ||
525 | * Displays the publish button to the entry <strong>creator</strong>, if the article is not published yet. | ||
526 | * | ||
527 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
528 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
529 | * @todo AJAX calls. | ||
530 | *### | ||
531 | #macro(displayPublishButton $entryDoc $entryObj) | ||
532 | #isPublished($entryObj $isPublished) | ||
533 | #if(!$isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) | ||
534 | [[{{html clean="false"}}#toolImage('page_white_world' 'publish '){{/html}}>>path:$blogPublisher.getURL('view', "entryName=${escapetool.url($entryDoc.fullName)}&xredirect=${escapetool.url($thisURL)}&form_token=$!{services.csrf.getToken()}")||title="$services.localization.render('xe.blog.code.notpublished')"]]## | ||
535 | #end | ||
536 | #end | ||
537 | ## | ||
538 | ## | ||
539 | ## | ||
540 | #** | ||
541 | * Displays the hide or show button to the entry <strong>creator</strong>, if the article is already published. | ||
542 | * | ||
543 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
544 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
545 | *### | ||
546 | #macro(displayHideShowButton $entryDoc $entryObj) | ||
547 | #isPublished($entryObj $isPublished) | ||
548 | #isHidden($entryObj $isHidden) | ||
549 | ## Only published articles can be hidden. Unpublished articles are considered already hidden. | ||
550 | #if($isPublished && $entryDoc.creator == $xcontext.user && $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) | ||
551 | #if ($isHidden) | ||
552 | [[{{html clean="false"}}#toolImage('lock_open', 'show '){{/html}}>>path:$entryDoc.getURL('save', "${entryObj.getxWikiClass().getName()}_${entryObj.number}_hidden=0&comment=${escapetool.url($services.localization.render('xe.blog.code.madevisible'))}&xredirect=${escapetool.url($thisURL)}&form_token=$!{services.csrf.getToken()}")||class="blog-tool-show" title="$services.localization.render('xe.blog.code.makevisible')"]]## | ||
553 | #else | ||
554 | [[{{html clean="false"}}#toolImage('lock', 'hide '){{/html}}>>path:$entryDoc.getURL('save', "${entryObj.getxWikiClass().getName()}_${entryObj.number}_hidden=1&comment=${escapetool.url($services.localization.render('xe.blog.code.hid'))}&xredirect=${escapetool.url($thisURL)}&form_token=$!{services.csrf.getToken()}")||class="blog-tool-hide" title="$services.localization.render('xe.blog.code.hide')"]]## | ||
555 | #end | ||
556 | #end | ||
557 | #end | ||
558 | ## | ||
559 | ## | ||
560 | ## | ||
561 | #** | ||
562 | * Displays the edit button to those that can edit the article. | ||
563 | * | ||
564 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
565 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
566 | *### | ||
567 | #macro(displayEditButton $entryDoc $entryObj) | ||
568 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName)) | ||
569 | ## Call getDefaultEditMode() for backward compatibility with older blog posts. | ||
570 | [[{{html clean="false"}}#toolImage('pencil' 'edit '){{/html}}>>path:$entryDoc.getURL('edit')||title="$services.localization.render('xe.blog.code.editpost')"]]## | ||
571 | #end | ||
572 | #end | ||
573 | ## | ||
574 | ## | ||
575 | ## | ||
576 | #** | ||
577 | * Displays the delete button to those that can edit the article. | ||
578 | * | ||
579 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
580 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
581 | * @todo AJAX calls. | ||
582 | *### | ||
583 | #macro(displayDeleteButton $entryDoc $entryObj) | ||
584 | #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName)) | ||
585 | [[{{html clean="false"}}#toolImage('cross' 'delete '){{/html}}>>path:$entryDoc.getURL('delete')||title="$services.localization.render('xe.blog.code.deletepost')"]]## | ||
586 | #end | ||
587 | #end | ||
588 | ## | ||
589 | ## | ||
590 | ## | ||
591 | #** | ||
592 | * Displays the title of the entry. | ||
593 | * | ||
594 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
595 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
596 | *### | ||
597 | #macro(displayEntryTitle $entryDoc $entryObj) | ||
598 | #if($doc.fullName == $entryDoc.fullName) | ||
599 | (% class="entry-title" %) | ||
600 | = $entryDoc.display('title', 'view', $entryObj) = | ||
601 | #else | ||
602 | (% class="entry-title" %) | ||
603 | === [[$entryDoc.display('title', 'view', $entryObj)>>doc:$entryDoc]] === | ||
604 | #end | ||
605 | #end | ||
606 | ## | ||
607 | ## | ||
608 | ## | ||
609 | #** | ||
610 | * Displays the body of the entry. | ||
611 | * | ||
612 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
613 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
614 | * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. | ||
615 | *### | ||
616 | #macro(displayEntryContent $entryDoc $entryObj $onlyExtract) | ||
617 | (% class="#if($onlyExtract)entry-summary#{else}entry-content#end" %)((( | ||
618 | #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent) | ||
619 | $xcontext.dropPermissions() | ||
620 | ## FIXME: This is fragile to malformed blogpost contents that have a closed content macro, without previously opening it, i.e. "{{/content}}" | ||
621 | ## However, we considered this acceptable for now, as opposed to the doc.getRenderedContent() alternative that spits out HTML. | ||
622 | {{content syntax="$entryDoc.syntax.toIdString()"}}$entryContent{{/content}} | ||
623 | ))) ## entry-content | ||
624 | (% class="clearfloats" %)((())) | ||
625 | #end | ||
626 | ## | ||
627 | ## | ||
628 | ## | ||
629 | #** | ||
630 | * Extracts the body of the entry that should be displayed. If <tt>onlyExtract</tt> is <tt>true</tt>, display the content | ||
631 | * of the <tt>extract</tt> field (if not empty). | ||
632 | * | ||
633 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
634 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
635 | * @param onlyExtract If <tt>true</tt>, try to display only a summary of the entry, instead of the full content. | ||
636 | * @param entryContent The resulting content. | ||
637 | *### | ||
638 | #macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent) | ||
639 | #if ($onlyExtract) | ||
640 | #set ($result = $entryObj.getProperty('extract').value) | ||
641 | #end | ||
642 | #if("$!result" == '') | ||
643 | #set($result = $entryObj.getProperty('content').value) | ||
644 | #* Disabled until the content can be cleanly cut. | ||
645 | * #if($onlyExtract && $result.length()>$maxchars) | ||
646 | * #set($i = $result.lastIndexOf(" ", $maxchars)) | ||
647 | * #set($i = $i + 1) | ||
648 | * #set($result = "${result.substring(0,$i)} *[...>${entryDoc.fullName}]*") | ||
649 | * #end | ||
650 | ## *### | ||
651 | #else | ||
652 | #if($entryDoc.syntax.toIdString() == 'xwiki/1.0') | ||
653 | #set($result = "${result} <a href='${entryDoc.getURL()}' title='$services.localization.render('xe.blog.code.readpost')'>...</a>") | ||
654 | #else | ||
655 | #set($result = "${result} [[...>>${entryDoc}||title='$services.localization.render('xe.blog.code.readpost')']]") | ||
656 | #end | ||
657 | #end | ||
658 | #set ($entryContent = $NULL) | ||
659 | #setVariable ("$entryContent" $result) | ||
660 | #end | ||
661 | ## | ||
662 | ## | ||
663 | ## | ||
664 | #** | ||
665 | * Displays the footer of the entry. | ||
666 | * | ||
667 | * @param entryDoc The xdocument of the blog post. Each post resides in its own document. | ||
668 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
669 | *### | ||
670 | #macro(displayEntryFooter $entryDoc $entryObj) | ||
671 | (% class="entry-footer" %)((( | ||
672 | #isPublished($entryObj $isPublished) | ||
673 | (% class='entry-author-label' %) | ||
674 | #if($isPublished) | ||
675 | {{translation key='xe.blog.code.postedby'/}} ## | ||
676 | #else | ||
677 | {{translation key='xe.blog.code.createdby'/}} ## | ||
678 | #end | ||
679 | {{html wiki="false" clean="false"}}<address class='author vcard'>#userfn($entryDoc.creator)</address>{{/html}} ## | ||
680 | #getEntryDate($entryDoc $entryObj $entryDate) | ||
681 | #listCategories($entryObj) #* | ||
682 | ## Since the publish date and update date are not set at the exact same time, there could be a small difference that | ||
683 | ## we assume cannot be more than 3 seconds. | ||
684 | *#(% class="separator" %)·(%%) [[{{translation key='xe.blog.code.permalink'/}}>>$entryDoc||rel="bookmark"]] ## | ||
685 | (% class="separator" %)·(%%) [[{{translation key='xe.blog.code.comments'/}}>>$entryDoc||anchor="Comments"]] (% class="itemCount" %)($entryDoc.comments.size())(%%) ## | ||
686 | )))## entry-footer | ||
687 | #end | ||
688 | ## | ||
689 | ## | ||
690 | ## | ||
691 | #** | ||
692 | * List the categories an entry belongs to. Used in the footer. The categories are instances of <tt>Blog.CategoryClass</tt>. | ||
693 | * | ||
694 | * @param entryObj The xobject of the blog post, an instance of the <tt>Blog.BlogPostClass</tt> xclass. | ||
695 | *### | ||
696 | #macro(listCategories $entryObj) | ||
697 | #if($entryObj.getxWikiClass().getName() == $blogPostClassname) | ||
698 | #set($categories = $entryObj.getProperty('category').value) | ||
699 | #set($first = true) | ||
700 | #if($categories.size() > 0) | ||
701 | #foreach($category in $categories) | ||
702 | #set($categoryDoc = $!xwiki.getDocument($category)) | ||
703 | #if(!$categoryDoc.isNew() && $categoryDoc.getObject(${blogCategoryClassname})) | ||
704 | #if($foreach.count == 1) | ||
705 | (% class='separator' %)·(%%) $services.localization.render('xe.blog.code.categories') ## | ||
706 | #else | ||
707 | , ## | ||
708 | #end## | ||
709 | [[$!{escapetool.xml($!categoryDoc.getObject($blogCategoryClassname).getValue('name'))}>>${category}||rel='tag']]## | ||
710 | #end## | ||
711 | #end## | ||
712 | #end | ||
713 | #end | ||
714 | #end | ||
715 | ## | ||
716 | ## | ||
717 | ## | ||
718 | #** | ||
719 | * Displays blog pagination links (older and newer entries). | ||
720 | * | ||
721 | * @param blogDoc the XDocument holding the blog definition object. | ||
722 | *### | ||
723 | #macro(displayNavigationLinks $blogDoc) | ||
724 | (% class="clearfloats" %)((())) | ||
725 | #getBlogDisplayType($blogDoc $displayType) | ||
726 | #if($displayType == 'weekly') | ||
727 | (% class="pagingLinks" %)((( | ||
728 | #getRequestedWeek($weekDate) | ||
729 | $weekDate.addWeeks(-1)## | ||
730 | (% class="prevPage" %)**[[« {{translation key='xe.blog.code.previousweek'/}}>>$doc.name||queryString="year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear"]]**(%%) | ||
731 | #sep() | ||
732 | $weekDate.addWeeks(2)## 2 because we already subtracted 1 above | ||
733 | (% class="nextPage" %)**[[{{translation key='xe.blog.code.nextweek'/}} »>>$doc.name||queryString="year=$weekDate.weekyear&week=$weekDate.weekOfWeekyear"]]**(%%) | ||
734 | ))) | ||
735 | #elseif($displayType == 'monthly') | ||
736 | (% class="pagingLinks" %)((( | ||
737 | #getRequestedMonth($monthDate) | ||
738 | $monthDate.addMonths(-1)## | ||
739 | (% class="prevPage" %)**[[« {{translation key='xe.blog.code.previousmonth'/}}>>$doc.name||queryString="year=$monthDate.year&month=$monthDate.monthOfYear"]]**(%%) | ||
740 | #sep() | ||
741 | $monthDate.addMonths(2)## 2 because we already subtracted 1 above | ||
742 | (% class="nextPage" %)**[[{{translation key='xe.blog.code.nextmonth'/}} »>>$doc.name||queryString="year=$monthDate.year&month=$monthDate.monthOfYear"]]**(%%) | ||
743 | ))) | ||
744 | #elseif($displayType == 'all') | ||
745 | #else | ||
746 | ## Paginated | ||
747 | #if(($totalPages > 1)) | ||
748 | #set($queryString = '') | ||
749 | #foreach($p in $request.getParameterNames()) | ||
750 | #if($p != 'page' && $p != 'ipp') | ||
751 | #foreach($v in $request.getParameterValues($p)) | ||
752 | #set($queryString = "${queryString}&${p}=${v}") | ||
753 | #end | ||
754 | #end | ||
755 | #end | ||
756 | (% class="pagingLinks" %)((( | ||
757 | #if ($currentPageNumber < $totalPages) | ||
758 | #set($currentPageNumber = $currentPageNumber + 1) | ||
759 | (% class="prevPage" %)**[[« {{translation key='xe.blog.code.olderposts'/}}>>$doc.name||queryString="page=${currentPageNumber}&ipp=${itemsPerPage}$queryString"]]**(%%) | ||
760 | #set($currentPageNumber = $currentPageNumber - 1) | ||
761 | #end | ||
762 | #if ($currentPageNumber > 1) | ||
763 | #if ($currentPageNumber < $totalPages) | ||
764 | #sep() | ||
765 | #end | ||
766 | #set($currentPageNumber = $currentPageNumber - 1) | ||
767 | (% class="nextPage" %)**[[{{translation key='xe.blog.code.newerposts'/}} »>>$doc.name||queryString="page=${currentPageNumber}&ipp=${itemsPerPage}$queryString"]]**(%%) | ||
768 | #set($currentPageNumber = $currentPageNumber + 1) | ||
769 | #end | ||
770 | (% class="clear" %)(%%) | ||
771 | )))## pagingLinks | ||
772 | #end | ||
773 | #end | ||
774 | #end | ||
775 | ## | ||
776 | ## | ||
777 | ## | ||
778 | #** | ||
779 | * Displays a message box with "publish" icon. | ||
780 | * | ||
781 | * @param message A text message concerning blog article publishing | ||
782 | *### | ||
783 | #macro(publishMessageBox $message) | ||
784 | (% class="plainmessage publish-message" %)((($message))) | ||
785 | #end | ||
786 | #** | ||
787 | * Displays a message box with "show/hide" icon. | ||
788 | * | ||
789 | * @param message A text message concerning blog article hiding | ||
790 | *### | ||
791 | #macro(hideMessageBox $message) | ||
792 | (% class="plainmessage hide-message" %)((($message))) | ||
793 | #end | ||
794 | ## | ||
795 | ## | ||
796 | ## | ||
797 | #** | ||
798 | * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are | ||
799 | * <tt>year</tt> and <tt>week</tt>. By default, the current week is used. | ||
800 | * | ||
801 | * @param monthDate The resulting week, a JODATime MutableDateTime. | ||
802 | *### | ||
803 | #macro(getRequestedWeek $weekDate) | ||
804 | #set ($weekDate = $NULL) | ||
805 | #setVariable ("$weekDate" $xwiki.jodatime.mutableDateTime) | ||
806 | #if("$!{request.year}" != '') | ||
807 | $weekDate.setYear($mathtool.toInteger($request.year)) | ||
808 | #end | ||
809 | #if("$!{request.week}" != '') | ||
810 | $weekDate.setWeekOfWeekyear($mathtool.toInteger($request.week)) | ||
811 | #end | ||
812 | #end | ||
813 | ## | ||
814 | ## | ||
815 | ## | ||
816 | #** | ||
817 | * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are | ||
818 | * <tt>year</tt> and <tt>month</tt>. By default, the current month is used. | ||
819 | * | ||
820 | * @param monthDate The resulting month, a JODATime MutableDateTime. | ||
821 | *### | ||
822 | #macro(getRequestedMonth $monthDate) | ||
823 | #set ($monthDate = $NULL) | ||
824 | #setVariable ("$monthDate" $xwiki.jodatime.mutableDateTime) | ||
825 | #if("$!{request.year}" != '') | ||
826 | $monthDate.setYear($mathtool.toInteger($request.year)) | ||
827 | #end | ||
828 | #if("$!{request.month}" != '') | ||
829 | $monthDate.setMonthOfYear($mathtool.toInteger($request.month)) | ||
830 | #end | ||
831 | #end | ||
832 | ## | ||
833 | ## | ||
834 | ## | ||
835 | #** | ||
836 | * Retrieve a blog property (title, display type, etc). | ||
837 | * | ||
838 | * @param blogDoc The blog document. It should contain a <tt>Blog.BlogClass</tt> object. | ||
839 | * @param propertyName The name of the property to be retrieved. One of the <tt>Blog.BlogClass</tt>'s properties. | ||
840 | * @param defaultValue The default value to use in case the blog object does not define one. | ||
841 | * @param propertyValue The resulting value. | ||
842 | *### | ||
843 | #macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue) | ||
844 | #set($result = "$!{blogDoc.getObject(${blogClassname}).getProperty($propertyName).value}") | ||
845 | #if($result == '') | ||
846 | #set($result = $defaultValue) | ||
847 | #end | ||
848 | #set ($propertyValue = $NULL) | ||
849 | #setVariable ("$propertyValue" $result) | ||
850 | #end | ||
851 | |||
852 | #** | ||
853 | * If an error occurs when executing an action, set a specific response status and display an error message. | ||
854 | * | ||
855 | * @param status The response status. | ||
856 | * @param text The user readable error to be displayed. Can be a translation key. | ||
857 | * @param parameters The parameters to use when decoding the translation key. | ||
858 | *### | ||
859 | #macro(blog__actionResponseError $status $text $parameters) | ||
860 | $response.setStatus($status) | ||
861 | #if($request.ajax) | ||
862 | $services.localization.render($text, $!parameters) | ||
863 | #else | ||
864 | {{error}}$services.localization.render($text, $!parameters){{/error}} | ||
865 | #end | ||
866 | #end | ||
867 | {{/velocity}} |