General Actions:
Log-in
Register
Wiki:
Main wiki
▼
:
Document Index
»
Space:
AppWithinMinutes
▼
:
Document Index
»
Page:
ClassEditSheet
Search
default
Page Actions:
Export
▼
:
Export as PDF
Export as RTF
Export as HTML
More actions
▼
:
Print preview
View Source
Main wiki
»
App Within Minutes
»
ClassEditSheet
Wiki source code of
ClassEditSheet
Last modified by
Administrator
on 2012/03/21 17:41
Content
·
Comments
(0)
·
Annotations
(0)
·
Attachments
(3)
·
History
·
Information
Hide line numbers
1: {{groovy}} 2: import com.xpn.xwiki.XWikiContext; 3: import com.xpn.xwiki.api.Context; 4: import com.xpn.xwiki.api.Object; 5: import com.xpn.xwiki.api.PropertyClass; 6: import com.xpn.xwiki.doc.XWikiDocument; 7: import com.xpn.xwiki.objects.BaseObject; 8: 9: /** 10: * Used to preview class fields that have a custom display associated, before they are actually added/saved to the 11: * class. For instance, when the user drags a Date field from the palette to the field canvas the class editor needs to 12: * display that Date field as if the user would be editing an object with this Date field in "Inline form" edit mode. 13: * This means that if the Date field has a custom display, the custom display should be used (e.g. using a Date picker). 14: */ 15: class PropertyCustomDisplayer 16: { 17: private XWikiContext context; 18: 19: public PropertyCustomDisplayer(Context context) 20: { 21: this.context = context.getContext(); 22: } 23: 24: public String display(PropertyClass property, String prefix, com.xpn.xwiki.api.Object object) 25: { 26: HashMap<String, Object> backup = new HashMap<String, Object>(); 27: try { 28: XWikiDocument.backupContext(backup, this.context); 29: return this.displayInternal(property.getPropertyClass(), prefix, object.getXWikiObject()); 30: } finally { 31: XWikiDocument.restoreContext(backup, this.context); 32: } 33: } 34: 35: private String displayInternal(com.xpn.xwiki.objects.classes.PropertyClass property, String prefix, BaseObject object) 36: { 37: StringBuffer result = new StringBuffer(); 38: property.displayCustom(result, property.getName(), prefix, "edit", object, this.context); 39: return result.toString(); 40: } 41: } 42: xcontext.put('propertyCustomDisplayer', new PropertyCustomDisplayer(xcontext)) 43: {{/groovy}} 44: 45: {{velocity output="false"}} 46: #** 47: * Displays the field palette. 48: *# 49: #macro(displayFieldPalette) 50: (% id="palette" %) 51: ((( 52: **$msg.get('platform.appwithinminutes.classEditorPaletteTitle')** 53: 54: (% class="xHint" %) 55: $msg.get('platform.appwithinminutes.classEditorPaletteHint') 56: 57: ## List all form field types, grouped by category. 58: #set($formFieldDocs = []) 59: #set($formFieldClassName = 'AppWithinMinutes.FormFieldClass') 60: #set($categoryListStatement = 'from doc.object(AppWithinMinutes.FormFieldCategoryClass) as category order by category.priority') 61: #foreach($category in $services.query.xwql($categoryListStatement).execute()) 62: #set($categoryDoc = $xwiki.getDocument($category)) 63: * (% class="category" %)$categoryDoc.plainTitle 64: #set($formFieldsForCategoryStatement = "from doc.object($formFieldClassName) as field where field.category = :category order by field.priority") 65: #set($formFieldsForCategoryQuery = $services.query.xwql($formFieldsForCategoryStatement).bindValue('category', $category)) 66: #foreach($formField in $formFieldsForCategoryQuery.execute()) 67: #set($formFieldDoc = $xwiki.getDocument($formField)) 68: #set($discard = $formFieldDocs.add($formFieldDoc)) 69: #set($formFieldIcon = $formFieldDoc.getObject($formFieldClassName).getProperty('icon').value) 70: #if($formFieldIcon.contains('/')) 71: #set($formFieldIconURL = $xwiki.getSkinFile($formFieldIcon)) 72: #else 73: #set($formFieldIconURL = $formFieldDoc.getAttachmentURL($formFieldIcon)) 74: #end 75: ** (% class="field" %){{html}} 76: <img src="$formFieldIconURL" alt="$escapetool.xml($formFieldDoc.title)" class="icon" /> 77: $escapetool.xml($formFieldDoc.plainTitle) 78: ## FIXME: We should use the 'get' action instead to prevent the stats module from recording this AJAX request. 79: ## The 'edit' action is a temporary solution until the sheet module is modified to allow a sheet to be enforced through 80: ## the query string even if it doesn't match the action (e.g. the 'get' action). 81: ## The sheet parameter is required when editing a new class because the request will be made to a document that doesn't exist. 82: <input type="hidden" value="$doc.getURL('edit', "xpage=plain&sheet=AppWithinMinutes.ClassEditSheet&field=$escapetool.url($formFieldDoc.fullName)")" class="data"/> 83: {{/html}} 84: #end 85: #end 86: ))) 87: #end 88: 89: #** 90: * Displays the field canvas. 91: *# 92: #macro(displayFieldCanvas) 93: #set($propertyType2FormField = {}) 94: #foreach($formFieldDoc in $formFieldDocs) 95: ## Use the type of the field template. 96: #set($type = $formFieldDoc.getxWikiClass().properties.get(0).classType) 97: #set($discard = $propertyType2FormField.put($type, $formFieldDoc)) 98: #end 99: (% id="canvas" %) 100: ((( 101: (% class="hint" %) 102: $msg.get('platform.appwithinminutes.classEditorCanvasHint') 103: 104: #set($unknownFields = []) 105: #set($empty = true) 106: #foreach ($field in $doc.getxWikiClass().properties) 107: #set($formFieldDoc = $propertyType2FormField.get($field.classType)) 108: #if($formFieldDoc) 109: #set($empty = false) 110: * (((#displayField($field $formFieldDoc)))) 111: #else 112: #set($discard = $unknownFields.add($field)) 113: #end 114: #end 115: #if(!$empty) 116: ## Leave an empty line to separate the blocks. 117: 118: #end 119: ## 120: (% class="hidden" %) 121: {{html}} 122: ## Output the field meta data even if the field is not supported to preserve it when the class is saved. 123: #foreach($field in $unknownFields) 124: #displayFieldMetaData($field) 125: #end 126: {{/html}} 127: ))) 128: #end 129: 130: #** 131: * Display the options to create/update the class template and the class sheet. 132: *# 133: #macro(displayClassOptions) 134: #set($className = $doc.name) 135: #if($className.endsWith('Class')) 136: #set($className = $className.substring(0, $mathtool.sub($className.length(), 5))) 137: #end 138: #set($templateName = "${className}Template") 139: #set($classSheets = $services.sheet.getClassSheets($doc)) 140: #if($classSheets.isEmpty()) 141: #set($sheetName = "${className}Sheet") 142: #elseif($classSheets.size() == 1) 143: #set($sheetName = $services.model.serialize($classSheets.get(0))) 144: #end 145: {{html wiki="true"}} 146: ## Hide the options if neither the sheet nor the template exists. They don't have to be updated, they have to be created. 147: (% id="options" #if(!$xwiki.exists($sheetName) && !$xwiki.exists($templateName))class="hidden" #end%) 148: ; <label for="updateClassTemplate"><input type="checkbox" id="updateClassTemplate" name="updateClassTemplate" checked="checked" />$msg.get('platform.appwithinminutes.classEditorUpdateTemplateLabel')</label> 149: : (% class="xHint" %)$msg.get('platform.appwithinminutes.classEditorUpdateTemplateHint', "[[$templateName]]") 150: ; <label for="updateClassSheet"><input type="checkbox" id="updateClassSheet" name="updateClassSheet" #if($sheetName)checked="checked" #{else}disabled="disabled" #end/>$msg.get('platform.appwithinminutes.classEditorUpdateSheetLabel')</label> 151: : #if($sheetName) 152: (% class="xHint" %)$msg.get('platform.appwithinminutes.classEditorUpdateSheetHint', "[[$sheetName]]") 153: #else 154: (% class="warningmessage" %)$msg.get('platform.appwithinminutes.classEditorMultipleSheetsWarning') 155: #end 156: {{/html}} 157: #end 158: 159: #** 160: * Display a form field. 161: *# 162: #macro(displayField $field $formFieldDoc) 163: #if($formFieldDoc.getObject('XWiki.StyleSheetExtension')) 164: #set($discard = $xwiki.ssx.use($formFieldDoc.fullName)) 165: #end 166: #if($formFieldDoc.getObject('XWiki.JavaScriptExtension')) 167: #set($discard = $xwiki.jsx.use($formFieldDoc.fullName)) 168: #end 169: (% class="hidden" %) 170: {{html}} 171: #displayFieldMetaData($field) 172: ## We need this information to avoid querying and loading all FormField documents twice. 173: ## NOTE: We use a different ID format to avoid collisions with the field meta properties. 174: <input type="hidden" id="template-$field.name" name="template-$field.name" value="$escapetool.xml($formFieldDoc.fullName)" /> 175: {{/html}} 176: 177: #set($className = $doc.name) 178: #if($className.endsWith('Class')) 179: #set($className = $className.substring(0, $mathtool.sub($className.length(), 5))) 180: #end 181: #set($templateRef = $services.model.createDocumentReference($doc.wiki, $doc.space, "${className}Template")) 182: #set($templateDoc = $xwiki.getDocument($templateRef)) 183: ## Simulate the editing of the class instance from the template document. 184: ## Note that we can't simply call display on the template document because $field could be a new field that hasn't 185: ## been added to the class yet (so the object from the template doesn't have this field yet). 186: (% class="field-viewer" %) 187: #displayFieldProperty($field "${doc.fullName}_0_" $templateDoc.getObject($doc.fullName, true)) 188: 189: #set($propertyNames = ['name', 'prettyName', 'number', 'required', 'hint']) 190: #set($formFieldObj = $formFieldDoc.getObject('AppWithinMinutes.FormFieldClass')) 191: #set($customPropertyNames = $formFieldObj.getProperty('properties').value.split('\s+')) 192: #set($discard = $customPropertyNames.removeAll($propertyNames)) 193: #set($discard = $propertyNames.addAll($customPropertyNames.subList(0, $customPropertyNames.size()))) 194: (% class="field-config" %) 195: #foreach($propertyName in $propertyNames) 196: #set($propertyDefinition = $field.xWikiClass.get($propertyName)) 197: #if($propertyDefinition) 198: #displayFieldProperty($propertyDefinition "field-${field.name}_" $field) 199: #end 200: #end 201: #end 202: 203: #** 204: * Display the field meta data. This is needed to preserve the field when its type is not supported by the editor. 205: *# 206: #macro(displayFieldMetaData $field) 207: <input type="hidden" id="type-$field.name" name="type-$field.name" value="$field.classType" /> 208: #end 209: 210: #** 211: * Displays a configuration property of a class field. This macro can also be used to display a property of an object. 212: *# 213: #macro(displayFieldProperty $property $prefix $field) 214: #set($displayFormType = $property.getProperty('displayFormType')) 215: #if($property.type.indexOf('Boolean') != -1 && (!$displayFormType || $displayFormType.value == 'checkbox')) 216: ; {{html clean="false"}}<label for="$!{prefix}$property.name">#displayPropertyEditInput($property, $prefix, $field)$escapetool.xml($property.prettyName)</label>{{/html}} 217: #else 218: ; {{html}}<label for="${prefix}$property.name">$escapetool.xml($property.prettyName)</label>{{/html}} 219: : {{html clean="false"}}#displayPropertyEditInput($property, $prefix, $field){{/html}} 220: #end 221: #end 222: 223: #** 224: * Displays the input used to edit the specified property of the given object. The given object can be either an 225: * instance of an XWiki class or a class field. In the first case the property represents an object field and in the 226: * second case the property represents a field meta property. 227: *# 228: #macro(displayPropertyEditInput $property $prefix $object) 229: #set($wrappedProperty = $property.propertyClass) 230: #if("$!wrappedProperty.customDisplay" != '') 231: $xcontext.get('propertyCustomDisplayer').display($property, $prefix, $object) 232: #else 233: $doc.displayEdit($property, $prefix, $object) 234: #end 235: #end 236: 237: #** 238: * Called when a new form field is added via AJAX. 239: *# 240: #macro(displayNewField) 241: {{html}} 242: <!-- com.xpn.xwiki.plugin.skinx.JsSkinExtensionPlugin --> 243: <!-- com.xpn.xwiki.plugin.skinx.CssSkinExtensionPlugin --> 244: {{/html}} 245: 246: #set($formFieldDoc = $xwiki.getDocument($request.field)) 247: #set($formFieldDocClassFields = $formFieldDoc.getxWikiClass().getXWikiClass().properties) 248: #if($formFieldDocClassFields.size() > 0) 249: ## Clone the field template. 250: #set($field = $formFieldDocClassFields.get(0).clone()) 251: #if("$!field.prettyName" == '') 252: #set($discard = $field.setPrettyName($formFieldDoc.title)) 253: #end 254: #set($discard = $doc.getxWikiClass().getXWikiClass().addField($field.name, $field)) 255: #displayField($doc.getxWikiClass().get($field.name) $formFieldDoc) 256: #else 257: Unsupported form field. 258: #end 259: #end 260: 261: #** 262: * Preview a class field. 263: *# 264: #macro(previewField) 265: ## Find the request parameter that specifies the field template. 266: #foreach($paramName in $request.getParameterMap().keySet()) 267: #if($paramName.startsWith('template-')) 268: #set($fieldName = $paramName.substring(9)) 269: #set($fieldTemplateDoc = $xwiki.getDocument($request.getParameter($paramName))) 270: #break 271: #end 272: #end 273: ## 274: ## Clone the field template. 275: #set($field = $fieldTemplateDoc.getxWikiClass().getXWikiClass().properties.get(0).clone()) 276: ## 277: ## Update the field meta properties based on the submitted data. 278: #set($valuesFromRequest = $xcontext.context.getForm().getObject("field-$fieldName")) 279: #set($discard = $field.getxWikiClass().fromMap($valuesFromRequest, $field)) 280: ## 281: ## Don't rename the field (ignore the submitted name). 282: #set($discard = $field.setName($fieldName)) 283: ## 284: ## We have to add the field to the class before setting its value. 285: ## (otherwise the field value from the request is ignored). 286: #set($xclass = $doc.getxWikiClass().getXWikiClass()) 287: #set($discard = $xclass.addField($fieldName, $field)) 288: ## 289: ## Create an object that has this field and set its value from request. 290: #set($object = $fieldTemplateDoc.getObject($doc.fullName, true)) 291: ## 292: ## Filter empty values from the request, otherwise the update method could try to select an invalid value. 293: #set($values = []) 294: #foreach($value in $request.getParameterValues("${doc.fullName}_0_$fieldName")) 295: #if($value != '') 296: #set($discard = $values.add($value)) 297: #end 298: #end 299: #if($values.size() > 0) 300: #set($stringArray = $request.getParameterValues("template-$fieldName")) 301: #set($discard = $xclass.fromMap({$fieldName: $values.toArray($stringArray)}, $object.getXWikiObject())) 302: #end 303: ## 304: ## Display the field. 305: #set($field = $doc.getxWikiClass().get($fieldName)) 306: {{html clean="false"}}#displayPropertyEditInput($field, "${doc.fullName}_0_", $object){{/html}} 307: #end 308: 309: #** 310: * Display the edit class form. 311: *# 312: #macro(displayEditForm) 313: $xwiki.jsfx.use('js/scriptaculous/dragdrop.js')## 314: $xwiki.jsx.use('AppWithinMinutes.ClassEditSheet')## 315: $xwiki.ssx.use('AppWithinMinutes.ClassEditSheet')## 316: $xwiki.ssx.use('AppWithinMinutes.ClassSheetGenerator')## 317: #if("$!request.wizard" == 'true') 318: #appWizardHeader(2) 319: 320: #end 321: #displayFieldPalette() 322: #displayFieldCanvas() 323: #displayClassOptions() 324: #if("$!request.wizard" == 'true') 325: 326: #appWizardFooter(2) 327: #end 328: (% class="clearfloats" %)((())) 329: #end 330: 331: #** 332: * Displays either the edit class form or a new form field. The later is used when adding a new form field via AJAX. 333: *# 334: #macro(doEdit) 335: #if("$!request.field" != '') 336: #displayNewField() 337: #elseif("$!request.preview" == 'true') 338: #previewField() 339: #else 340: ## Make sure that only the sheet content is rendered when the class is saved using AJAX. 341: (% class="hidden" %) 342: {{html}}<input type="hidden" name="xpage" value="plain" />{{/html}} 343: 344: #displayEditForm() 345: #end 346: #end 347: 348: #** 349: * Updates and saves the class definition based on the submitted data. 350: *# 351: #macro(updateAndSaveClass) 352: #set($class = $doc.xWikiClass) 353: #set($xclass = $class.getXWikiClass().clone()) 354: #set($xdoc = $doc.document) 355: ## 356: ## Handle new fields and field type changes. 357: ## 358: #set($fieldNames = []) 359: #foreach($paramName in $request.getParameterMap().keySet()) 360: #if($paramName.startsWith('type-')) 361: #set($fieldName = $paramName.substring(5)) 362: #set($fieldType = $request.getParameter($paramName)) 363: #set($field = $class.get($fieldName)) 364: #if(!$field || $field.classType != $fieldType) 365: #if($field) 366: ## The field type has changed. Remove the field and add a new one with the proper type. 367: #set($discard = $xclass.removeField($fieldName)) 368: #end 369: ## Add a new class field with the specified type. 370: #set($fieldTemplateRef = $request.getParameter("template-$fieldName")) 371: #if("$!fieldTemplateRef" != '') 372: #set($fieldTemplateDoc = $xwiki.getDocument($fieldTemplateRef)) 373: #set($field = $fieldTemplateDoc.getxWikiClass().getXWikiClass().properties.get(0).clone()) 374: #set($discard = $field.setObject($xclass)) 375: #set($discard = $xclass.addField($fieldName, $field)) 376: #set($discard = $fieldNames.add($fieldName)) 377: #set($discard = $xdoc.setMetaDataDirty(true)) 378: #end 379: #else 380: #set($discard = $fieldNames.add($fieldName)) 381: #end 382: #end 383: #end 384: ## 385: ## Handle deleted fields. 386: ## 387: #foreach($field in $class.properties) 388: #if(!$fieldNames.contains($field.name)) 389: #set($discard = $xclass.removeField($field.name)) 390: #end 391: #end 392: ## 393: ## Handle field updates. 394: ## 395: #set($fieldsToRename = {}) 396: #foreach($fieldName in $xclass.propertyNames) 397: #set($field = $xclass.get($fieldName)) 398: #set($valuesFromRequest = $xcontext.context.getForm().getObject("field-$fieldName")) 399: #set($discard = $field.getxWikiClass().fromMap($valuesFromRequest, $field)) 400: #if($field.name.matches('^[a-zA-Z_][\w:\-\.]*$')) 401: #if($fieldName != $field.name) 402: ## The field name has changed. 403: #if($xclass.get($field.name)) 404: ## There is already a field with the same name. 405: #set($errorMessage = $msg.get('platform.appwithinminutes.classEditorDuplicateFieldNameError', $field.name)) 406: #break 407: #else 408: #set($discard = $xclass.removeField($fieldName)) 409: #set($discard = $xclass.addField($field.name, $field)) 410: #set($originalField = $class.get($fieldName)) 411: #if($originalField) 412: ## This is not a new field. 413: #set($discard = $fieldsToRename.put($fieldName, $field.name)) 414: #set($discard = $xclass.addPropertyForRemoval($originalField.propertyClass)) 415: #end 416: #end 417: #end 418: #else 419: #set($errorMessage = $msg.get('propertynamenotcorrect')) 420: #break 421: #end 422: #end 423: ## 424: ## Save 425: ## 426: #if(!$errorMessage) 427: #set($discard = $xdoc.setXClass($xclass)) 428: #set($discard = $xdoc.renameProperties($doc.documentReference, $fieldsToRename)) 429: #set($discard = $xdoc.setMetaDataDirty(true)) 430: #set($discard = $doc.save($msg.get('core.comment.updateClassProperty'), $minorEdit)) 431: #end 432: ## 433: ## Handle field renames. 434: ## 435: #if(!$errorMessage && !$fieldsToRename.isEmpty()) 436: ## We need to load all documents that have objects of this class and rename their properties. 437: #set($instancesStatement = "from doc.object($doc.fullName) as obj where doc.fullName <> :className") 438: #set($instancesQuery = $services.query.xwql($instancesStatement).bindValue('className', $doc.fullName)) 439: #foreach($instanceDocName in $instancesQuery.execute()) 440: #set($instanceDoc = $xwiki.getDocument($instanceDocName)) 441: #set($discard = $instanceDoc.document.renameProperties($doc.documentReference, $fieldsToRename)) 442: #set($discard = $instanceDoc.save($msg.get('core.comment.updateClassPropertyName'), true)) 443: #end 444: #end 445: ## 446: ## Clear cache. 447: ## 448: #if(!$errorMessage) 449: #set($discard = $xwiki.getXWiki().flushCache($xcontext.context)) 450: #end 451: #end 452: 453: #** 454: * Updates and saves the class template based on the submitted data. 455: *# 456: #macro(updateAndSaveTemplate) 457: #if(!$errorMessage && $request.updateClassTemplate) 458: #set($className = $doc.name) 459: #if($className.endsWith('Class')) 460: #set($className = $className.substring(0, $mathtool.sub($className.length(), 5))) 461: #end 462: #set($templateRef = $services.model.createDocumentReference($doc.wiki, $doc.space, "${className}Template")) 463: #set($templateDoc = $xwiki.getDocument($templateRef)) 464: #set($discard = $templateDoc.setParent($doc.name)) 465: #set($discard = $templateDoc.updateObjectFromRequest($doc.fullName)) 466: #set($discard = $templateDoc.save($msg.get('platform.appwithinminutes.classEditorTemplateSaveComment'), $minorEdit)) 467: #end 468: #end 469: 470: #** 471: * Updates and saves the class sheet based on the submitted data. 472: *# 473: #macro(updateAndSaveSheet) 474: #if(!$errorMessage && $request.updateClassSheet) 475: #set($classSheets = $services.sheet.getClassSheets($doc)) 476: #if($classSheets.isEmpty()) 477: #set($className = $doc.name) 478: #if($className.endsWith('Class')) 479: #set($className = $className.substring(0, $mathtool.sub($className.length(), 5))) 480: #end 481: #set($sheetReference = $services.model.createDocumentReference($doc.wiki, $doc.space, "${className}Sheet")) 482: #set($discard = $services.sheet.bindClassSheet($doc, $sheetReference)) 483: #set($discard = $doc.save($msg.get('platform.appwithinminutes.classEditorBindSheetSaveComment'), $minorEdit)) 484: #elseif($classSheets.size() == 1) 485: #set($sheetReference = $classSheets.get(0)) 486: #end 487: #if($sheetReference) 488: #set($sheetDoc = $xwiki.getDocument($sheetReference)) 489: #set($sheetGeneratorDoc = $xwiki.getDocument('AppWithinMinutes.ClassSheetGenerator')) 490: #set($discard = $sheetDoc.setParent($doc.name)) 491: #set($discard = $sheetDoc.setContent($doc.getRenderedContent($sheetGeneratorDoc.content, $sheetGeneratorDoc.syntax.toIdString(), 'plain/1.0'))) 492: #set($discard = $sheetDoc.save($msg.get('platform.appwithinminutes.classEditorSheetSaveComment'), $minorEdit)) 493: #end 494: #end 495: #end 496: 497: #** 498: * Updates and saves the class definition, the class sheet and the class template. 499: *# 500: #macro(doSave) 501: #set($minorEdit = "$!request.minorEdit" != '') 502: #updateAndSaveClass() 503: #updateAndSaveTemplate() 504: #updateAndSaveSheet() 505: #if($action == 'save') 506: #if($errorMessage) 507: {{error}}{{html}}$errorMessage{{/html}}{{/error}} 508: #elseif("$!request.wizard" == 'true') 509: ## Redirect to next wizard step. 510: #set($homePageRef = $services.model.createDocumentReference($doc.wiki, $doc.space, 'WebHome')) 511: #set($queryString = 'wizard=true') 512: #if(!$xwiki.exists($homePageRef)) 513: #set($homePageTitle = '$msg.get(''platform.appwithinminutes.appHomePageTitle'', $doc.space)') 514: #set($queryString = "$queryString&editor=inline&template=AppWithinMinutes.LiveTableTemplate&AppWithinMinutes.LiveTableClass_0_class=$escapetool.url($doc.fullName)&title=$escapetool.url($homePageTitle)&parent=Main.WebHome") 515: #end 516: $response.sendRedirect($xwiki.getURL($homePageRef, 'edit', $queryString)); 517: #else 518: ## Redirect to view mode. 519: $response.sendRedirect($doc.getURL()) 520: #end 521: #else 522: #if($errorMessage) 523: $response.sendError(400, $errorMessage) 524: #else 525: $response.setStatus(204) 526: #end 527: #end 528: #end 529: {{/velocity}} 530: 531: {{velocity}} 532: #if("$!request.wizard" == 'true') 533: {{include document="AppWithinMinutes.WizardStep" /}} 534: #end 535: {{/velocity}} 536: 537: {{velocity}} 538: ## Determine the action button that triggered the request 539: #set($action = 'edit') 540: #foreach($paramName in $request.getParameterMap().keySet()) 541: #if($paramName.startsWith('xaction_')) 542: #set($action = $paramName.substring(8)) 543: #break 544: #end 545: #end 546: #if($action == 'edit') 547: #doEdit() 548: #elseif($action == 'save' || $action == 'saveandcontinue') 549: #if($services.csrf.isTokenValid($request.form_token)) 550: #doSave() 551: #else 552: $response.sendRedirect($services.csrf.getResubmissionURL()); 553: #end 554: #end 555: {{/velocity}}