Wiki source code of Default Class Sheet
Last modified by superadmin on 2019/11/08 17:58
Hide last authors
author | version | line-number | content |
---|---|---|---|
1.1 | 1 | {{template name="locationPicker_macros.vm" /}} | |
2 | |||
3 | {{velocity}} | ||
4 | ## This document can be copied in order to be customized so we cannot rely on its name to determine if the currently | ||
5 | ## displayed document is a class or the class sheet itself. We look for the sheet descriptor instead. | ||
6 | #set ($isSheet = $doc.getObject('XWiki.SheetDescriptorClass')) | ||
7 | #if ($isSheet) | ||
8 | ## Viewing the sheet document itself. | ||
9 | {{translation key="platform.xclass.defaultClassSheet.description"/}} | ||
10 | #elseif ("$!request.bindSheet" != '' && $hasEdit) | ||
11 | #if ($services.csrf.isTokenValid($request.getParameter('form_token'))) | ||
12 | ## Bind the sheet to the class. | ||
13 | #set ($classSheetReference = $services.model.resolveDocument($request.bindSheet)) | ||
14 | #if ($services.sheet.bindClassSheet($doc, $classSheetReference)) | ||
15 | $doc.save($services.localization.render('platform.xclass.defaultClassSheet.sheets.bind')) | ||
16 | #end | ||
17 | $response.sendRedirect($request.xredirect) | ||
18 | #else | ||
19 | $response.sendRedirect($services.csrf.getResubmissionURL()) | ||
20 | #end | ||
21 | ## Stop processing, since we already sent a redirect. | ||
22 | #stop | ||
23 | #elseif("$!request.docName" != '') | ||
24 | ## Request for creating a new instance. | ||
25 | ## We don't actually create a new instance here, we just redirect to the edit mode. | ||
26 | #set ($targetSpaceRef = $services.model.resolveSpace($request.spaceName)) | ||
27 | #set ($targetDocRef = $services.model.createDocumentReference($request.docName, $targetSpaceRef)) | ||
28 | #if (!$xwiki.exists($targetDocRef) && $services.security.authorization.hasAccess('edit', $targetDocRef)) | ||
29 | ## Compute the default edit mode to ensure backward compatibility with documents that are still using the deprecated | ||
30 | ## inline action. | ||
31 | #set ($editAction = $xwiki.getDocument($request.template).getDefaultEditMode()) | ||
32 | $response.sendRedirect($xwiki.getURL($targetDocRef, $editAction, $escapetool.url({ | ||
33 | 'template': $request.template, | ||
34 | 'parent': $request.parent, | ||
35 | 'title': $request.docName | ||
36 | }))) | ||
37 | ## Stop processing, since we already sent a redirect. | ||
38 | #stop | ||
39 | #end | ||
40 | #end | ||
41 | {{/velocity}} | ||
42 | |||
43 | {{velocity}} | ||
44 | ## If this sheet is explicitly bound to the displayed class then print the class document content before the | ||
45 | ## sheet output. Class authors can put the description of the class in the class document content. | ||
46 | #set($classSheetReference = $services.model.createDocumentReference($doc.wiki, 'XWiki', 'ClassSheet')) | ||
47 | #if($services.sheet.getDocumentSheets($doc).contains($classSheetReference)) | ||
48 | {{include reference="" /}} | ||
49 | #end | ||
50 | {{/velocity}} | ||
51 | |||
52 | {{velocity}} | ||
53 | #if (!$isSheet) | ||
54 | #set ($className = $doc.pageReference.name) | ||
55 | #set ($className = $stringtool.removeEnd($className, 'Class')) | ||
56 | ## Determine the class sheets. | ||
57 | #set ($classSheetReferences = $services.sheet.getClassSheets($doc)) | ||
58 | #if ($classSheetReferences.isEmpty()) | ||
59 | ## There is no class sheet explicitly bound to this class. Fall-back on naming convention. | ||
60 | ## Before XWiki 2.0, the default class sheet was suffixed with "ClassSheet". Since 2.0, the suffix is just "Sheet". | ||
61 | #set ($defaultClassSheetReference = $services.model.createDocumentReference("${className}ClassSheet", | ||
62 | $doc.documentReference.parent)) | ||
63 | #if (!$xwiki.exists($defaultClassSheetReference)) | ||
64 | #set ($defaultClassSheetReference = $services.model.createDocumentReference("${className}Sheet", | ||
65 | $doc.documentReference.parent)) | ||
66 | #end | ||
67 | #end | ||
68 | ## Determine the template using naming convention. | ||
69 | ## Before XWiki 2.0, the default class template was suffixed with "ClassTemplate". | ||
70 | ## Since 2.0, the suffix is just "Template". | ||
71 | #set ($classTemplateReference = $services.model.createDocumentReference("${className}ClassTemplate", | ||
72 | $doc.documentReference.parent)) | ||
73 | #if (!$xwiki.exists($classTemplateReference)) | ||
74 | #set ($classTemplateReference = $services.model.createDocumentReference("${className}Template", | ||
75 | $doc.documentReference.parent)) | ||
76 | #end | ||
77 | ## Determine the template provider using naming convention. | ||
78 | #set ($classTemplateProviderReference = $services.model.createDocumentReference("${className}TemplateProvider", | ||
79 | $doc.documentReference.parent)) | ||
80 | #set ($classTemplateProviderDoc = $xwiki.getDocument($classTemplateProviderReference)) | ||
81 | #set ($hasClassTemplateProvider = !$classTemplateProviderDoc.isNew()) | ||
82 | #set($classTemplateDoc = $xwiki.getDocument($classTemplateReference)) | ||
83 | #set($hasClassSheets = !$classSheetReferences.isEmpty() || $xwiki.exists($defaultClassSheetReference)) | ||
84 | #set($hasClassTemplate = !$classTemplateDoc.isNew()) | ||
85 | #if(!$defaultSpace) | ||
86 | #set($defaultSpace = $doc.space) | ||
87 | #end | ||
88 | #if(!$defaultParent) | ||
89 | #set($defaultParent = ${doc.fullName}) | ||
90 | #end | ||
91 | |||
92 | #set ($classEditorURL = $doc.getURL('edit', 'editor=class')) | ||
93 | #if($doc.getxWikiClass().properties.size() == 0) | ||
94 | {{warning}}$services.localization.render('platform.xclass.defaultClassSheet.properties.empty', [ | ||
95 | "{{html}}<a href='$classEditorURL'>", | ||
96 | '</a>{{/html}}' | ||
97 | ]){{/warning}} | ||
98 | #else | ||
99 | (% id="HClassProperties" %) | ||
100 | = {{translation key="platform.xclass.defaultClassSheet.properties.heading"/}} = | ||
101 | #foreach($property in $doc.getxWikiClass().properties) | ||
102 | * $services.rendering.escape("$property.prettyName ($property.name: $xwiki.metaclass.get($property.classType).prettyName)", $xwiki.currentContentSyntaxId) | ||
103 | #end | ||
104 | * //$services.localization.render('platform.xclass.defaultClassSheet.properties.edit', [ | ||
105 | "{{html}}<a href='$classEditorURL'>", | ||
106 | '</a>{{/html}}' | ||
107 | ])// | ||
108 | |||
109 | #end | ||
110 | #if ($hasClassSheets && $hasClassTemplate) | ||
111 | (% id="HCreatePage" %) | ||
112 | = {{translation key="platform.xclass.defaultClassSheet.createPage.heading"/}} = | ||
113 | #if("$!targetDocRef" != '' && $xwiki.exists($targetDocRef)) | ||
114 | |||
115 | {{warning}}$services.localization.render('platform.xclass.defaultClassSheet.createPage.pageAlreadyExists', [ | ||
116 | '[[', | ||
117 | ">>$services.model.serialize($targetDocRef)]]" | ||
118 | ]){{/warning}} | ||
119 | #elseif("$!targetDocRef" != '') | ||
120 | |||
121 | {{warning}}{{translation key="platform.xclass.defaultClassSheet.createPage.denied"/}}{{/warning}} | ||
122 | #end | ||
123 | |||
124 | {{html}} | ||
125 | <form action="$doc.getURL()" id="newdoc" method="post" class="xform half"> | ||
126 | <div class="hidden"> | ||
127 | <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> | ||
128 | <input type="hidden" name="parent" value="${defaultParent}"/> | ||
129 | <input type="hidden" name="template" value="${classTemplateDoc}"/> | ||
130 | <input type="hidden" name="sheet" value="1"/> | ||
131 | </div> | ||
132 | #locationPicker({ | ||
133 | 'id': 'target', | ||
134 | 'title': { | ||
135 | 'label': 'core.create.title', | ||
136 | 'hint': 'core.create.title.hint', | ||
137 | 'name': 'docTitle', | ||
138 | 'placeholder': 'core.create.name.placeholder' | ||
139 | }, | ||
140 | 'preview': { | ||
141 | 'label': 'core.create.locationPreview.label', | ||
142 | 'hint': 'core.create.locationPreview.hint' | ||
143 | }, | ||
144 | 'parent': { | ||
145 | 'label': 'core.create.spaceReference.label', | ||
146 | 'hint': 'core.create.spaceReference.hint', | ||
147 | 'name': 'spaceName', | ||
148 | 'reference': $services.model.resolveSpace($defaultSpace), | ||
149 | 'placeholder': 'core.create.spaceReference.placeholder' | ||
150 | }, | ||
151 | 'name': { | ||
152 | 'label': 'core.create.name.label', | ||
153 | 'hint': 'core.create.name.hint', | ||
154 | 'name': 'docName', | ||
155 | 'placeholder': 'core.create.name.placeholder' | ||
156 | } | ||
157 | }) | ||
158 | <p> | ||
159 | <span class="buttonwrapper"> | ||
160 | <input type="submit" class="button" value="$escapetool.xml($services.localization.render( | ||
161 | 'platform.xclass.defaultClassSheet.createPage.label'))"/> | ||
162 | </span> | ||
163 | </p> | ||
164 | </form> | ||
165 | {{/html}} | ||
166 | |||
167 | #end## has class sheet and class template | ||
168 | (% id="HExistingPages" %) | ||
169 | = {{translation key="platform.xclass.defaultClassSheet.pages.heading"/}} = | ||
170 | |||
171 | {{translation key="platform.xclass.defaultClassSheet.pages.description"/}} | ||
172 | |||
173 | {{html}} | ||
174 | #set ($columns = ['doc.title', 'doc.location', 'doc.date', 'doc.author', 'doc.objectCount', '_actions']) | ||
175 | #set ($columnsProperties = { | ||
176 | 'doc.title': {'link': 'view'}, | ||
177 | 'doc.location': {'html': true}, | ||
178 | 'doc.author': {'link': 'author'}, | ||
179 | 'doc.objectCount': {'type': 'numeric', 'filterable': false, 'sortable': false}, | ||
180 | '_actions': {'sortable': false, 'filterable': false, 'html': true, 'actions': ['edit', 'delete']} | ||
181 | }) | ||
182 | #set ($options = { | ||
183 | 'className': $doc.fullName, | ||
184 | 'translationPrefix' : 'platform.index.', | ||
185 | 'rowCount': 10, | ||
186 | 'outputOnlyHtml': true, | ||
187 | 'queryFilters': ['unique'] | ||
188 | }) | ||
189 | #livetable("classEntries" $columns $columnsProperties $options) | ||
190 | {{/html}} | ||
191 | |||
192 | (% id="HClassSheets" %) | ||
193 | = {{translation key="platform.xclass.defaultClassSheet.sheets.heading"/}} = | ||
194 | #if (!$hasClassSheets || !$hasClassTemplate) | ||
195 | |||
196 | {{translation key="platform.xclass.defaultClassSheet.sheets.missing"/}} | ||
197 | #end | ||
198 | |||
199 | {{info}}$services.localization.render('platform.xclass.defaultClassSheet.sheets.description', ['//', '//']){{/info}} | ||
200 | |||
201 | #if(!$hasClassSheets) | ||
202 | {{html}} | ||
203 | <form action="$xwiki.getURL($defaultClassSheetReference, 'save', 'editor=wiki')" method="post"> | ||
204 | <div> | ||
205 | <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> | ||
206 | <input type="hidden" name="parent" value="${doc.fullName}"/> | ||
207 | <input type="hidden" name="xredirect" value="${doc.URL}"/> | ||
208 | #set ($sheetContent = $xwiki.getDocument('XWiki.ObjectSheet').getContent().replace('XWiki.MyClass', | ||
209 | $doc.fullName)) | ||
210 | ## We have to encode the new line characters in order to preserve them, otherwise they are replace with a | ||
211 | ## space when the HTML is cleaned. | ||
212 | ## FIXME: Use a dedicated escape tool method when XCOMMONS-405 is implemented. | ||
213 | #set ($sheetContent = $escapetool.xml($sheetContent).replaceAll("\n", ' ')) | ||
214 | <input type="hidden" name="content" value="$sheetContent"/> | ||
215 | <input type="hidden" name="title" value="${escapetool.h}if(${escapetool.d}doc.documentReference.name == '$escapetool.xml($defaultClassSheetReference.name)')$escapetool.xml($className) Sheet${escapetool.h}{else}${escapetool.d}services.display.title(${escapetool.d}doc, {'displayerHint': 'default', 'outputSyntaxId': 'plain/1.0'})${escapetool.h}end"/> | ||
216 | <span class="buttonwrapper"><input type="submit" class="button" value="$escapetool.xml( | ||
217 | $services.localization.render('platform.xclass.defaultClassSheet.sheets.create'))"/></span> | ||
218 | </div> | ||
219 | </form> | ||
220 | {{/html}} | ||
221 | #else | ||
222 | #set($defaultClassSheetDoc = $xwiki.getDocument($defaultClassSheetReference)) | ||
223 | #if($classSheetReferences.isEmpty() && !$defaultClassSheetDoc.getObject('XWiki.SheetClass')) | ||
224 | ## The sheet is not bound to the class. | ||
225 | #set($xredirect = $xwiki.relativeRequestURL) | ||
226 | #set($defaultClassSheetStringReference = $services.model.serialize($defaultClassSheetReference, "default")) | ||
227 | #set($bindURL = $doc.getURL('view', "bindSheet=${escapetool.url($defaultClassSheetStringReference)}&xredirect=${escapetool.url($xredirect)}&form_token=$!{services.csrf.getToken()}")) | ||
228 | {{warning}} | ||
229 | {{translation key="platform.xclass.defaultClassSheet.sheets.notBound"/}} ## | ||
230 | #if ($hasEdit) | ||
231 | {{html}} | ||
232 | <a href="$bindURL">$services.localization.render('platform.xclass.defaultClassSheet.sheets.bind') »</a>. | ||
233 | {{/html}} | ||
234 | #end | ||
235 | {{/warning}} | ||
236 | |||
237 | #end | ||
238 | #if ($classSheetReferences.size() < 2) | ||
239 | #set($classSheetDoc = $defaultClassSheetDoc) | ||
240 | #if(!$classSheetReferences.isEmpty()) | ||
241 | #set($classSheetDoc = $xwiki.getDocument($classSheetReferences.get(0))) | ||
242 | #end | ||
243 | #set ($sheetPath = "#hierarchy($classSheetDoc.documentReference, {'plain': true, 'local': true, 'limit': 4})") | ||
244 | [[$services.localization.render('platform.xclass.defaultClassSheet.sheets.view', [$sheetPath.trim()]) »>>${classSheetDoc.fullName}]] | ||
245 | #else | ||
246 | {{translation key="platform.xclass.defaultClassSheet.sheets.list"/}} | ||
247 | |||
248 | #foreach($classSheetReference in $classSheetReferences) | ||
249 | * [[$services.model.serialize($classSheetReference, "default")]] | ||
250 | #end | ||
251 | #end | ||
252 | #end | ||
253 | |||
254 | (% id="HClassTemplate" %) | ||
255 | = {{translation key="platform.xclass.defaultClassSheet.template.heading"/}} = | ||
256 | |||
257 | {{info}}$services.localization.render('platform.xclass.defaultClassSheet.template.description', | ||
258 | ['//', '//']){{/info}} | ||
259 | |||
260 | #if (!$hasClassTemplate) | ||
261 | {{html}} | ||
262 | <form action="$classTemplateDoc.getURL('save', 'editor=wiki')" method="post"> | ||
263 | <div> | ||
264 | <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> | ||
265 | <input type="hidden" name="parent" value="${doc.fullName}"/> | ||
266 | <input type="hidden" name="xredirect" value="${doc.URL}"/> | ||
267 | <input type="hidden" name="title" value="$className Template"/> | ||
268 | <span class="buttonwrapper"><input type="submit" class="button" value="$escapetool.xml( | ||
269 | $services.localization.render('platform.xclass.defaultClassSheet.template.create'))"/></span> | ||
270 | </div> | ||
271 | </form> | ||
272 | {{/html}} | ||
273 | #else | ||
274 | #if(!$classTemplateDoc.getObject(${doc.fullName})) | ||
275 | #set($xredirect = $xwiki.relativeRequestURL) | ||
276 | #set($createUrl = $classTemplateDoc.getURL('objectadd', "classname=${escapetool.url($doc.fullName)}&xredirect=${escapetool.url($xredirect)}&form_token=$!{services.csrf.getToken()}")) | ||
277 | {{warning}} | ||
278 | $services.localization.render('platform.xclass.defaultClassSheet.template.missingObject', ["//$className//"]) ## | ||
279 | {{html}}<a href="$createUrl">$escapetool.xml($services.localization.render( | ||
280 | 'platform.xclass.defaultClassSheet.template.addObject', [$className])) »</a>.{{/html}} | ||
281 | {{/warning}} | ||
282 | |||
283 | #end | ||
284 | #set ($templatePath = "#hierarchy($classTemplateDoc.documentReference, {'plain': true, 'local': true, 'limit': 4})") | ||
285 | [[$services.localization.render('platform.xclass.defaultClassSheet.template.view', | ||
286 | [$templatePath.trim()]) »>>${classTemplateDoc.fullName}]] | ||
287 | #end | ||
288 | ## Create a template provider only if a template for the current class exists. | ||
289 | #if ($classTemplateDoc.getObject(${doc.fullName})) | ||
290 | (% id="HClassTemplateProvider" %) | ||
291 | = {{translation key="platform.xclass.defaultClassSheet.templateProvider.heading"/}} = | ||
292 | |||
293 | {{info}}$services.localization.render('platform.xclass.defaultClassSheet.templateProvider.description', | ||
294 | ['//']){{/info}} | ||
295 | |||
296 | #if (!$hasClassTemplateProvider) | ||
297 | #set ($templateProviderClassName = 'XWiki.TemplateProviderClass') | ||
298 | ## Do the page creation and object addition in one step, providing some default values. | ||
299 | ## In order to get the root space of the class and use it as restrictionSpace, we need to be sure that we have | ||
300 | ## the expected result for multiple level hierarchies, like MyApplication.Code.MyApplicationClass. In this case, | ||
301 | ## the template provider in enabled in MyApplication space. | ||
302 | #set ($restrictionSpace = $doc.documentReference.spaceReferences.get(0).name) | ||
303 | #set ($createUrlQueryString = $escapetool.url({ | ||
304 | 'classname': $templateProviderClassName, | ||
305 | 'xredirect': $xwiki.relativeRequestURL, | ||
306 | 'form_token': $services.csrf.token, | ||
307 | "${templateProviderClassName}_name": $className, | ||
308 | "${templateProviderClassName}_description": | ||
309 | $services.localization.render('platform.xclass.templateProvider.defaultDescription', [$className]), | ||
310 | "${templateProviderClassName}_template": $classTemplateDoc, | ||
311 | "${templateProviderClassName}_visibilityRestrictions": $restrictionSpace})) | ||
312 | #set ($createUrl = $classTemplateProviderDoc.getURL('objectadd', $createUrlQueryString)) | ||
313 | {{html}} | ||
314 | <form action="$classTemplateProviderDoc.getURL('save', 'editor=wiki')" method="post"> | ||
315 | <div> | ||
316 | <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> | ||
317 | <input type="hidden" name="parent" value="${doc.fullName}"/> | ||
318 | <input type="hidden" name="xredirect" value="$createUrl"/> | ||
319 | <input type="hidden" name="title" value="$className Template Provider"/> | ||
320 | <span class="buttonwrapper"><input type="submit" class="button" value="$escapetool.xml( | ||
321 | $services.localization.render('platform.xclass.defaultClassSheet.templateProvider.create'))"/></span> | ||
322 | </div> | ||
323 | </form> | ||
324 | {{/html}} | ||
325 | #else | ||
326 | #set ($templateProviderPath = "#hierarchy($classTemplateProviderDoc.documentReference, {'plain': true, 'local': true, 'limit': 4})") | ||
327 | [[$services.localization.render('platform.xclass.defaultClassSheet.templateProvider.view', | ||
328 | [$templateProviderPath.trim()]) »>>${classTemplateProviderDoc.fullName}]] | ||
329 | #end | ||
330 | #end | ||
331 | |||
332 | #end## !$isSheet | ||
333 | {{/velocity}} |