Changes for page Hierarchy Macro
Last modified by Ruud de Jong on 2024/12/17 19:47
From version 2.1
edited by Dongxu Lu
on 2023/07/04 10:30
on 2023/07/04 10:30
Change comment:
Migrated property [type] from class [XWiki.WikiMacroParameterClass]
To version 3.1
edited by Ruud de Jong
on 2024/12/17 19:47
on 2024/12/17 19:47
Change comment:
Install extension [org.xwiki.contrib:xwiki-macro-hierarchy/1.3.1]
Summary
-
Page properties (3 modified, 0 added, 0 removed)
-
Objects (2 modified, 6 added, 0 removed)
Details
- Page properties
-
- Author
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki. DongxuLu1 +XWiki.RuuddeJong - Default language
-
... ... @@ -1,1 +1,0 @@ 1 -en - Content
-
... ... @@ -1,6 +1,7 @@ 1 1 Document that defines the hierarchy macro, which displays and allows to edit the documents hierarchy in a specific space (the standard parent-child relation) along with a special information, children order, which is saved in each parent to allow ordering its children as set by the user when displayed with this macro (and whenever some code which is aware of this information uses it). 2 2 3 3 Note that the children order information should be used as a relative order, since a document can have additional children which are not present in the order information, as the order information is not updated when the parent parents / children are changed through other means than this macro. In such situations, hierarchy macro uses the stored children order for a document as follows: 4 + 4 4 * for all the documents which are in the stored order, if they are an actual child of the document, they are displayed, as they appear in the stored order 5 5 * for all the actual children of the document in alphabetic order of their display values (with a special case for the displayTitle), if they have not been yet displayed, they are displayed. 6 6 Thus, children in the stored order will appear first, as dictated by the order, followed by the children for which there is no order information.
- XWiki.JavaScriptExtension[0]
-
- Code
-
... ... @@ -447,8 +447,8 @@ 447 447 if (parentLi) { 448 448 var sublist = parentLi.down('ul'); 449 449 if (sublist && sublist.parentNode == parentLi) { 450 - sublist.toggle(); 451 - handler.toggleClassName('open'); 450 + sublist.toggleClassName('hidden'); 451 + handler.toggleClassName('open'); 452 452 } 453 453 } 454 454 },
- XWiki.WikiMacroClass[0]
-
- Macro code
-
... ... @@ -19,11 +19,28 @@ 19 19 #if ($hasChildrenList || (($editable || $reorderable) && $context.action != "export")) 20 20 #set($showChildrenList = true) 21 21 #end 22 - <div class="hierarchynode"> 22 + ## 23 + ## we need to mark the opened node, @$openNode, using a CSS class called 'open-node' in order to target it in the DOM tree 24 + #set($markOpenNode = '') 25 + #if($isOpenNodeMode && $openNode.equals($parent)) 26 + #set($markOpenNode = 'open-node') 27 + #end 28 + <div class="hierarchynode ${markOpenNode}"> 23 23 ## display the toggle button only if it has children list and we're not in export action (exporting pdf) 24 24 ## actually we should put this button from js, when loading the handlers, since it can only be used with js. FIXME: move 25 25 #if($showChildrenList && $context.action != "export") 26 - <span class="togglenodehandler hidden open">toggle</span> 32 + #set($classAttributeValue = "togglenodehandler hidden") 33 + ## if the pathToRootNode array contains at least 1 element then the tree must be collapsed except for one node 34 + ## the array holds the path from that node to the root node 35 + ## if the current processed node, @$parent, is in the array which holds the ancestor hierarchy of the document specified in the @$openNode parameter 36 + ## and @$collapsed is false, we display it 37 + #if(($isOpenNodeMode && $pathToRootNode.contains($parent)) && !$collapsed) 38 + #set($classAttributeValue = "${classAttributeValue} open") 39 + ## otherwise, if there are no elements in the @$pathToRootNode array and there is no explicit collapse set, then display the nodes expanded 40 + #elseif(!$isOpenNodeMode && !$collapsed) 41 + #set($classAttributeValue = "${classAttributeValue} open") 42 + #end 43 + <span class="${classAttributeValue}">toggle</span> 27 27 #else 28 28 ## for other cases, display anyway a toggle span, for layouting purposes 29 29 <span class="togglenodehandlerplaceholder"></span> ... ... @@ -45,7 +45,7 @@ 45 45 ## don't display link if we're in edit mode since dragging a link is a pain since you'll too often click it. 46 46 ## Don't display link if doesn't have right to view 47 47 #if(!$editable && !$reorderable && $hasRightToView)<a href="${xwiki.getURL($parent)}">#end 48 - <span class="documentlabel">$ {titleToDisplay}</span> #if(!$hasRightToView)*#end65 + <span class="documentlabel">$titleToDisplay</span> #if(!$hasRightToView)*#end 49 49 #if(!$editable && !$reorderable && $hasRightToView)</a>#end 50 50 ## display reference of this element, to be able to catch it with js and perform the operation 51 51 <input type="hidden" name="docreference" value="$parent" /> ... ... @@ -68,7 +68,12 @@ 68 68 </div> 69 69 ## and now the children 70 70 #if ($showChildrenList) 71 - <ul> 88 + #set($ulClassAttribute = '') 89 + ## we hide the sublists if the node is not on the hierarchical path, not contained in the ancestor array of the document @$openNode, or if the collapse is set explicitly 90 + #if(($isOpenNodeMode && !$pathToRootNode.contains($parent)) || $collapsed) 91 + #set($ulClassAttribute = 'hidden') 92 + #end 93 + <ul class="$ulClassAttribute"> 72 72 #if ($hasChildrenList) 73 73 ## prepare the children list, in the order given by the ChildrenOrder object in the parent 74 74 #set($childrenListToDisplay = []) ... ... @@ -120,6 +120,35 @@ 120 120 #set($discard = $xwiki.jsx.use("$xcontext.macro.doc", {'defer' : false, 'minify': false})) 121 121 ## get the parameters, the space to show hierarchy for 122 122 #set($space = "$!xcontext.macro.params.space") 145 +## get the node value (a document's full name) for which we want to display the path expanded from the root node to the specified node 146 +## collapsing all the other branches 147 +#set($openNode = "$!xcontext.macro.params.openNode") 148 +## we need to recursively get all the ancestors of the specified node @$openNode 149 +#set($pathToRootNode = []) 150 +#if(!$openNode.isEmpty() && $xwiki.exists($openNode)) 151 + #macro(getPathToRoot $document) 152 + #set($documentParent = $document.getParent()) 153 + #if(!$documentParent.equals('')) 154 + #set($discard = $pathToRootNode.add($documentParent)) 155 + #getPathToRoot($xwiki.getDocument($documentParent)) 156 + #end 157 + #end 158 + ## 159 + #getPathToRoot($xwiki.getDocument($openNode)) 160 +#end 161 +#set($isOpenNodeMode = $pathToRootNode.size() > 0) 162 +## specify if the tree should be collapsed 163 +#set($collapsed = "$!xcontext.macro.params.collapsed" == 'true' || "$!xcontext.macro.params.collapsed" == 'yes') 164 +## get the list of spaces that will be excluded 165 +#set($excludedSpacesString = "$!xcontext.macro.params.excludespaces") 166 +#set($excludedSpacesRaw = $excludedSpacesString.split(',')) 167 +#set($excludedSpaces = []) 168 +#foreach($excludedSpacesElt in $excludedSpacesRaw) 169 + #set($excludedSpacesElt = $excludedSpacesElt.trim()) 170 + #if("$!excludedSpacesElt" != "") 171 + #set($discard = $excludedSpaces.add($excludedSpacesElt)) 172 + #end 173 +#end 123 123 ## the list of documents to exclude, if any 124 124 #set($excludeListString = "$!xcontext.macro.params.excludes") 125 125 #set($excludeListRaw = $excludeListString.split(',')) ... ... @@ -131,6 +131,16 @@ 131 131 #set($discard = $excludeList.add($excludedElt)) 132 132 #end 133 133 #end 185 +## the list of the doccuments that will be displayed 186 +#set($displayedDocumentsString = "$!xcontext.macro.params.doclist") 187 +#set($displayedDocumentsRaw = $displayedDocumentsString.split(',')) 188 +#set($displayedDocuments = []) 189 +#foreach($displayedDocElt in $displayedDocumentsRaw) 190 + #set($displayedDocElt = $displayedDocElt.trim()) 191 + #if("$!displayedDocElt" != "") 192 + #set($discard = $displayedDocuments.add($displayedDocElt)) 193 + #end 194 +#end 134 134 ## whether only roots of the tree should be shown or not 135 135 #set($onlyRoots = false) 136 136 #if("$!xcontext.macro.params.onlyroots" == "true" || "$!xcontext.macro.params.onlyroots" == "yes") ... ... @@ -191,6 +191,22 @@ 191 191 #set($where = "doc.space = ?") 192 192 #set($discard = $paramsList.add($space)) 193 193 #end 255 +## exclude spaces 256 +#if($excludedSpaces.size() > 0) 257 + #if($where.length() > 0) 258 + set($where = $where + ' and ') 259 + #end 260 + #set($where = $where + 'doc.space not in (') 261 + #foreach($excluded in $excludedSpaces) 262 + #if($velocityCount > 1) 263 + #set($where = $where + ', ') 264 + #end 265 + #set($where = $where + '?') 266 + #set($discard = $paramsList.add($excluded)) 267 + #end 268 + #set($where = $where + ')') 269 +#end 270 +## exclude doccuments 194 194 #if($excludeList.size() > 0) 195 195 #if ($where.length() > 0) 196 196 #set($where = $where + ' and ') ... ... @@ -205,12 +205,49 @@ 205 205 #end 206 206 #set($where = $where + ')') 207 207 #end 285 + 286 +#set($docLanguage = "$!xcontext.macro.params.documentLanguage") 287 +#if($docLanguage != '') 288 + #if ($where.length() > 0) 289 + #set($where = $where + ' and ') 290 + #end 291 + #if($docLanguage == $xwiki.getXWikiPreference('default_language')) 292 + #set($where = "${where} (doc.language = ? OR doc.language='') ") 293 + #else 294 + #set($where = "${where} doc.language = ? ") 295 + #end 296 + #set($discard = $paramsList.add($docLanguage)) 297 +#end 208 208 #if($where.length() > 0) 209 209 #set($where = " where ${where}") 210 210 #end 211 211 #set($sql = "$selectFrom $where $order") 212 212 ## get the results 213 -#set($resultDocs = $xwiki.search($sql, $paramsList)) 303 +#if("$!displayedDocuments" != "[]") 304 + #set($displayedDocumentsDoc = []) 305 + #foreach($element in $displayedDocuments) 306 + #set($buffer = []) 307 + #set($bufferDoc = $xwiki.getDocument($element)) 308 + #set($discard = $buffer.add("$!bufferDoc")) 309 + #set($discard = $buffer.add("$!bufferDoc.parent")) 310 + #if($displayValue == 'fullName') 311 + #set($discard = $buffer.add("$!bufferDoc.fullName")) 312 + #elseif($displayValue == 'name') 313 + #set($discard = $buffer.add("$!bufferDoc.name")) 314 + #elseif($displayValue == 'title') 315 + #set($discard = $buffer.add("$!bufferDoc.title")) 316 + #end 317 + #set($discard = $displayedDocumentsDoc.add($buffer)) 318 + #end 319 + #set($resultDocs = $displayedDocumentsDoc) 320 +#else 321 + #set($displayHidden = "$!xcontext.macro.params.displayHidden") 322 + #set($query = $services.query.hql($sql).bindValues($paramsList)) 323 + #if($displayHidden != "true") 324 + #set($query = $query.addFilter("hidden")) 325 + #end 326 + #set($resultDocs = $query.execute()) 327 +#end 214 214 ## prepare the tree 215 215 #set($childrenMap = {}) 216 216 ## compute the title to be displayed and put it in the map ... ... @@ -227,7 +227,8 @@ 227 227 ## filter the docs in the passed space and filter out the excludes from parents 228 228 #set($currentParent = $resultDoc.get(1)) 229 229 #set($currentParentReference = $services.model.resolveDocument($currentParent, 'currentmixed', $currentReference)) 230 - #if("$!currentParent" != "" && !$excludeList.contains($currentParent) && $currentParentReference.wikiReference.name.equals($xcontext.wiki) && ("$!space" == "" || $currentParentReference.lastSpaceReference.name.equals($space))) 344 + #set($currentParentSpace = $xwiki.getDocument("$currentParent").space) 345 + #if("$!currentParent" != "" && !$excludeList.contains($currentParent) && !$excludedSpaces.contains($currentParentSpace) && ($displayedDocuments.contains($currentParent) || $displayedDocuments.size() == 0 ) && $currentParentReference.wikiReference.name.equals($xcontext.wiki) && ("$!space" == "" || $currentParentReference.lastSpaceReference.name.equals($space))) 231 231 ## it's not an orphan, it has non-excluded parent in the current wiki and in the passed space 232 232 ## put it in his parent's children list 233 233 ## we'll get the parent by re-serializing the resolved reference,
- XWiki.WikiMacroParameterClass[12]
-
- Parameter name
-
... ... @@ -1,0 +1,1 @@ 1 +documentLanguage - Parameter description
-
... ... @@ -1,0 +1,1 @@ 1 +This parameter's value is used to display a tree of documents in the desired language. - Parameter mandatory
-
... ... @@ -1,0 +1,1 @@ 1 +No
- XWiki.WikiMacroParameterClass[13]
-
- Parameter name
-
... ... @@ -1,0 +1,1 @@ 1 +openNode - Parameter description
-
... ... @@ -1,0 +1,1 @@ 1 +This parameter's value is used to restrict the hierarchy tree from displaying the whole tree expanded, instead it expands only the path from the root node to the specified document's node. 'openNode' parameter's value should specify the full name of the document for which the tree should expand its branch. - Parameter mandatory
-
... ... @@ -1,0 +1,1 @@ 1 +No
- XWiki.WikiMacroParameterClass[14]
-
- Parameter default value
-
... ... @@ -1,0 +1,1 @@ 1 +false - Parameter name
-
... ... @@ -1,0 +1,1 @@ 1 +collapsed - Parameter description
-
... ... @@ -1,0 +1,1 @@ 1 +This parameter's value is used to collapse the tree of documents. - Parameter mandatory
-
... ... @@ -1,0 +1,1 @@ 1 +No
- XWiki.WikiMacroParameterClass[15]
-
- Parameter name
-
... ... @@ -1,0 +1,1 @@ 1 +excludespaces - Parameter description
-
... ... @@ -1,0 +1,1 @@ 1 +Comma separated list of spaces to exclude from the hierarchy display. - Parameter mandatory
-
... ... @@ -1,0 +1,1 @@ 1 +No
- XWiki.WikiMacroParameterClass[16]
-
- Parameter name
-
... ... @@ -1,0 +1,1 @@ 1 +doclist - Parameter description
-
... ... @@ -1,0 +1,1 @@ 1 +Document list that will be displayed - Parameter mandatory
-
... ... @@ -1,0 +1,1 @@ 1 +No
- XWiki.WikiMacroParameterClass[17]
-
- Parameter default value
-
... ... @@ -1,0 +1,1 @@ 1 +false - Parameter name
-
... ... @@ -1,0 +1,1 @@ 1 +displayHidden - Parameter description
-
... ... @@ -1,0 +1,1 @@ 1 +Display the hidden documents - Parameter mandatory
-
... ... @@ -1,0 +1,1 @@ 1 +No