Wiki source code of Macros for the Blog Categories
Last modified by Jan Rhebergen on 2022/03/12 10:00
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | {{include reference="Blog.BlogCode"/}} | ||
2 | |||
3 | {{velocity output="false"}} | ||
4 | ## | ||
5 | ## | ||
6 | ## | ||
7 | #** | ||
8 | * Retrieves the list of blog entries from a given category. Entries belonging to subcategories | ||
9 | * are not returned. | ||
10 | * | ||
11 | * @param category The name of the category (XDocument full name, for example 'MyBlog.Fishing'). | ||
12 | * @param entries Return parameter, where the list of entries is placed. | ||
13 | * @param totalEntries Return parameter, where the total number of entries belonging to this category is | ||
14 | * placed. Useful for a paginated view. | ||
15 | *### | ||
16 | #macro(getEntriesForCategory $category $entries $totalEntries) | ||
17 | #set ($entries = $NULL) | ||
18 | #set ($totalEntries = $NULL) | ||
19 | #if ("$!{blogCategoryEntriesCache.containsKey($!{category})}" == 'true') | ||
20 | #setVariable ("$entries" $blogCategoryEntriesCache.get($!{category}).get(0)) | ||
21 | #setVariable ("$totalEntries" $blogCategoryEntriesCache.get($!{category}).get(1)) | ||
22 | #preparePagedViewParams ($totalEntries 10) | ||
23 | #else | ||
24 | #getCategoriesHierarchy ('' $tree) | ||
25 | #set ($subcategories = []) | ||
26 | #getSubcategories ($tree $category $subcategories) | ||
27 | #set ($categories = []) | ||
28 | ## check if it a categories space | ||
29 | #set ($categoryDoc = $xwiki.getDocument($category)) | ||
30 | #if ("$!categoryDoc.getObject($blogCategoryClassname)" != '') | ||
31 | #set ($discard = $categories.add($category)) | ||
32 | #end | ||
33 | #set ($discard = $categories.addAll(${subcategories})) | ||
34 | #getAllBlogPostsQuery($query) | ||
35 | #set ($query = ", DBStringListProperty as categories join categories.list as category${query} and obj.id = categories.id.id and categories.id.name='category' and category in (:categories)") | ||
36 | #if ($categories.size() > 0) | ||
37 | #set ($totalResult = $services.query.hql($query).bindValue('categories', $categories).addFilter("unique").count()) | ||
38 | #preparePagedViewParams ($totalResult 10) | ||
39 | #set ($result = $services.query.hql("${query} order by publishDate.value desc").setLimit($itemsPerPage).setOffset($startAt).bindValue('categories', $categories).addFilter("unique").execute()) | ||
40 | #else | ||
41 | #set ($totalResult = 0) | ||
42 | #set ($result = []) | ||
43 | #end | ||
44 | #if ("$!{blogCategoryEntriesCache.containsKey($!{category})}" == '') | ||
45 | #set ($blogCategoryEntriesCache = {}) | ||
46 | #end | ||
47 | #set ($discard = $blogCategoryEntriesCache.put("$!{category}", [$result, $totalResult])) | ||
48 | #setVariable ("$entries" $result) | ||
49 | #setVariable ("$totalEntries" $totalResult) | ||
50 | #end | ||
51 | #end | ||
52 | #macro(getSubcategories $tree $category $subcategories) | ||
53 | #foreach($subcategory in $tree.get($category)) | ||
54 | #set($discard = $subcategories.add($subcategory)) | ||
55 | #getSubcategories($tree $subcategory $subcategories) | ||
56 | #end | ||
57 | #end | ||
58 | ## | ||
59 | ## | ||
60 | ## | ||
61 | #** | ||
62 | * Builds a tree of categories, respecting the parent<->subcategory relation. Each node holds the | ||
63 | * full name of the category's document. The root of the tree is 'Blog.Categories' or 'aCategorySpace.WebHome'. | ||
64 | * | ||
65 | * @param space The space where to search for categories. If this parameter is an emptry string or | ||
66 | * null, all the categories in the wiki are returned. | ||
67 | * @param tree Return parameter, HashMap<String, List<String>> structure holding the categories | ||
68 | * hierarchy, where the key is the name of a category, and the value contains the names of | ||
69 | * all its subcategories. To obtain the full hierarchy, start with the key 'Blog.Categories'. | ||
70 | *### | ||
71 | #macro(getCategoriesHierarchy $space $tree) | ||
72 | #set ($tree = $NULL) | ||
73 | #if ("$!{blogCategoriesHierarchyCache.containsKey($!{space})}" == 'true') | ||
74 | #setVariable ("$tree" $blogCategoriesHierarchyCache.get($!{space})) | ||
75 | #else | ||
76 | #set ($result = {}) | ||
77 | #set($query = ', BaseObject obj where ') | ||
78 | #if("$!space" != '') | ||
79 | #set($query = "${query}doc.space = :space and ") | ||
80 | #end | ||
81 | #set($query = "${query}obj.name = doc.fullName and obj.className = '${blogCategoryClassname}' order by doc.name") | ||
82 | #set($queryObj = $services.query.hql($query)) | ||
83 | #if("$!space" != '') | ||
84 | #set($queryObj = $queryObj.bindValue('space', $space)) | ||
85 | #end | ||
86 | #foreach($category in $queryObj.execute()) | ||
87 | #set($categoryDoc = $xwiki.getDocument($category)) | ||
88 | #set($categoryParent = "$!categoryDoc.parent") | ||
89 | #if($categoryParent == '') | ||
90 | #set($categoryParent = $defaultCategoryParent) | ||
91 | #end | ||
92 | #if(!$result.containsKey($categoryParent)) | ||
93 | #set($discard = $result.put($categoryParent, [])) | ||
94 | #end | ||
95 | #set($discard = $result.get($categoryParent).add($category)) | ||
96 | #end | ||
97 | #if ("$!{blogCategoriesHierarchyCache.containsKey($!{space})}" == '') | ||
98 | #set ($blogCategoriesHierarchyCache = {}) | ||
99 | #end | ||
100 | #set ($discard = $blogCategoriesHierarchyCache.put("$!{space}", $result)) | ||
101 | #setVariable ("$tree" $result) | ||
102 | #end | ||
103 | #end | ||
104 | ## | ||
105 | ## | ||
106 | ## | ||
107 | #** | ||
108 | * Displays the category hierarchy held in the <tt>tree</tt> parameter. | ||
109 | * | ||
110 | * @param tree The category hierarchy, a HashMap<String, List<String>> structure, where the key | ||
111 | * is the name of a category, and the value contains the names of all its subcategories. | ||
112 | * @param displayMethod Selects how to display the category tree. Possible values are: | ||
113 | * <ul> | ||
114 | * <li><em>"simple"</em>: tree with links to the category pages.</li> | ||
115 | * <li><em>"selectable"</em>: each category name in the tree is preceded by a checkbox.</li> | ||
116 | * <li><em>"option"</em>: wraps each category name in an <option> element, to be used | ||
117 | * in a select box.</li> | ||
118 | * <li><em>"editable"</em>: displays links to delete and edit each category, if the rights | ||
119 | * allow such actions.</li> | ||
120 | * </ul> | ||
121 | * For any other value, the default ("simple") is considered. | ||
122 | *### | ||
123 | #macro(displayCategoriesHierarchy $tree $displayMethod) | ||
124 | #set($processedCategories = []) | ||
125 | #displayCategoriesHierarchyRecursive($tree $defaultCategoryParent 1 $displayMethod) | ||
126 | #end | ||
127 | ## | ||
128 | ## | ||
129 | ## | ||
130 | #** | ||
131 | * Displays recursively the category hierarchy held in the <tt>tree</tt> parameter, starting at | ||
132 | * the node indicated by the <tt>root</tt> parameter, which is on the <tt>level</tt>th level in | ||
133 | * the tree. | ||
134 | * | ||
135 | * @param tree The category hierarchy HashMap<String, List<String>> structure, where the key | ||
136 | * is the name of a category, and the value contains the names of all its subcategories. | ||
137 | * @param root The full name of the document containing the category that is to be considered the | ||
138 | * root of the displayed subtree. | ||
139 | * @param level The current depth of the tree, used for proper indentation. | ||
140 | * @param displayMethod Selects how to display the category tree. Possible values are: | ||
141 | * <ul> | ||
142 | * <li><em>"simple"</em>: tree with links to the category pages.</li> | ||
143 | * <li><em>"selectable"</em>: each category name in the tree is preceded by a checkbox.</li> | ||
144 | * <li><em>"option"</em>: wraps each category name in an <option> element, to be used | ||
145 | * in a select box.</li> | ||
146 | * <li><em>"editable"</em>: displays links to delete and edit each category, if the rights | ||
147 | * allow such actions.</li> | ||
148 | * </ul> | ||
149 | * For any other value, the default ("simple") is considered. | ||
150 | *### | ||
151 | #macro(displayCategoriesHierarchyRecursive $tree $root $level $displayMethod) | ||
152 | #if(!$processedCategories) | ||
153 | #set($processedCategories = []) | ||
154 | #end | ||
155 | #foreach($item in $tree.get($root)) | ||
156 | #if(!$processedCategories.contains($item)) | ||
157 | #set($discard = $processedCategories.add($item)) | ||
158 | #displayCategory($item $level $displayMethod) | ||
159 | #displayCategoriesHierarchyRecursive($tree $item $mathtool.add($level, 1) $displayMethod) | ||
160 | #end | ||
161 | #end | ||
162 | #if($displayMethod == "selectable") | ||
163 | #set ($entryObjNumber = 0) | ||
164 | #if("$!entryObj.number" != '') | ||
165 | #set ($entryObjNumber = $entryObj.number) | ||
166 | #end | ||
167 | <input type="hidden" name="${blogPostClassname}_$!{entryObjNumber}_category" value="" /> | ||
168 | #end | ||
169 | #end | ||
170 | ## | ||
171 | ## | ||
172 | ## | ||
173 | #** | ||
174 | * Displays a category as part of a category hierarchy. | ||
175 | * | ||
176 | * @param name The full name of the document containing the category to be displayed. | ||
177 | * @param level The depth where this category is in the tree, used for proper indentation. | ||
178 | * @param displayMethod Selects how to display the category tree. Possible values are: | ||
179 | * <ul> | ||
180 | * <li><em>"simple"</em>: tree with links to the category pages.</li> | ||
181 | * <li><em>"selectable"</em>: each category name in the tree is preceded by a checkbox.</li> | ||
182 | * <li><em>"option"</em>: wraps each category name in an <option> element, to be used | ||
183 | * in a select box.</li> | ||
184 | * <li><em>"editable"</em>: displays links to delete and edit each category, if the rights | ||
185 | * allow such actions.</li> | ||
186 | * </ul> | ||
187 | * For any other value, the default ("simple") is considered. | ||
188 | *### | ||
189 | #macro(displayCategory $name $level $displayMethod) | ||
190 | #if("$!displayMethod" == "option") | ||
191 | #displayOptionCategory($name $level) | ||
192 | #elseif("$!displayMethod" == "selectable") | ||
193 | #displaySelectableCategory($name $level) | ||
194 | #elseif("$!displayMethod" == "editable") | ||
195 | #displayEditableCategory($name $level) | ||
196 | #else | ||
197 | #displaySimpleCategory($name $level) | ||
198 | #end | ||
199 | #end | ||
200 | ## | ||
201 | ## | ||
202 | ## | ||
203 | #** | ||
204 | * Displays a category as part of a category hierarchy, preceded by a checkbox that allows choosing | ||
205 | * this category for a blog entry. | ||
206 | * | ||
207 | * @param name The full name of the document containing the category to be displayed. | ||
208 | * @param level The depth where this category is in the tree, used for proper indentation. | ||
209 | *### | ||
210 | #macro(displaySelectableCategory $name $level) | ||
211 | #set($categoryDoc = $xwiki.getDocument($name)) | ||
212 | #set($addCategURL = $doc.getURL('view', $escapetool.url({ | ||
213 | 'xaction': 'showAddCategory', | ||
214 | 'parentCategory' : $name | ||
215 | }))) | ||
216 | #set($addEntryParams = false) | ||
217 | #if($isBlogPost) | ||
218 | #set($entry = $xwiki.getDocument($doc.fullName)) | ||
219 | #set($entryObj = $isBlogPost) | ||
220 | #set($addEntryParams = true) | ||
221 | #elseif("$!request.entry" != '' && "$!request.entryObjNb" != '') | ||
222 | #set($entry = $xwiki.getDocument($request.entry)) | ||
223 | #set($entryObj = $entry.getObject($blogPostClassname, $numbertool.toNumber($request.entryObjNb).intValue())) | ||
224 | #set($addEntryParams = true) | ||
225 | #end | ||
226 | #if($isBlogPost || $addEntryParams) | ||
227 | ## parentCategory must be the last param | ||
228 | #set($addCategURL = $doc.getURL('view', $escapetool.url({ | ||
229 | 'xaction': 'showAddCategory', | ||
230 | 'entry': $entry.fullName, | ||
231 | 'entryObjNb': $entryObj.number, | ||
232 | 'parentCategory': $name | ||
233 | }))) | ||
234 | #end | ||
235 | #foreach($i in [1..$level])*#end ## | ||
236 | #set ($entryObjNumber = 0) | ||
237 | #if("$!entryObj.number" != '') | ||
238 | #set ($entryObjNumber = $entryObj.number) | ||
239 | #end | ||
240 | <span class="blog-category-level"><span class="blog-category">## | ||
241 | <label id='blog_category_${services.rendering.escape(${escapetool.xml($name)}, $xwiki.currentContentSyntaxId)}' title="#getCategoryDescription($categoryDoc)"><input name="${blogPostClassname}_$!{entryObjNumber}_category" value="$services.rendering.escape(${escapetool.xml($name)}, $xwiki.currentContentSyntaxId)" type="checkbox"#if($entryObj.getProperty('category').getValue().contains($name)) checked="checked" #end/> #getCategoryName($categoryDoc)</label>## | ||
242 | </span>## | ||
243 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $doc.fullName) && ("$!{request.xaction}" != "showAddCategory" || "$!{request.parentCategory}" != $name)) | ||
244 | <span class="blog-category-tools">## | ||
245 | <a href="$escapetool.xml($addCategURL)" class="tool add-subcategory">#toolImage('add')</a>## | ||
246 | </span>## | ||
247 | #end | ||
248 | </span> | ||
249 | #end | ||
250 | ## | ||
251 | ## | ||
252 | ## | ||
253 | #** | ||
254 | * Displays a form for creating a new category. If a parentCategory parameter is present in the | ||
255 | * query string, the parent category is set accordingly. Otherwise, the form provides a selection | ||
256 | * control for choosing the parent category among existing categories. | ||
257 | *### | ||
258 | ## DO NOT CHANGE INDENTATION | ||
259 | #macro(addCategoryForm) #set($addCategURL = $doc.getURL()) #if("$!request.entry" != '') #set($addCategURL = "${addCategURL}?entry=$escapetool.url($request.entry)&entryObjNb=$escapetool.url($!request.entryObjNb)")#end<form action="${addCategURL}" method="post" class="category-add-form"><div class='create-category'> <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> <input type="hidden" name="xaction" value="create"/> <label>$services.localization.render('blog.categories.new')<br/> <input type="text" name="newCategoryName" class="category-name-input" /></label><br/>#if("$!{request.parentCategory}" == "")<label>#* $services.localization.render('blog.categories.parent')*# $escapetool.xml($services.localization.render('blog.manageCategories.forms.sub_cat_of'))<br/> <select name="newCategoryParent" id="blog_category_selectBox" class="category-add-input"> <option value="${escapetool.xml($defaultCategoryParent)}" selected="selected">$escapetool.xml($services.localization.render('blog.manageCategories.forms.select_none'))</option> $!processedCategories.clear() #displayCategoriesHierarchy($tree 'option') </select> <br/></label>#else<input type="hidden" name="newCategoryParent" value="${escapetool.xml($request.parentCategory)}"/>#end<span class="buttonwrapper"><input class="button" type="submit" value="$escapetool.xml($services.localization.render('blog.manageCategories.forms.add_button_label'))" /></span> <a class="btn btn-default" href="$doc.getURL()">$escapetool.xml($services.localization.render('blog.manageCategories.forms.cancel_button_label'))</a> </div></form> #end | ||
260 | ## | ||
261 | ## | ||
262 | ## | ||
263 | #** | ||
264 | * Displays a form for renaming a category. | ||
265 | *### | ||
266 | ## DO NOT CHANGE INDENTATION | ||
267 | #macro(renameCategoryForm)## | ||
268 | <form action="$doc.getURL()" method="post" class="category-rename-form"><div class='rename-category'>## | ||
269 | <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> | ||
270 | <input type="hidden" name="xaction" value="rename"/>## | ||
271 | <input type="hidden" name="category" value="${escapetool.xml($request.category)}"/>## | ||
272 | <label>$services.localization.render('blog.categories.newName')<br/> <input type="text" name="newCategoryName" class="category-name-input" /></label><br/>## | ||
273 | <span class="buttonwrapper"><input class="button" type="submit" value="$escapetool.xml($services.localization.render('blog.manageCategories.forms.rename_button_label'))" /></span> ## | ||
274 | <a class="btn btn-default" href="$doc.getURL()">$escapetool.xml($services.localization.render('blog.manageCategories.forms.cancel_button_label'))</a>## | ||
275 | </div></form>## | ||
276 | #end | ||
277 | ## | ||
278 | ## | ||
279 | ## | ||
280 | #** | ||
281 | * Displays a category as part of a category hierarchy, followed by links for editing and deleting | ||
282 | * this category, if the current user has the rights to perform these actions. | ||
283 | * | ||
284 | * @param name The full name of the document containing the category to be displayed. | ||
285 | * @param level The depth where this category is in the tree, used for proper indentation. | ||
286 | *### | ||
287 | ## DO NOT CHANGE INDENTATION | ||
288 | #macro(displayEditableCategory $name $level) | ||
289 | #getEntriesForCategory($name $discard $totalEntries) | ||
290 | #set($nameUrl = $escapetool.url($name)) | ||
291 | #foreach($i in [1..$level])*#end ## | ||
292 | <span class="blog-category-level"><span class="blog-category">## | ||
293 | <a href="$services.rendering.escape($xwiki.getURL('Blog.CategoryRss', 'view', "xpage=plain&category=$nameUrl"), $doc.syntax)" title="RSS">#toolImage('rss')</a> ## | ||
294 | <span class="wikilink"><a href="$services.rendering.escape($xwiki.getURL($name), $doc.syntax)">#getCategoryName($xwiki.getDocument($name)) <span class="itemCount">($totalEntries)</span></a></span></span>## | ||
295 | <span class="blog-category-tools">## | ||
296 | #if($xwiki.hasAccessLevel('delete', $xcontext.user, $name) && ("$!{request.xaction}" != 'showRenameCategory' || "$!{request.category}" != $name))<a href="$services.rendering.escape($xwiki.getURL('Blog.ManageCategories', 'view', "xaction=showRenameCategory&category=$nameUrl"), $doc.syntax)" class="tool rename">#toolImage('pencil')</a>#end## | ||
297 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $doc.fullName) && ("$!{request.xaction}" != "showAddCategory" || "$!{request.parentCategory}" != $name))<a href="$services.rendering.escape($xwiki.getURL('Blog.ManageCategories', 'view', "xaction=showAddCategory&parentCategory=$nameUrl"), $doc.syntax)" class="tool add-subcategory">#toolImage('add')</a>#end## | ||
298 | #if($xwiki.hasAccessLevel('delete', $xcontext.user, $name)) <a href="$services.rendering.escape($xwiki.getURL('Blog.ManageCategories', 'view', "xaction=delete&category=$nameUrl&form_token=$!{services.csrf.getToken()}"), $doc.syntax)" class="tool delete">#toolImage('cross')</a>#end## | ||
299 | </span>## | ||
300 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $doc.fullName) && "$!{request.xaction}" == "showRenameCategory" && "$!{request.category}" == $name) #renameCategoryForm() #end## | ||
301 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $doc.fullName) && "$!{request.xaction}" == "showAddCategory" && "$!{request.parentCategory}" == $name) #addCategoryForm() #end## | ||
302 | </span> | ||
303 | #end | ||
304 | ## | ||
305 | ## | ||
306 | ## | ||
307 | #** | ||
308 | * Displays a category as part of a category hierarchy, wrapped in an <option> element, to | ||
309 | * be used in a select box. | ||
310 | * | ||
311 | * @param name The full name of the document containing the category to be displayed. | ||
312 | * @param level The depth where this category is in the tree, used for proper indentation. | ||
313 | *### | ||
314 | #macro(displayOptionCategory $name $level) | ||
315 | <option id="blog_category_${services.rendering.escape(${escapetool.xml($name)}, $doc.syntax)}_option" value="$services.rendering.escape(${escapetool.xml($name)}, $doc.syntax)">#if($level > 1)#foreach($i in [2..$level]) #end#end#getCategoryName($xwiki.getDocument($name))</option> | ||
316 | #end | ||
317 | ## | ||
318 | ## | ||
319 | ## | ||
320 | #** | ||
321 | * Displays a category as part of a category hierarchy, wrapped in a link. | ||
322 | * | ||
323 | * @param name The full name of the document containing the category to be displayed. | ||
324 | * @param level The depth where this category is in the tree, used for proper indentation. | ||
325 | *### | ||
326 | #macro(displaySimpleCategory $name $level) | ||
327 | #getEntriesForCategory($name $discard $totalEntries) | ||
328 | #set($nameUrl = $escapetool.url($name)) | ||
329 | #foreach($i in [1..$level])*#end (% class="blog-category-level" %)((( [[#toolImage('rss')>>$name||queryString="xpage=plain&sheet=Blog.CategoryRss" title="RSS"]] <span class="wikilink"><a href="$services.rendering.escape($xwiki.getURL($name), $xwiki.getCurrentContentSyntaxId())">#getCategoryName($xwiki.getDocument($name)) <span class="itemCount">($totalEntries)</span></a></span>))) | ||
330 | #end | ||
331 | ## | ||
332 | ## | ||
333 | ## | ||
334 | #** | ||
335 | * Prints the name of a category, indicated by its document. | ||
336 | * The result is XML-escaped and Wiki syntax escaped. | ||
337 | * | ||
338 | * @param categoryDoc The document containing the category to be displayed. | ||
339 | *### | ||
340 | #macro(getCategoryName $categoryDoc) | ||
341 | ## Don't indent! | ||
342 | #set($result = "$!categoryDoc.getObject(${blogCategoryClassname}).getProperty('name').value.trim()")## | ||
343 | #if($result == '') | ||
344 | #set($result = $categoryDoc.name) | ||
345 | #end | ||
346 | ## Escape wiki syntax, if any. | ||
347 | #set ($result = "$services.rendering.escape($result, $xwiki.currentContentSyntaxId)") | ||
348 | ## Escape HTML, if any. | ||
349 | $escapetool.xml($result)## | ||
350 | #end | ||
351 | ## | ||
352 | ## | ||
353 | ## | ||
354 | #** | ||
355 | * Prints the description of a category, indicated by its document. | ||
356 | * The result is XML-escaped | ||
357 | * | ||
358 | * @param categoryDoc The document containing the category to be displayed. | ||
359 | *### | ||
360 | #macro(getCategoryDescription $categoryDoc) | ||
361 | ## Don't indent! | ||
362 | $escapetool.xml($!categoryDoc.getObject(${blogCategoryClassname}).getProperty('description').value.trim())## | ||
363 | #end | ||
364 | ## | ||
365 | ## | ||
366 | ## | ||
367 | #** | ||
368 | * Generates a form for creating a new category. The form allows to enter the name of the new | ||
369 | * category, and select a parent category from the existing ones. | ||
370 | * | ||
371 | * @param tree The category hierarchy, a HashMap<String, List<String>> structure, where the key | ||
372 | * is the name of a category, and the value contains the names of all its subcategories. | ||
373 | * @todo When javascript is disabled, a link to "Manage categories" should be displayed instead. | ||
374 | * This "form" should be created from javascript. | ||
375 | *### | ||
376 | #macro(showCreateCategoryBoxWithForm $tree) | ||
377 | <form action="$doc.getURL()" method="post"> | ||
378 | #showCreateCategoryBox($tree) | ||
379 | </form> | ||
380 | #end | ||
381 | #** | ||
382 | * Generates a box for creating a new category. This allows to enter the name of the new | ||
383 | * category, and select a parent category from the existing ones. Note that this does not create | ||
384 | * a HTML form element, but requires one to be defined already as its ancestor. | ||
385 | * | ||
386 | * @param tree The category hierarchy HashMap<String, List<String>> structure, where the key | ||
387 | * is the name of a category, and the value contains the names of all its subcategories. | ||
388 | * @todo When javascript is disabled, a link to "Manage categories" should be displayed instead. | ||
389 | * This "form" should be created from javascript. | ||
390 | *### | ||
391 | #macro(showCreateCategoryBox $tree) | ||
392 | <div class='create-category'> | ||
393 | <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> | ||
394 | <input type="hidden" name="xaction" value="create"/> | ||
395 | <label>$services.localization.render('blog.categories.new') <input type="text" name="newCategoryName" /></label> | ||
396 | <label>$services.localization.render('blog.categories.parent') | ||
397 | <select name="newCategoryParent" id="blog_category_selectBox"> | ||
398 | <option value="${defaultCategoryParent}" selected="selected">None</option> | ||
399 | $!processedCategories.clear()## | ||
400 | #displayCategoriesHierarchy($tree 'option') | ||
401 | </select> | ||
402 | </label> | ||
403 | <span class="buttonwrapper"><input class="button" type="button" value="Add" id="blog_AddCategoryButton" /></span> | ||
404 | </div> | ||
405 | #end | ||
406 | ## | ||
407 | ## | ||
408 | ## | ||
409 | #macro(displayCategoryManagementTree $space $displayType) | ||
410 | <div class="blog-categories-list"> | ||
411 | #getCategoriesHierarchy("$!{space}" $tree) | ||
412 | #if ("$!space" != $defaultBlogSpace) | ||
413 | #set ($defaultCategoryParent = "${space}.WebHome") | ||
414 | #end | ||
415 | #displayCategoriesHierarchy($tree $displayType) | ||
416 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $doc.fullName)) | ||
417 | #set($addCategURL = $doc.getURL('view', $escapetool.url({ | ||
418 | 'xaction' : 'showAddCategory', | ||
419 | 'parentCategory' : '', | ||
420 | 'categoriesSpace': $space | ||
421 | }))) | ||
422 | #if($isBlogPost || ("$!request.entry" != '' && "$!request.entryObjNb" != '')) | ||
423 | #set($entryParam = $!doc.fullName) | ||
424 | #set($entryObjNbParam = $!entryObj.number) | ||
425 | #if(!$isBlogPost) | ||
426 | #set($entryParam = $!request.entry) | ||
427 | #set($entryObjNbParam = $!request.entryObjNb) | ||
428 | #end | ||
429 | #set($addCategURL = $doc.getURL('view', $escapetool.url({ | ||
430 | 'xaction' : 'showAddCategory', | ||
431 | 'parentCategory' : '', | ||
432 | 'entry' : $entryParam, | ||
433 | 'entryObjNb' : $entryObjNbParam, | ||
434 | 'categoriesSpace': $space | ||
435 | }))) | ||
436 | #end | ||
437 | * <span class="blog-add-category-label">$services.icon.renderHTML('add') <a href="$escapetool.xml($addCategURL)">$services.localization.render('blog.categories.addcategory')</a></span> | ||
438 | #if("$!{request.xaction}" == "showAddCategory" && "$!{request.parentCategory}" == "") #addCategoryForm() #end | ||
439 | #end | ||
440 | |||
441 | |||
442 | </div> | ||
443 | #end | ||
444 | ## | ||
445 | ## | ||
446 | ## | ||
447 | #** | ||
448 | * Deletes a category, moving all the subcategories to its parent and removing this category from | ||
449 | * all existing blog entries. | ||
450 | * | ||
451 | * @param category The full name of the document containing the category to be deleted. | ||
452 | *### | ||
453 | #macro(deleteCategory $category) | ||
454 | #set($categoryDoc = $xwiki.getDocument($category)) | ||
455 | #set($categoryParent = "$!categoryDoc.parent") | ||
456 | #if($categoryParent == '') | ||
457 | #set($categoryParent = "{$defaultCategoryParent}") | ||
458 | #end | ||
459 | #set($query = ', BaseObject obj where ') | ||
460 | #if($space != '') | ||
461 | #set($query = "${query}doc.space = '${space}' and ") | ||
462 | #end | ||
463 | ## Get the subcategories of the deleted category. | ||
464 | #set($query = "${query}obj.name = doc.fullName and obj.className = '${blogCategoryClassname}' and doc.fullName <> 'Blog.CategoryTemplate' and doc.parent = :category order by doc.name") | ||
465 | |||
466 | #foreach($item in $services.query.hql($query).bindValue('category', $category).execute()) | ||
467 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $item) && $!{services.csrf.isTokenValid("$!{request.getParameter('form_token')}")}) | ||
468 | #set($subcategoryDoc = $xwiki.getDocument($item)) | ||
469 | $subcategoryDoc.setParent($categoryParent) | ||
470 | $subcategoryDoc.save($services.localization.render('blog.manageCategories.comment.updatedParent'), true) | ||
471 | #end | ||
472 | #end | ||
473 | #set($query = ', BaseObject obj, DBStringListProperty categories join categories.list as category where ') | ||
474 | #if($space != '') | ||
475 | #set($query = "${query}doc.space = '${space}' and ") | ||
476 | #end | ||
477 | ## Get the blog posts of the deleted category. | ||
478 | #set($query = "${query}obj.name = doc.fullName and obj.className = '${blogPostClassname}' and doc.fullName <> 'Blog.BlogPostTemplate' and categories.id.id = obj.id and categories.id.name = 'category' and category = :category order by doc.name") | ||
479 | |||
480 | #foreach($item in $services.query.hql($query).bindValue('category', $category).execute()) | ||
481 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $item) && $!{services.csrf.isTokenValid("$!{request.getParameter('form_token')}")}) | ||
482 | #set($blogEntryDoc = $xwiki.getDocument($item)) | ||
483 | #set($discard = $blogEntryDoc.getObject(${blogPostClassname}).getProperty('category').value.remove($category)) | ||
484 | $blogEntryDoc.save($services.localization.render('blog.manageCategories.comment.removedDeletedCategory'), true) | ||
485 | #end | ||
486 | #end | ||
487 | $categoryDoc.delete() | ||
488 | #end | ||
489 | ## | ||
490 | ## | ||
491 | ## | ||
492 | #** | ||
493 | * Renames a category, updating all the subcategories and all existing blog entries. | ||
494 | * | ||
495 | * @param category The full name of the document containing the category to be renamed. | ||
496 | * @param newCategoryName The new name of the category. | ||
497 | *### | ||
498 | #macro(renameCategory $category $newCategoryName) | ||
499 | #set($categoryDoc = $xwiki.getDocument($category)) | ||
500 | #set ($newCategoryFullName = $newCategoryName) | ||
501 | #if ($category.space != $defaultBlogSpace) | ||
502 | #set ($newCategoryFullName = "${categoryDoc.space}.${newCategoryName}") | ||
503 | #end | ||
504 | #set($newCategoryDoc = $xwiki.getDocument($newCategoryFullName)) | ||
505 | #set($query = ', BaseObject obj where ') | ||
506 | ## Get the subcategories of the renamed category. | ||
507 | #set($query = "${query}obj.name = doc.fullName and obj.className = '${blogCategoryClassname}' and doc.fullName <> 'Blog.CategoryTemplate' and doc.parent = :category order by doc.name") | ||
508 | #foreach($item in $services.query.hql($query).bindValue('category', $category).execute()) | ||
509 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $item) && $!{services.csrf.isTokenValid("$!{request.getParameter('form_token')}")}) | ||
510 | #set($subcategoryDoc = $xwiki.getDocument($item)) | ||
511 | $subcategoryDoc.setParent($newCategoryDoc.fullName) | ||
512 | $subcategoryDoc.save($services.localization.render('blog.manageCategories.comment.updatedParent'), true) | ||
513 | #end | ||
514 | #end | ||
515 | #set($query = ', BaseObject obj, DBStringListProperty categories join categories.list as category where ') | ||
516 | ## Get the blog posts of the renamed category. | ||
517 | #set($query = "${query}obj.name = doc.fullName and obj.className = '${blogPostClassname}' and doc.fullName <> 'Blog.BlogPostTemplate' and categories.id.id = obj.id and categories.id.name = 'category' and category = :category order by doc.name") | ||
518 | #foreach($item in $services.query.hql($query).bindValue('category', $category).execute()) | ||
519 | #if($xwiki.hasAccessLevel('edit', $xcontext.user, $item) && $!{services.csrf.isTokenValid("$!{request.getParameter('form_token')}")}) | ||
520 | #set($blogEntryDoc = $xwiki.getDocument($item)) | ||
521 | #set($discard = $blogEntryDoc.getObject(${blogPostClassname}).getProperty('category').value.remove($category)) | ||
522 | #set($discard = $blogEntryDoc.getObject(${blogPostClassname}).getProperty('category').value.add($newCategoryDoc.fullName)) | ||
523 | $blogEntryDoc.save($services.localization.render('blog.manageCategories.comment.updatedRenamedCategory'), true) | ||
524 | #end | ||
525 | #end | ||
526 | #if ($!{services.csrf.isTokenValid("$!{request.getParameter('form_token')}")}) | ||
527 | $categoryDoc.getObject('Blog.CategoryClass').set('name', $newCategoryName) | ||
528 | $categoryDoc.save($services.localization.render('blog.manageCategories.comment.updatedCategory'), true) | ||
529 | $categoryDoc.rename($newCategoryFullName) | ||
530 | #end | ||
531 | #end | ||
532 | ## | ||
533 | ## | ||
534 | ## | ||
535 | #** | ||
536 | * Dipslay posts of a given category or a categories space. | ||
537 | * This macro is used in Blog.CategorySheet and Blog.CategoriesSheet pages | ||
538 | * | ||
539 | * @param catDoc The document containing the category or the WebHome page of a categories space. | ||
540 | * @param catObj The Blog.CategoryClass object attached to the category document, this parameter is null in case of categories space WebHome. | ||
541 | *### | ||
542 | #macro(displayCategoryPosts $catDoc $catObj) | ||
543 | #getEntriesForCategory($catDoc.fullName $discard $totalEntries) | ||
544 | |||
545 | #if ($totalEntries == 0) | ||
546 | |||
547 | {{info}}{{translation key="blog.categories.noentries"/}}{{/info}} | ||
548 | #else | ||
549 | #set ($macro.isCategoriesSpace = $catDoc.getObject('XWiki.DocumentSheetBinding').sheet == 'Blog.CategoriesSheet') | ||
550 | #if ($catObj || $macro.isCategoriesSpace) | ||
551 | |||
552 | (% class="cat-posts-count" %) | ||
553 | ==== [[#toolImage('feed')>>Blog.CategoryRss||queryString="xpage=plain&category=$escapetool.url($catDoc.fullName)" title="RSS"]] $services.localization.render('blog.category.posts.count', [$totalEntries]) ==== | ||
554 | #end | ||
555 | ## Keep testing the inline action for backward compatibility with older categories. | ||
556 | #if ($xcontext.action != 'edit' && $xcontext.action != 'inline') | ||
557 | #getCategoriesHierarchy($catDoc.space $tree) | ||
558 | #if ("$!tree.get($catDoc.fullName)" != '') | ||
559 | (% class="blog-categories-list subcategories cat-count" %) | ||
560 | ((( | ||
561 | ((( | ||
562 | ** ** | ||
563 | ))) | ||
564 | ((( | ||
565 | #displayCategoriesHierarchyRecursive($tree $catDoc.fullName 1 'simple') | ||
566 | ))) | ||
567 | ))) | ||
568 | #end | ||
569 | (% class="clearfloats" %)((())) | ||
570 | |||
571 | #set ($macro.layoutParams = 'displayTitle=true|useSummary=true') | ||
572 | #getBlogDocumentForCategoriesSpace($catDoc.space $blogDoc) | ||
573 | #getBlogPostsLayout($blogDoc $postsLayout) | ||
574 | #set ($category = $catDoc.fullName) | ||
575 | #if ($macro.isCategoriesSpace) | ||
576 | #set ($category = $catDoc.space) | ||
577 | #end | ||
578 | (% class="hfeed category" %)((({{blogpostlist category="$category.replaceAll('~', '~~').replaceAll('"', '~"')" paginated="yes" layout="$postsLayout.replaceAll('~', '~~').replaceAll('"', '~"')" layoutParams="$!macro.layoutParams.replaceAll('~', '~~').replaceAll('"', '~"')" /}}))) | ||
579 | #end | ||
580 | #end | ||
581 | #end | ||
582 | {{/velocity}} |