Wiki source code of Migration details

Last modified by Eleni Cojocariu on 2026/10/12 15:46

Show last authors
1 One row per legacy page of the tree, with what it was converted into. The numbers on [[Migration progress>>XWikiOrg.documentation-scripts-queries.migration-progress.WebHome]] are these same queries counted instead of listed.
2
3 {{velocity}}
4 #set ($audiences = [])
5 #set ($discard = $audiences.add({'key': 'user', 'label': 'User', 'tree': 'Documentation.UserGuide'}))
6 #set ($discard = $audiences.add({'key': 'admin', 'label': 'Admin', 'tree': 'Documentation.AdminGuide'}))
7 #set ($discard = $audiences.add({'key': 'dev', 'label': 'Developer', 'tree': 'Documentation.DevGuide'}))
8 ## 'audience' is what the switcher below is labelled and what the keys are named. 'tree' is the
9 ## parameter this page used until 2026-10-02, kept as a fallback so an old bookmark still opens the
10 ## guide it named instead of silently falling through to the default one.
11 #set ($requested = "$!request.get('audience')")
12 #if ($requested == '')
13 #set ($requested = "$!request.get('tree')")
14 #end
15 #set ($audience = '')
16 #foreach ($candidate in $audiences)
17 #if ($candidate.key == $requested)
18 #set ($audience = $candidate)
19 #end
20 #end
21 #if ($audience == '')
22 #set ($audience = $audiences.get(0))
23 #end
24 #set ($links = [])
25 #foreach ($candidate in $audiences)
26 #if ($candidate.key == $audience.key)
27 #set ($discard = $links.add("**$candidate.label**"))
28 #else
29 #set ($url = $doc.getURL('view', "audience=$candidate.key"))
30 #set ($discard = $links.add("[[$candidate.label>>path:$url]]"))
31 #end
32 #end
33 Audience: $stringtool.join($links, ' | ')
34
35 = $audience.label guide =
36
37 #set ($Q = '"')
38 #set ($mappingClass = 'XWikiOrg.documentation-scripts-queries.MigratedPageClass')
39 #set ($redirectClass = 'XWiki.RedirectClass')
40 #set ($base = "type:DOCUMENT AND wiki:xwiki AND hidden:false AND space_prefix:${Q}${audience.tree}${Q} AND -name:WebPreferences")
41 #set ($query = $services.query.createQuery($base, 'solr'))
42 #set ($discard = $query.setLimit(1000))
43 #set ($discard = $query.bindValue('sort', 'fullname asc'))
44 #set ($rows = $query.execute().get(0).results)
45 ## The same test as the Done column of the summary page, so the two can never disagree.
46 #set ($query = $services.query.createQuery("${base} AND property.XWiki.TagClass.tags:done", 'solr'))
47 #set ($discard = $query.setLimit(1000))
48 #set ($doneRefs = [])
49 #foreach ($row in $query.execute().get(0).results)
50 #set ($discard = $doneRefs.add($row.get('fullname')))
51 #end
52 ## Unconvertable pages are counted the same way, and by the same test as the summary page's column:
53 ## the page documents something deprecated, so it is leaving the tree without being converted.
54 #set ($query = $services.query.createQuery("${base} AND property.XWiki.TagClass.tags:unconvertable", 'solr'))
55 #set ($discard = $query.setLimit(1000))
56 #set ($unconvertableRefs = [])
57 #foreach ($row in $query.execute().get(0).results)
58 #set ($discard = $unconvertableRefs.add($row.get('fullname')))
59 #end
60 #set ($redirectCount = 0)
61 #set ($backlinkedCount = 0)
62 ## Distinct replacement pages of the whole tree: several legacy pages often converge on the
63 ## same new page, so this is a count of labels already seen, not a sum of the rows.
64 #set ($allTargets = [])
65 (% class="table" %)
66 |=Legacy page|=Done|=Unconvertable|=Converted into|=Redirects to|=Still has backlinks
67 #foreach ($row in $rows)
68 #set ($fullName = $row.get('fullname'))
69 #set ($title = "$!row.get('title_')")
70 #if ($title == '')
71 #set ($title = "$!row.get('name')")
72 #end
73 #set ($classes = $row.get('class'))
74 #set ($newPages = '')
75 #set ($redirect = '')
76 #if ($classes && ($classes.contains($mappingClass) || $classes.contains($redirectClass)))
77 #set ($legacyDoc = $xwiki.getDocument($fullName))
78 #set ($mapping = $legacyDoc.getObject($mappingClass))
79 #if ($mapping)
80 #set ($newPages = "$!mapping.getValue('newPages')")
81 #end
82 #set ($redirectObject = $legacyDoc.getObject($redirectClass))
83 #if ($redirectObject)
84 #set ($redirect = "$!redirectObject.getValue('location')")
85 #end
86 #end
87 #if ($doneRefs.contains($fullName))
88 #set ($doneCell = '✅')
89 #else
90 #set ($doneCell = '❌')
91 #end
92 #if ($unconvertableRefs.contains($fullName))
93 #set ($unconvertableCell = '✅')
94 #else
95 #set ($unconvertableCell = '❌')
96 #end
97 #set ($targets = [])
98 #set ($targetLabels = [])
99 #foreach ($line in $newPages.split('[\r\n]+'))
100 ## The field holds one wiki link per line, so that moving a replacement page rewrites it: the
101 ## rename job only follows links, and a bare reference it cannot see goes stale silently. Values
102 ## written before that change are still bare, hence unwrapping rather than parsing a link.
103 #set ($target = $line.trim().replaceAll('^\[\[', '').replaceAll('\]\]$', ''))
104 #set ($target = $target.replaceAll('\|\|.*$', '').replaceAll('^.*>>', ''))
105 #set ($target = $target.replaceAll('^doc:', '').trim())
106 #if ($target != '')
107 #set ($label = $target.replaceAll('^xwiki:', '').replaceAll('\.WebHome$', ''))
108 #set ($discard = $targetLabels.add($label))
109 #set ($discard = $targets.add("[[$label>>doc:$target]]"))
110 #if (!$allTargets.contains($label))
111 #set ($discard = $allTargets.add($label))
112 #end
113 #end
114 #end
115 ## A redirect names a replacement too, and it is the only one most legacy pages have: list it here
116 ## as well, unless the mapping object already records it.
117 #if ($redirect == '')
118 #set ($redirectCell = '—')
119 #else
120 #set ($redirectCount = $redirectCount + 1)
121 #set ($redirectLabel = $redirect.replaceAll('^xwiki:', '').replaceAll('\.WebHome$', ''))
122 #set ($redirectCell = "[[$redirectLabel>>doc:$redirect]]")
123 #if (!$targetLabels.contains($redirectLabel))
124 #set ($discard = $targets.add("[[$redirectLabel>>doc:$redirect]] //(redirect)//"))
125 #end
126 #if (!$allTargets.contains($redirectLabel))
127 #set ($discard = $allTargets.add($redirectLabel))
128 #end
129 #end
130 #if ($targets.isEmpty())
131 #set ($targetCell = '—')
132 #else
133 #set ($targetCell = $stringtool.join($targets, '\\'))
134 #end
135 ## What still points at the page, from the same index the Information tab reads -- and the same
136 ## answer: 63/63 and 48/48 on the two most linked pages, cross-wiki backlinks included (they are
137 ## a third of them here). It is also immune to the trailing-slash trap of that tab's URL, which
138 ## answers "no backlinks" for a terminal page. A page that already redirects needs no such check,
139 ## so it is not queried: this costs one lookup per remaining row, ~5 ms each.
140 #if ($redirect != '')
141 #set ($backlinkCell = '—')
142 #else
143 #set ($backlinks = $xwiki.getDocument($fullName).getBacklinks())
144 #if ($backlinks.isEmpty())
145 #set ($backlinkCell = '❌')
146 #else
147 #set ($backlinkedCount = $backlinkedCount + 1)
148 #set ($backlinkURL = $xwiki.getURL($fullName, 'view', 'viewer=information'))
149 #set ($backlinkCell = "[[✅ $backlinks.size()>>path:$backlinkURL]]")
150 #end
151 #end
152 |[[$title>>doc:$fullName]]|$doneCell|$unconvertableCell|$targetCell|$redirectCell|$backlinkCell
153 #end
154 |=**$rows.size() pages**|=**$doneRefs.size() done**|=**$unconvertableRefs.size() unconvertable**|=**$allTargets.size() new pages**|=**$redirectCount redirects**|=**$backlinkedCount still linked**
155 {{/velocity}}
156
157 A page counts as **done** when it carries the ##done## tag, and **unconvertable** when it carries the ##unconvertable## tag: that page documents something deprecated, so its content has no place in the new documentation and it will be neither converted nor mapped. Either tag takes the page out of the //Left// column of [[Migration progress>>XWikiOrg.documentation-scripts-queries.migration-progress.WebHome]]. //Converted into// is the ##newPages## field of its [[MigratedPageClass>>XWikiOrg.documentation-scripts-queries.MigratedPageClass]] object, so it stays empty until someone records where the content went. The field holds one wiki link per line: moving a replacement page rewrites that link like any other, so an entry follows its page instead of going stale. The total under //Converted into// counts the **distinct** replacement pages of the whole tree, so it is smaller than the sum of the rows whenever several legacy pages were merged into one new page. //Redirects to// is the ##location## of an ##XWiki.RedirectClass## object: such a page already sends its readers elsewhere, whether or not anyone marked it as done. //Still has backlinks// is the number of pages that link to this one, from the same index the page's own //Information// tab reads, so the two always agree - ✅ means there is still something to repoint, and the number links to the list. Pages that already redirect are not checked, since a redirect sends every one of those readers on; they show a dash. Backlinks from the other wikis of the farm are included, and they are a large share of them - of the 63 pointing at //Page Editing//, 9 come from extensions.xwiki.org, dev.xwiki.org and design.xwiki.org. What this index cannot see is a link written as an absolute URL (##~[~[...>>url:https:~/~/www.xwiki.org/...]]##); those need a separate search of the page content.

Get Connected