Wiki source code of Macros for the Blog Categories
Version 1.1 by Jan Rhebergen on 2021/02/27 22:16
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, $mathtool.toInteger($request.entryObjNb))) | ||
| 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}} |