Изменения документа Document Tree Macros

Редактировал(а) Георгий Глущенко 2026/07/02 17:46

От версии 5.1
отредактировано Давид Гавриков
на 2024/10/22 15:18
Изменить комментарий: Install extension [org.xwiki.platform:xwiki-platform-index-tree-macro/16.8.0]
К версии 10.1
отредактировано Георгий Глущенко
на 2026/07/02 17:46
Изменить комментарий: Install extension [org.xwiki.platform:xwiki-platform-index-tree-macro/18.5.0]

Сводка

Подробности

Свойства страницы
Автор документа
... ... @@ -1,1 +1,1 @@
1 -XWiki.gavrikof
1 +XWiki.ggv
Содержимое
... ... @@ -30,11 +30,19 @@
30 30   #end
31 31   #end
32 32   ## Handle relative references
33 - #makeNodeReferencesAbsolute($docTreeConfig ['root', 'openTo'])
34 - ## Sort the child documents by (raw) title when the node label is the document title.
35 - #if ($docTreeConfig.showDocumentTitle)
36 - #set ($docTreeConfig.orderBy = 'title')
33 + #foreach ($key in ['root', 'openTo'])
34 + #set ($docTreeConfig[$key] = $services.index.tree.normalizeEntityTreeNodeId($docTreeConfig[$key]))
37 37   #end
36 + ## FIXME: The 'orderBy' property of the tree API is shared by all tree node types, which means we can't indicate a
37 + ## different sort field per tree node type (e.g. sort wiki nodes by name and document nodes by last modification
38 + ## date). At the same time, this property is currently taken into account only for sorting document tree nodes, so for
39 + ## now we set its value to the specified document sort. In the future we may want to convert this into a map, where
40 + ## the key is the node type.
41 + #set ($docTreeConfig.orderBy = $docTreeConfig.sortDocumentsBy)
42 + ## Sort the child documents by (raw) title when the node label is the document title and there's no sort specified.
43 + #if ($docTreeConfig.showDocumentTitle && "$!docTreeConfig.orderBy" == '')
44 + #set ($docTreeConfig.orderBy = 'title:asc')
45 + #end
38 38   ## Determine which hierarchy needs to be used.
39 39   #if ($docTreeConfig.showSpaces)
40 40   #if ($docTreeConfig.hierarchyMode == 'parentchild')
... ... @@ -50,29 +50,6 @@
50 50   #set ($discard = $tree.properties.putAll($docTreeConfig))
51 51  #end
52 52  
53 -#set ($documentPseudoNodeTypes = ['translations', 'attachments', 'classProperties', 'objects', 'addDocument',
54 - 'addAttachment'])
55 -#macro (makeNodeReferencesAbsolute $map $keys)
56 - #foreach ($key in $keys)
57 - #set ($nodeId = $map.get($key))
58 - #set ($parts = $nodeId.split(':', 2))
59 - #if ($parts && $parts.size() == 2)
60 - #set ($nodeType = $parts[0].toLowerCase())
61 - #set ($nodeReference = $parts[1])
62 - #set ($entityType = $nodeType)
63 - #if ($documentPseudoNodeTypes.contains($nodeType))
64 - #set ($entityType = 'document')
65 - #end
66 - #set ($discard = "#evaluate(""${escapetool.h}set (${escapetool.d}entityReference =
67 - ${escapetool.d}services.model.resolve$stringtool.capitalize($entityType)(${escapetool.d}nodeReference))"")")
68 - #if ($entityReference)
69 - #set ($nodeReference = $services.model.serialize($entityReference, 'default'))
70 - #end
71 - #set ($discard = $map.put($key, "$nodeType:$nodeReference"))
72 - #end
73 - #end
74 -#end
75 -
76 76  #macro (handleDocumentTreeRequest)
77 77   #if ($request.action)
78 78   #if ($services.csrf.isTokenValid($request.form_token))
... ... @@ -146,6 +146,8 @@
146 146   #set ($limit = $mathtool.max($numbertool.toNumber($request.limit).intValue(), 1))
147 147   #if ("$!limit" == '')
148 148   #set ($limit = 15)
134 + #else
135 + #validateQueryLimit($limit)
149 149   #end
150 150   #if ($nodeId == '#' && $docTreeConfig.showRoot)
151 151   #maybeAddNode($actualNodeId $children)
... ... @@ -165,8 +165,39 @@
165 165   #if ($parts && $parts.size() == 2)
166 166   #set ($nodeType = $parts[0])
167 167   #set ($nodeReference = $parts[1])
168 - #set ($discard = "#evaluate(""${escapetool.h}maybeAdd$stringtool.capitalize($nodeType)Node(
169 - ${escapetool.d}nodeReference ${escapetool.d}siblings ${escapetool.d}placeholder)"")")
155 + #if ($nodeType == 'farm')
156 + #maybeAddFarmNode($nodeReference $siblings)
157 + #elseif ($nodeType == 'wiki')
158 + #maybeAddWikiNode($nodeReference $siblings $placeholder)
159 + #elseif ($nodeType == 'space')
160 + #maybeAddSpaceNode($nodeReference $siblings $placeholder)
161 + #elseif ($nodeType == 'document')
162 + #maybeAddDocumentNode($nodeReference $siblings $placeholder)
163 + #elseif ($nodeType == 'addDocument')
164 + #maybeAddAddDocumentNode($nodeReference $siblings)
165 + #elseif ($nodeType == 'translations')
166 + #maybeAddTranslationsNode($nodeReference $siblings)
167 + #elseif ($nodeType == 'translation')
168 + #maybeAddTranslationNode($nodeReference $siblings)
169 + #elseif ($nodeType == 'attachments')
170 + #maybeAddAttachmentsNode($nodeReference $siblings)
171 + #elseif ($nodeType == 'attachment')
172 + #maybeAddAttachmentNode($nodeReference $siblings)
173 + #elseif ($nodeType == 'addAttachment')
174 + #maybeAddAddAttachmentNode($nodeReference $siblings)
175 + #elseif ($nodeType == 'classProperties')
176 + #maybeAddClassPropertiesNode($nodeReference $siblings)
177 + #elseif ($nodeType == 'classProperty')
178 + #maybeAddClassPropertyNode($nodeReference $siblings)
179 + #elseif ($nodeType == 'objects')
180 + #maybeAddObjectsNode($nodeReference $siblings)
181 + #elseif ($nodeType == 'objectsOfType')
182 + #maybeAddObjectsOfTypeNode($nodeReference $siblings)
183 + #elseif ($nodeType == 'object')
184 + #maybeAddObjectNode($nodeReference $siblings)
185 + #elseif ($nodeType == 'objectProperty')
186 + #maybeAddObjectPropertyNode($nodeReference $siblings)
187 + #end
170 170   #end
171 171  #end
172 172  
... ... @@ -199,6 +199,7 @@
199 199  
200 200  #macro (maybeAddFarmNode $nodeReference $siblings)
201 201   #set ($farmHomeReference = $services.model.resolveDocument('', 'default'))
220 + #set ($isOpened = $docTreeConfig.expandToLevel > 0)
202 202   #set ($discard = $siblings.add({
203 203   'id': 'farm:*',
204 204   'text': 'Farm',
... ... @@ -208,6 +208,9 @@
208 208   'type': 'farm',
209 209   'validChildren': ['wiki', 'pagination']
210 210   },
230 + 'state': {
231 + 'opened': $isOpened
232 + },
211 211   'a_attr': {
212 212   'href': $xwiki.getURL($farmHomeReference)
213 213   }
... ... @@ -236,6 +236,7 @@
236 236   #else
237 237   #set ($label = $wiki.id)
238 238   #end
261 + #set ($isOpened = $docTreeConfig.expandToLevel > 0)
239 239   #set ($discard = $siblings.add({
240 240   'id': "wiki:$wiki.id",
241 241   'text': $label,
... ... @@ -247,6 +247,9 @@
247 247   'validChildren': ['space', 'document', 'pagination'],
248 248   'canDelete': $canDeleteWiki
249 249   },
273 + 'state': {
274 + 'opened': $isOpened
275 + },
250 250   'a_attr': {
251 251   'href': $xwiki.getURL($wiki.mainPageReference)
252 252   }
... ... @@ -272,6 +272,7 @@
272 272  
273 273  #macro (addSpaceNode $spaceReference $siblings)
274 274   #set ($spaceId = $services.model.serialize($spaceReference, 'default'))
301 + #set ($spaceNodeId = "space:$spaceId")
275 275   #set ($hasSpaceAdmin = $services.security.authorization.hasAccess('admin', $spaceReference))
276 276   #set ($canViewSpace = $services.security.authorization.hasAccess('view', $spaceReference))
277 277   #if ($docTreeConfig.showTerminalDocuments)
... ... @@ -279,10 +279,21 @@
279 279   #set ($hasChildren = true)
280 280   #else
281 281   ## We display only the nested spaces. This space might contain only documents.
282 - #set ($hasChildren = $tree.getChildCount("space:$spaceId") > 0)
309 + #set ($hasChildren = $tree.getChildCount($spaceNodeId) > 0)
283 283   #end
311 + #set ($isOpened = false)
312 + #if ("$!docTreeConfig.expandToLevel" != '')
313 + #set ($rootNode = "wiki:$services.wiki.currentWikiId")
314 + #if ("$!docTreeConfig.root" != '')
315 + #set ($rootNode = "wiki:$services.wiki.currentWikiId")
316 + #else
317 + #set ($rootNode = $docTreeConfig.root)
318 + #end
319 + #set ($rootDistance = $tree.getPath($spaceNodeId).size())
320 + #set ($isOpened = ($rootDistance != -1 && $docTreeConfig.expandToLevel >= $rootDistance))
321 + #end
284 284   #set ($discard = $siblings.add({
285 - 'id': "space:$spaceId",
323 + 'id': $spaceNodeId,
286 286   'text': $spaceReference.name,
287 287   'icon': 'fa fa-folder-o',
288 288   'iconOpened': 'fa fa-folder-open-o',
... ... @@ -300,6 +300,9 @@
300 300   'createDocumentURL': $xwiki.getURL($spaceReference, 'create', $NULL),
301 301   'deleteURL': $xwiki.getURL($spaceReference, 'deletespace', $NULL)
302 302   },
341 + 'state': {
342 + 'opened': $isOpened
343 + },
303 303   'a_attr': {
304 304   'href': $xwiki.getURL($spaceReference)
305 305   }
... ... @@ -325,6 +325,7 @@
325 325  
326 326  #macro (addDocumentNode $documentReference $siblings)
327 327   #set ($documentId = $services.model.serialize($documentReference, 'default'))
369 + #set ($docNodeId = "document:$documentId")
328 328   #set ($label = $documentReference.name)
329 329   #if (!$docTreeConfig.showSpaces &&
330 330   $documentReference.name == $services.model.getEntityReference('DOCUMENT', 'default').name)
... ... @@ -341,9 +341,11 @@
341 341   #set ($label = $plainTitle)
342 342   #end
343 343   #end
344 - #set ($hasChildren = $tree.getChildCount("document:$documentId") > 0)
386 + #set ($hasChildren = $tree.getChildCount($docNodeId) > 0)
387 + #set ($isOpened = false)
388 + #computeIsOpened($docNodeId $isOpened)
345 345   #set ($discard = $siblings.add({
346 - 'id': "document:$documentId",
390 + 'id': $docNodeId,
347 347   'text': $label,
348 348   'icon': 'fa fa-file-o',
349 349   'children': $hasChildren,
... ... @@ -358,6 +358,9 @@
358 358   'canCopy': $canViewDoc,
359 359   'createDocumentURL': $xwiki.getURL($documentReference, 'create', $NULL)
360 360   },
405 + 'state': {
406 + 'opened': $isOpened
407 + },
361 361   'a_attr': {
362 362   'href': $xwiki.getURL($documentReference)
363 363   }
... ... @@ -402,9 +402,27 @@
402 402   #end
403 403  #end
404 404  
452 +#macro (computeIsOpened $docNodeId $result)
453 + #set ($isOpened = false)
454 + #if ("$!docTreeConfig.expandToLevel" != '')
455 + #set ($rootNode = "wiki:$services.wiki.currentWikiId")
456 + #if ("$!docTreeConfig.root" != '')
457 + #set ($rootNode = "wiki:$services.wiki.currentWikiId")
458 + #else
459 + #set ($rootNode = $docTreeConfig.root)
460 + #end
461 + #set ($rootDistance = $tree.getPath($docNodeId).size())
462 + #set ($isOpened = ($rootDistance != -1 && $docTreeConfig.expandToLevel >= $rootDistance))
463 + #end
464 + #setVariable("$result" $isOpened)
465 +#end
466 +
405 405  #macro (addTranslationsNode $documentReference $siblings)
406 - #set ($discard = $children.add({
407 - 'id': "translations:${documentReference}",
468 + #set ($isOpened = false)
469 + #set ($docNodeId = "translations:${documentReference}")
470 + #computeIsOpened($docNodeId $isOpened)
471 + #set ($discard = $siblings.add({
472 + 'id': $docNodeId,
408 408   'text': 'Translations',
409 409   'icon': 'fa fa-language',
410 410   'children': true,
... ... @@ -412,6 +412,9 @@
412 412   'type': 'translations',
413 413   'validChildren': ['translation'],
414 414   'canDelete': $services.security.authorization.hasAccess('delete', $documentReference)
480 + },
481 + 'state': {
482 + 'opened': $isOpened
415 415   }
416 416   }))
417 417  #end
... ... @@ -428,8 +428,11 @@
428 428  
429 429  #macro (addTranslationNode $translationReference $siblings)
430 430   #set ($currentLocale = $services.localization.currentLocale)
499 + #set ($isOpened = false)
500 + #set ($docNodeId = "translation:$services.model.serialize($translationReference, 'default')_$translationReference.locale")
501 + #computeIsOpened($docNodeId $isOpened)
431 431   #set ($discard = $siblings.add({
432 - 'id': "translation:$services.model.serialize($translationReference, 'default')_$translationReference.locale",
503 + 'id': $docNodeId,
433 433   'text': $translationReference.locale.getDisplayName($currentLocale),
434 434   'icon': 'fa fa-file-text-o',
435 435   'children': false,
... ... @@ -440,6 +440,9 @@
440 440   },
441 441   'a_attr': {
442 442   'href': $xwiki.getURL($translationReference)
514 + },
515 + 'state': {
516 + 'opened': $isOpened
443 443   }
444 444   }))
445 445  #end
... ... @@ -456,8 +456,11 @@
456 456  #end
457 457  
458 458  #macro (addAttachmentsNode $documentReference $siblings)
533 + #set ($isOpened = false)
534 + #set ($docNodeId = "attachments:${documentReference}")
535 + #computeIsOpened($docNodeId $isOpened)
459 459   #set ($discard = $siblings.add({
460 - 'id': "attachments:${documentReference}",
537 + 'id': $docNodeId,
461 461   'text': 'Attachments',
462 462   'icon': 'fa fa-paperclip',
463 463   'children': true,
... ... @@ -469,6 +469,9 @@
469 469   },
470 470   'a_attr': {
471 471   'href': $xwiki.getURL($documentReference, 'view', 'viewer=attachments')
549 + },
550 + 'state': {
551 + 'opened': $isOpened
472 472   }
473 473   }))
474 474  #end
... ... @@ -488,8 +488,11 @@
488 488   #set ($attachmentId = $services.model.serialize($attachmentReference, 'default'))
489 489   #set ($canEditDoc = $services.security.authorization.hasAccess('edit', $attachmentReference.parent))
490 490   #getAttachmentIcon($attachment $icon)
571 + #set ($isOpened = false)
572 + #set ($docNodeId = "attachment:$attachmentId")
573 + #computeIsOpened($docNodeId $isOpened)
491 491   #set ($discard = $siblings.add({
492 - 'id': "attachment:$attachmentId",
575 + 'id': $docNodeId,
493 493   'text': $attachment.filename,
494 494   'icon': $icon,
495 495   'children': false,
... ... @@ -508,6 +508,9 @@
508 508   },
509 509   'a_attr': {
510 510   'href': $attachment.document.getAttachmentURL($attachment.filename)
594 + },
595 + 'state': {
596 + 'opened': $isOpened
511 511   }
512 512   }))
513 513  #end
... ... @@ -586,8 +586,11 @@
586 586  #end
587 587  
588 588  #macro (addClassPropertiesNode $documentReference $siblings)
589 - #set ($discard = $children.add({
590 - 'id': "classProperties:${documentReference}",
675 + #set ($isOpened = false)
676 + #set ($docNodeId = "classProperties:${documentReference}")
677 + #computeIsOpened($docNodeId $isOpened)
678 + #set ($discard = $siblings.add({
679 + 'id': $docNodeId,
591 591   'text': 'Class Properties',
592 592   'icon': 'fa fa-gears',
593 593   'children': true,
... ... @@ -595,6 +595,9 @@
595 595   'type': 'classProperties',
596 596   'validChildren': ['classProperty'],
597 597   'canDelete': $services.security.authorization.hasAccess('edit', $documentReference)
687 + },
688 + 'state': {
689 + 'opened': $isOpened
598 598   }
599 599   }))
600 600  #end
... ... @@ -627,8 +627,11 @@
627 627   #if (!$icon)
628 628   #set ($icon = 'gear')
629 629   #end
722 + #set ($isOpened = false)
723 + #set ($docNodeId = "classProperty:$classPropertyId")
724 + #computeIsOpened($docNodeId $isOpened)
630 630   #set ($discard = $siblings.add({
631 - 'id': "classProperty:$classPropertyId",
726 + 'id': $docNodeId,
632 632   'text': $property.name,
633 633   'icon': "fa fa-$icon",
634 634   'children': false,
... ... @@ -636,6 +636,9 @@
636 636   'id': $classPropertyId,
637 637   'type': 'classProperty',
638 638   'validChildren': []
734 + },
735 + 'state': {
736 + 'opened': $isOpened
639 639   }
640 640   }))
641 641  #end
... ... @@ -652,8 +652,11 @@
652 652  #end
653 653  
654 654  #macro (addObjectsNode $documentReference $siblings)
655 - #set ($discard = $children.add({
656 - 'id': "objects:${documentReference}",
753 + #set ($isOpened = false)
754 + #set ($docNodeId = "objects:${documentReference}")
755 + #computeIsOpened($docNodeId $isOpened)
756 + #set ($discard = $siblings.add({
757 + 'id': $docNodeId,
657 657   'text': 'Objects',
658 658   'icon': 'fa fa-cubes',
659 659   'children': true,
... ... @@ -661,6 +661,9 @@
661 661   'type': 'objects',
662 662   'validChildren': ['objectsOfType'],
663 663   'canDelete': $services.security.authorization.hasAccess('edit', $documentReference)
765 + },
766 + 'state': {
767 + 'opened': $isOpened
664 664   }
665 665   }))
666 666  #end
... ... @@ -671,8 +671,11 @@
671 671   #set ($documentReference = $services.model.resolveDocument($parts.get(0)))
672 672   #set ($classReference = $services.model.resolveDocument($parts.get(1)))
673 673   #if ($services.security.authorization.hasAccess('view', $documentReference))
674 - #set ($discard = $children.add({
675 - 'id': "objectsOfType:$documentReference/$classReference",
778 + #set ($isOpened = false)
779 + #set ($docNodeId = "objectsOfType:$documentReference/$classReference")
780 + #computeIsOpened($docNodeId $isOpened)
781 + #set ($discard = $siblings.add({
782 + 'id': $docNodeId,
676 676   'text': $services.model.serialize($classReference, 'local'),
677 677   'icon': 'fa fa-cubes',
678 678   'children': true,
... ... @@ -680,6 +680,9 @@
680 680   'type': 'objectsOfType',
681 681   'validChildren': ['object', 'pagination'],
682 682   'canDelete': $services.security.authorization.hasAccess('edit', $documentReference)
790 + },
791 + 'state': {
792 + 'opened': $isOpened
683 683   }
684 684   }))
685 685   #end
... ... @@ -706,8 +706,11 @@
706 706  
707 707  #macro (addObjectNode $object $objectReference $siblings)
708 708   #set ($objectId = $services.model.serialize($objectReference, 'default'))
709 - #set ($discard = $children.add({
710 - 'id': "object:$objectId",
819 + #set ($isOpened = false)
820 + #set ($docNodeId = "object:$objectId")
821 + #computeIsOpened($docNodeId $isOpened)
822 + #set ($discard = $siblings.add({
823 + 'id': $docNodeId,
711 711   'text': "[$object.number]",
712 712   'icon': 'fa fa-cube',
713 713   'children': true,
... ... @@ -716,6 +716,9 @@
716 716   'type': 'object',
717 717   'validChildren': ['objectProperty'],
718 718   'canDelete': $services.security.authorization.hasAccess('edit', $objectReference.parent)
832 + },
833 + 'state': {
834 + 'opened': $isOpened
719 719   }
720 720   }))
721 721  #end
... ... @@ -740,8 +740,11 @@
740 740   #end
741 741   #set ($objectPropertyReference = $services.model.createEntityReference($property.name, 'OBJECT_PROPERTY', $objRef))
742 742   #set ($objectPropertyId = $services.model.serialize($objectPropertyReference, 'default'))
859 + #set ($isOpened = false)
860 + #set ($docNodeId = "objectProperty:$objectPropertyId")
861 + #computeIsOpened($docNodeId $isOpened)
743 743   #set ($discard = $siblings.add({
744 - 'id': "objectProperty:$objectPropertyId",
863 + 'id': $docNodeId,
745 745   'text': $property.name,
746 746   'icon': "fa fa-$icon",
747 747   'children': false,
... ... @@ -749,6 +749,9 @@
749 749   'id': $objectPropertyId,
750 750   'type': 'objectProperty',
751 751   'validChildren': []
871 + },
872 + 'state': {
873 + 'opened': $isOpened
752 752   }
753 753   }))
754 754  #end
... ... @@ -1192,6 +1192,8 @@
1192 1192  #end
1193 1193  
1194 1194  #macro (addCommonDocTreeSolrParams $params)
1317 + ## Enable prefix matching, besides standard language-dependent matching.
1318 + #set ($discard = $params.add('q=__INPUT__ __INPUT__*'))
1195 1195   #if ($rootType == 'wiki')
1196 1196   ## Limit the search to the specified wiki.
1197 1197   #addWikiLocationSolrParams($rootReference $params)