General Actions:
Log-in
Register
Home
▼
:
Wiki Index
»
Space:
XWiki
»
Page:
Registration
default
Page Actions:
Export
▼
:
Export as PDF
Export as RTF
Export as HTML
More actions
▼
:
Print preview
View Source
Welcome to bytebang
»
XWiki Space
»
Registration
Wiki source code of
Registration
Last modified by
Administrator
on 2014/06/29 19:28
Content
·
Attachments
(0)
·
Information
Hide line numbers
1: {{velocity}} 2: ## The registration is enabled: 3: ## - on the main wiki 4: ## - on a subwiki if there is no service "$services.wiki.user" 5: ## - on a subwiki where the user scope allows local users 6: #if($xcontext.isMainWiki() || "$!services.wiki.user" == '' || $services.wiki.user.getUserScope() != "GLOBAL_ONLY") 7: ## These are defined in other places around XWiki, changing them here will result in undefined behavior. 8: #set($redirectParam = 'xredirect') 9: #set($userSpace = 'XWiki.') 10: #set($loginPage = 'XWiki.XWikiLogin') 11: #set($loginAction = 'loginsubmit') 12: ## 13: #set($documentName = 'XWiki.Registration') 14: ## 15: ## Security measure: 16: ## If this document is changed such that it must have programming permission in order to run, change this to false. 17: #set($sandbox = true) 18: ## 19: ## Load the configuration from a seperate document. 20: #loadConfig('XWiki.RegistrationConfig') 21: ## 22: ## Defines what server generated error messages should look like 23: ## The error message when a field is entered incorrectly 24: #set($failureMessageParams = { 'class' : 'LV_validation_message LV_invalid'}) 25: ## 'LV_validation_message LV_invalid' depends on this: 26: $xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css', true) 27: ## 28: ## The * next to the fields to denote they are mandatory. 29: #set($fieldMandatoryStar = { 'class' : 'xRequired'}) 30: ## 31: #* 32: * You may include this document in other documents using {{include reference="XWiki.Registration"/}} 33: * To specify that the user is invited and should be allowed to register even if Guest does not have permission to 34: * register, set $invited to true. NOTE: The including script must have programming permission to do this. 35: * 36: * To specify some code which should run after registration is successfully completed, set 37: * $doAfterRegistration to a define block of velocity code like so: 38: * #define($doAfterRegistration) 39: * some code 40: * #end 41: * Output from running this code will not be printed. 42: * 43: * The fields which will be seen on the registration page are defined here. 44: * $fields is an array and each field is a Map. The names shown below are Map keys. 45: * 46: * Each field must have: 47: * name - this is the name of the field, it will be the value for "name" and "id" 48: * 49: * Each field may have: 50: * label - this String will be written above the field. 51: * 52: * tag - the HTML tag which will be created, default is <input>, may also be a non form tag such as <img> 53: * 54: * params - a Map, each key value pair will be in the html tag. eg: {"size" : "30"} becomes <input size=30... 55: * 56: * validate a Map describing how to validate the field, validation is done in javascript then redone in velocity 57: * | for security and because not everyone has javascript. 58: * | 59: * +-mandatory (Optional) - Will fail if the field is not filled in. 60: * | +-failureMessage (Required) - The message to display if the field is not filled in. 61: * | +-noscript (Optional) - will not be checked by javascript 62: * | 63: * +-regex (Optional) - Will validate the field using a regular expression. 64: * | | because of character escaping, you must provide a different expression for the 65: * | | javascript validation and the server side validation. Both javascript and server side 66: * | | validation are optional, but if you provide neither, then your field will not be validated. 67: * | | 68: * | +-failureMessage (Optional) - The message to display if the regex evaluation returns false. 69: * | +-jsFailureMessage (Optional) - The message for Javascript to display if regex fails. 70: * | | If jsFailureMessage is not defined Javascript uses failureMessage. 71: * | | NOTE: Javascript injects the failure message using createTextNode so < will 72: * | | be displayed as < 73: * | | 74: * | +-pattern (Optional) - The regular expression to test the input at the server side, it's important to use 75: * | | this if you need to validate the field for security reasons, also it is good because not 76: * | | all browsers use javascript or have it enabled. 77: * | | 78: * | +-jsPattern (Optional) - The regular expression to use for client side, you can use escaped characters to avoid 79: * | | them being parsed as HTML or javascript. To get javascript to unescape characters use: 80: * | | {"jsPattern" : "'+unescape('%5E%5B%24')+'"} 81: * | | NOTE: If no jsPattern is specified, the jsValidator will try to validate 82: * | | using the server pattern. 83: * | | 84: * | +-noscript (Optional) - will not be checked by javascript 85: * | 86: * +-mustMatch (Optional) - Will fail if the entry into the field is not the same as the entry in another field. 87: * | | Good for password confirmation. 88: * | | 89: * | +-failureMessage (Required) - The message to display if the field doesn't match the named field. 90: * | +-name (Required) - The name of the field which this field must match. 91: * | +-noscript (Optional) - will not be checked by javascript 92: * | 93: * +-programmaticValidation (Optional) - This form of validation executes a piece of code which you give it and 94: * | | if the code returns the word "failed" then it gives the error message. 95: * | | Remember to put the code in singel quotes ('') because you want the value 96: * | | of 'code' to equal the literal code, not the output from running it. 97: * | | 98: * | +-code (Required) - The code which will be executed to test whether the field is filled in correctly. 99: * | +-failureMessage (Required) - The message which will be displayed if evaluating the code returns "false" 100: * | 101: * +-fieldOkayMessage (Optional) - The message which is displayed by LiveValidation when a field is validated as okay. 102: * If not specified, will be $defaultFieldOkayMessage 103: * 104: * noReturn - If this is specified, the field will not be filled in if there is an error and the user has to fix their 105: * registration information. If you don't want a password to be passed back in html then set this true 106: * for the password fields. Used for the captcha because it makes no sense to pass back a captcha answer. 107: * 108: * doAfterRegistration - Some Velocity code which will be executed after a successfull registration. 109: * This is used in the favorite color example. 110: * Remember to put the code in singel quotes ('') because you want the 'code' entry to equal the literal 111: * code, not the output from running it. 112: * 113: * Each field may not have: (reserved names) 114: * error - This is used to pass back any error message from the server side code. 115: * 116: * NOTE: This template uses a registration method which requires: 117: * * register_first_name 118: * * register_last_name 119: * * xwikiname 120: * * register_password 121: * * register2_password 122: * * register_email 123: * * template 124: * Removing or renaming any of these fields will result in undefined behavior. 125: * 126: *### 127: #set($fields = []) 128: ## 129: ## The first name field, no checking. 130: #set($field = 131: {'name' : 'register_first_name', 132: 'label' : $services.localization.render('core.register.firstName'), 133: 'params' : { 134: 'type' : 'text', 135: 'size' : '60' 136: } 137: }) 138: #set($discard = $fields.add($field)) 139: ## 140: ## The last name field, no checking. 141: #set($field = 142: {'name' : 'register_last_name', 143: 'label' : $services.localization.render('core.register.lastName'), 144: 'params' : { 145: 'type' : 'text', 146: 'size' : '60' 147: } 148: }) 149: #set($discard = $fields.add($field)) 150: ## 151: ## The user name field, mandatory and programmatically checked to make sure the username doesn't exist. 152: #set($field = 153: {'name' : 'xwikiname', 154: 'label' : $services.localization.render('core.register.username'), 155: 'params' : { 156: 'type' : 'text', 157: 'onfocus' : 'prepareName(document.forms.register);', 158: 'size' : '60' 159: }, 160: 'validate' : { 161: 'mandatory' : { 162: 'failureMessage' : $services.localization.render('core.validation.required.message') 163: }, 164: 'programmaticValidation' : { 165: 'code' : '#nameAvailable($request.get("xwikiname"))', 166: 'failureMessage' : $services.localization.render('core.register.userAlreadyExists') 167: } 168: } 169: }) 170: #set($discard = $fields.add($field)) 171: ## Make sure the chosen user name is not already taken 172: ## This macro is called by programmaticValidation for xwikiname (above) 173: #macro(nameAvailable, $name) 174: #if($xwiki.exists("$userSpace$name")) 175: failed 176: #end 177: #end 178: ## 179: ##The password field, mandatory and must be at least 6 characters long. 180: #set($field = 181: {'name' : 'register_password', 182: 'label' : $services.localization.render('core.register.password'), 183: 'params' : { 184: 'type' : 'password', 185: 'autocomplete' : 'off', 186: 'size' : '60' 187: }, 188: 'validate' : { 189: 'mandatory' : { 190: 'failureMessage' : $services.localization.render('core.validation.required.message') 191: }, 192: 'regex' : { 193: 'pattern' : '/.{6,}/', 194: 'failureMessage' : $services.localization.render('xe.admin.registration.passwordTooShort') 195: } 196: } 197: }) 198: #set($discard = $fields.add($field)) 199: ## 200: ##The confirm password field, mandatory, must match password field, and must also be 6+ characters long. 201: #set($field = 202: {'name' : 'register2_password', 203: 'label' : $services.localization.render('core.register.passwordRepeat'), 204: 'params' : { 205: 'type' : 'password', 206: 'autocomplete' : 'off', 207: 'size' : '60' 208: }, 209: 'validate' : { 210: 'mandatory' : { 211: 'failureMessage' : $services.localization.render('core.validation.required.message') 212: }, 213: 'mustMatch' : { 214: 'name' : 'register_password', 215: 'failureMessage' : $services.localization.render('xe.admin.registration.passwordMismatch') 216: }, 217: 'regex' : { 218: 'pattern' : '/.{6,}/', 219: 'failureMessage' : $services.localization.render('xe.admin.registration.passwordTooShort') 220: } 221: } 222: }) 223: #set($discard = $fields.add($field)) 224: ## 225: ## The email address field, regex checked with an email pattern. Mandatory if registration uses email verification 226: #set($field = 227: {'name' : 'register_email', 228: 'label' : $services.localization.render('core.register.email'), 229: 'params' : { 230: 'type' : 'text', 231: 'size' : '60' 232: }, 233: 'validate' : { 234: 'regex' : { 235: 'pattern' : '/^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/', 236: 'failureMessage' : $services.localization.render('xe.admin.registration.invalidEmail') 237: } 238: } 239: }) 240: #if($xwiki.getXWikiPreferenceAsInt('use_email_verification', 0) == 1) 241: #set($field.validate.mandatory = {'failureMessage' : $services.localization.render('core.validation.required.message')}) 242: #end 243: #set($discard = $fields.add($field)) 244: ## 245: #********* 246: ## Uncomment this code to see an example of how you can easily add a field to the registration page 247: ## NOTE: In order to save the favorite color in the "doAfterRegistration" hook, this page must be 248: ## saved by an administrator and can not self sandboxing. 249: #set($sandbox = false) 250: #set($field = 251: {'name' : 'favorite_color', 252: 'label' : 'What is your favorite color', 253: 'params' : { 254: 'type' : 'text', 255: 'size' : '60' 256: }, 257: 'validate' : { 258: 'mandatory' : { 259: 'failureMessage' : $services.localization.render('core.validation.required.message') 260: }, 261: 'regex' : { 262: 'pattern' : '/^green$/', 263: 'failureMessage' : 'You are not cool enough to register here.' 264: }, 265: 'fieldOkayMessage' : 'You are awesome.' 266: }, 267: 'doAfterRegistration' : '#saveFavoriteColor()' 268: }) 269: #set($discard = $fields.add($field)) 270: ## Save the user's favorite color on their user page. 271: #macro(saveFavoriteColor) 272: #set($xwikiname = $request.get('xwikiname')) 273: #set($userDoc = $xwiki.getDocument("$userSpace$xwikiname")) 274: $userDoc.setContent("$userDoc.getContent() ${xwikiname}'s favorite color is $request.get('favorite_color')!") 275: ## The user (who is not yet logged in) can't save documents so saveWithProgrammingRights 276: ## will save the document as long as the user who last saved this registration page has programming rights. 277: $userDoc.saveWithProgrammingRights("Saved favorite color from registration form.") 278: #end 279: *********### 280: ## 281: ## To disable the captcha on this page, comment out the next two entries. 282: ## The captcha image, not an input field but still defined the same way. 283: #if($captchaservice 284: && !$invited 285: && $xcontext.getUser() == "XWiki.XWikiGuest" 286: && $requireCaptcha) 287: ## Empty label field used for padding. 288: ## Empty 'name' field overriddes name="captcha_image" with "" so name is not specified at all. 289: #set($field = 290: {'name' : 'captcha_image', 291: 'label' : "<span class='hidden'>$services.localization.render('core.captcha.image.label')</span>", 292: 'tag' : 'img', 293: 'params' : { 294: 'src' : $doc.getURL('imagecaptcha'), 295: 'alt' : $services.localization.render('core.captcha.image.alternateText', [$services.localization.render('core.register.submit')]), 296: 'name' : '' 297: } 298: }) 299: #set($discard = $fields.add($field)) 300: ## The captcha field, mandatory, programmatically checked to make sure the captcha is right 301: ## Not checked by javascript because javascript can't check the captcha and the Ok message because it passes the 302: ## mandatory test is misleading. 303: ## and not filled back in if there is an error ('noReturn') 304: #set($field = 305: {'name' : 'captcha_answer', 306: 'label' : $services.localization.render('core.captcha.image.instruction'), 307: 'params' : { 308: 'type' : 'text', 309: 'size' : '60' 310: }, 311: 'validate' : { 312: 'mandatory' : { 313: 'failureMessage' : $services.localization.render('core.captcha.captchaAnswerIsWrong'), 314: 'noscript' : true 315: }, 316: 'programmaticValidation' : { 317: 'code' : '#checkCaptcha($request, $request.get("captcha_answer"))', 318: 'failureMessage' : $services.localization.render('core.captcha.captchaAnswerIsWrong') 319: } 320: }, 321: 'noReturn' : true 322: }) 323: #set($discard = $fields.add($field)) 324: #end 325: ## 326: ## Checks the captcha answer; used by programmaticValidation above. 327: #macro(checkCaptcha, $request, $answer) 328: #set($cv = $captchaservice.getCaptchaVerifier('image')) 329: #if(!$cv.isAnswerCorrect($cv.getUserId($request), $answer)) 330: failed 331: #end 332: #end 333: ## 334: ## Pass the name of the template to $xwiki.createUser so any contained information will be passed in. 335: #set($field = 336: {'name' : 'template', 337: 'params' : { 338: 'type' : 'hidden', 339: 'value' : 'XWiki.XWikiUserTemplate' 340: } 341: }) 342: #set($discard = $fields.add($field)) 343: ## 344: ## Pass the redirect parameter on so that the login page may redirect to the right place. 345: ## Not necessary in Firefox 3.0.10 or Opera 9.64, I don't know about IE or Safari. 346: #set($field = 347: {'name' : $redirectParam, 348: 'params' : { 349: 'type' : 'hidden' 350: } 351: }) 352: #set($discard = $fields.add($field)) 353: ## 354: ####################################################################### 355: ## The Code. 356: ####################################################################### 357: ## 358: #if($useLiveValidation) 359: $xwiki.get('jsfx').use('uicomponents/widgets/validation/livevalidation_prototype.js') 360: $xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css', true) 361: #end 362: ## This application's HTML is dynamically generated and editing in WYSIWYG would not work 363: #if($xcontext.getAction() == 'edit') 364: $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'edit')?editor=wiki") 365: #end 366: ## 367: ## If this document has PR and is not included from another document then it's author should be set to Guest 368: ## for the duration of it's execution in order to improve security. 369: ## Note we compare document ids because 370: #if($sandbox 371: && $xcontext.hasProgrammingRights() 372: && $xcontext.getDoc().getDocumentReference().equals($xwiki.getDocument($documentName).getDocumentReference())) 373: ## 374: $xcontext.dropPermissions()## 375: #end 376: ## 377: ## Access level to register must be explicitly checked because it is only checked in XWiki.prepareDocuments 378: ## and this page is accessible through view action. 379: #if(!$xcontext.hasAccessLevel('register', 'XWiki.XWikiPreferences')) 380: ## Make an exception if another document with programming permission (Invitation app) has included this 381: ## document and set $invited to true. 382: #if(!$invited || !$xcontext.hasProgrammingRights()) 383: $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'login')") 384: #end 385: #end 386: ## If this is true, then assume the registration page is being viewed inside of a lightbox 387: #if($request.get('xpage')) 388: #set($assumeLightbox = true) 389: #end 390: ## 391: ## Display the heading 392: $heading 393: ## If the submit button has been pressed, then we test the input and maybe create the user. 394: #if($request.getParameter('xwikiname')) 395: ## Do server side validation of input fields. 396: ## This must not be in a #set directive as it will output messages if something goes wrong. 397: #validateFields($fields, $request) 398: ## If server side validation was successfull, create the user 399: #if(!$registrationFailed) 400: #createUser($fields, $request, $response, $doAfterRegistration) 401: #end 402: #end 403: ## If the registration was not successful or if the user hasn't submitted the info yet 404: ## Then we display the registration form. 405: #if(!$registrationDone) 406: $welcomeMessage 407: 408: {{html clean=false wiki=false}} 409: <form id="register" action="" method="post" class="xform half"> 410: <div> 411: <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> 412: #set ($userDirectoryReference = $services.model.createDocumentReference('', 'Main', 'UserDirectory')) 413: #if ($xwiki.exists($userDirectoryReference)) 414: <input type="hidden" name="parent" value="$!{services.model.serialize($userDirectoryReference, 'default')}" /> 415: #end 416: #generateHtml($fields, $fieldMandatoryStar, $failureMessageParams) 417: <div class="wikimodel-emptyline"></div> 418: <span class="buttonwrapper"> 419: #if($assumeLightbox) 420: ## LightBox detected... 421: <script type="text/javascript"> 422: ## Make the X button not reload the page. (overriding LbClose) 423: window.lb.lbClose = function() { 424: this.lbHide(); 425: this.lbClearData(); 426: ##return false; 427: } 428: ## Post the form entry to the page and load the result. (we override lbSaveForm) 429: window.lb.lbSaveForm = function() { 430: var formParams = Form.serialize(this.form); 431: Form.disable(this.form); 432: var ajaxRequest = new Ajax.Request(this.saveUrl, { 433: parameters: formParams, 434: asynchronous: false 435: }); 436: window.lb.lbFormDataLoaded(ajaxRequest.transport); 437: } 438: </script> 439: ## It doesn't really matter where these are, the scripts will be relocated to the head. 440: <!-- com.xpn.xwiki.plugin.skinx.CssSkinFileExtensionPlugin --> 441: <!-- com.xpn.xwiki.plugin.skinx.JsSkinFileExtensionPlugin --> 442: ## 443: <input class="button" type="submit" value="$services.localization.render('save')" onclick="window.lb.lbSaveForm();"/> 444: </span>#* End ButtonWrapper then start another...*#<span class="buttonwrapper"> 445: <input class="button secondary" type="submit" value="$services.localization.render("cancel")" onclick="Form.disable(window.lb.form); window.lb.lbClose();"/> 446: #else 447: ## Not using the LightBox 448: <input type="submit" value="$services.localization.render('core.register.submit')" class="button"/> 449: #end 450: </span>## ButtonWrapper 451: </div> 452: </form> 453: #if($useLiveValidation) 454: #generateJavascript($fields) 455: #end 456: {{/html}} 457: 458: ## 459: ## Allow permitted users to configure this application. 460: #if($xcontext.getUser() != 'XWiki.XWikiGuest' && $xcontext.hasAccessLevel("edit", $documentName)) 461: [[{{translation key="xe.admin.registration.youCanConfigureRegistrationHere"/}}>>XWiki.XWikiPreferences?section=Registration&editor=globaladmin#HCustomizeXWikiRegistration]] 462: {{html}}<a href="$xwiki.getURL($documentName, 'edit', 'editor=wiki')">$services.localization.render('xe.admin.registration.youCanConfigureRegistrationFieldsHere')</a>{{/html}} 463: #end 464: ## If the registration is done (successful) and we detect the Lightbox simply send the user back to the original page. 465: #elseif($assumeLightbox) 466: {{html clean=false wiki=false}} 467: <script type="text/javascript"> 468: var url = window.lb.redirectUrl; 469: window.lb.lbClose; 470: if (url != undefined) { 471: if(window.location.pathname + window.location.search == url) { 472: ## Under certain circumstances (bug) Opera will not load a page if the location is the same as the current page. 473: ## In these cases, location.reload() doesn't work either, the only solution (I could find) was to change the URL. 474: window.location.href = url + "&"; 475: } else { 476: window.location.href = url; 477: } 478: } 479: </script> 480: {{/html}} 481: #end 482: #else 483: ## The registration is not allowed on the subwiki 484: ## Redirecting to main wiki's registration page since local user registration is not allowed. 485: #set($mainWikiRegisterPageReference = $services.model.createDocumentReference($services.wiki.mainWikiId, 'XWiki', 'Register')) 486: #set($temp = $response.sendRedirect($xwiki.getURL($mainWikiRegisterPageReference, 'register', $request.queryString))) 487: #end 488: ## 489: ####### The Macros (nothing below this point is run directly) ######### 490: #* 491: * Server side validation, this is necessary for security and because not everyone has Javascript 492: * 493: * @param $fields The array of fields to validate. 494: * @param $request An XWikiRequest object which made the register request, used to get parameters. 495: *### 496: #macro(validateFields, $fields, $request) 497: #foreach($field in $fields) 498: #if($field.get('validate') && $field.get('name')) 499: #set($fieldName = $field.get('name')) 500: #set($validate = $field.get('validate')) 501: #set($error = '') 502: #set($value = $request.get($fieldName)) 503: #if($value && $value != '') 504: ## 505: ## mustMatch validation 506: #if($error == '' && $validate.get('mustMatch')) 507: #set($mustMatch = $validate.get('mustMatch')) 508: #if($mustMatch.get('name') && $mustMatch.get('failureMessage')) 509: #if($request.get($fieldName) != $request.get($mustMatch.get('name'))) 510: #set($error = $mustMatch.get('failureMessage')) 511: #end 512: #else 513: ERROR: In field: ${fieldName}: mustMatch validation required both name 514: (of field which this field must match) and failureMessage. 515: #end 516: #end 517: ## 518: ## Regex validation 519: ## We won't bother with regex validation if there is no entry, that would defeat the purpose of 'mandatory' 520: #if($error == '' && $validate.get('regex') && $value && $value != '') 521: #set($regex = $validate.get('regex')) 522: #if($regex.get('pattern') && $regex.get('failureMessage')) 523: ## Make Java regexes more compatible with Perl/js style regexes by removing leading and trailing / 524: #if($regex.get('pattern').length() > 1) 525: #set($pattern = $regex.get('pattern')) 526: #if($pattern.lastIndexOf('/') < $pattern.length() - 1) 527: ERROR: In field: ${fieldName}: regex validation does not allow flags after the /, please fix [${pattern}]. 528: #end 529: #set($pattern = $pattern.substring($mathtool.add(1, $pattern.indexOf('/')), $pattern.lastIndexOf('/'))) 530: #else 531: ## I don't expect this but want to maintain compatibility. 532: #set($pattern = $regex.get('pattern')) 533: #end 534: #if($regextool.find($value, $pattern).isEmpty()) 535: #set($error = $regex.get('failureMessage')) 536: #end 537: #elseif($regex.get('pattern')) 538: ERROR: In field: ${fieldName}: regex validation must include failureMessage. 539: #end 540: #end 541: ## 542: ## If regex and mustMatch validation passed, try programmatic validation 543: #if($error == '' && $validate.get('programmaticValidation')) 544: #set($pv = $validate.get('programmaticValidation')) 545: #if($pv.get('code') && $pv.get('failureMessage')) 546: #set($pvReturn = "#evaluate($pv.get('code'))") 547: #if($pvReturn.indexOf('failed') != -1) 548: #set($error = $pv.get('failureMessage')) 549: #end 550: #else 551: ERROR: In field: ${fieldName}: programmaticValidation requires code and failureMessage 552: #end 553: #end 554: #else 555: ## 556: ## If no content, check if content is mandatory 557: #if($validate.get('mandatory')) 558: #set($mandatory = $validate.get('mandatory')) 559: #if($mandatory.get('failureMessage')) 560: #set($error = $mandatory.get('failureMessage')) 561: #else 562: ERROR: In field: ${fieldName}: mandatory validation requires a failureMessage 563: #end 564: #end 565: #end 566: #if($error != '') 567: #set($discard = $field.put('error', $error)) 568: #set($registrationFailed = true) 569: #end 570: #elseif(!$field.get('name')) 571: ERROR: Field with no name. 572: #end##if(validate) 573: #end##loop 574: #end##macro 575: #* 576: * Create the user. 577: * Calls $xwiki.createUser to create a new user. 578: * 579: * @param $request An XWikiRequest object which made the register request. 580: * @param $response The XWikiResponse object to send any redirects to. 581: * @param $doAfterRegistration code block to run after registration completes successfully. 582: *### 583: #macro(createUser, $fields, $request, $response, $doAfterRegistration) 584: ## CSRF check 585: #if(${services.csrf.isTokenValid("$!{request.getParameter('form_token')}")}) 586: ## See if email verification is required and register the user. 587: #if($xwiki.getXWikiPreferenceAsInt('use_email_verification', 0) == 1) 588: #set($reg = $xwiki.createUser(true)) 589: #else 590: #set($reg = $xwiki.createUser(false)) 591: #end 592: #else 593: $response.sendRedirect("$!{services.csrf.getResubmissionURL()}") 594: #end 595: ## 596: ## Handle output from the registration. 597: #if($reg && $reg <= 0) 598: {{error}} 599: #if($reg == -2) 600: {{translation key="core.register.passwordMismatch"/}} 601: ## -3 means username taken, -8 means username is superadmin name 602: #elseif($reg == -3 || $reg == -8) 603: {{translation key="core.register.userAlreadyExists"/}} 604: #elseif($reg == -4) 605: {{translation key="core.register.invalidUsername"/}} 606: #else 607: {{translation key="core.register.registerFailed" parameters="$reg"/}} 608: #end 609: {{/error}} 610: #elseif($reg) 611: ## Registration was successful 612: #set($registrationDone = true) 613: ## 614: ## If there is any thing to "doAfterRegistration" then do it. 615: #foreach($field in $fields) 616: #if($field.get('doAfterRegistration')) 617: #evaluate($field.get('doAfterRegistration')) 618: #end 619: #end 620: ## If there is a "global" doAfterRegistration, do that as well. 621: ## Calling toString() on a #define block will execute it and we discard the result. 622: #set($discard = $doAfterRegistration.toString()) 623: ## 624: ## Define some strings which may be used by autoLogin or loginButton 625: #set($userName = $!request.get('xwikiname')) 626: #set($password = $!request.get('register_password')) 627: #set($loginURL = $xwiki.getURL($loginPage, $loginAction)) 628: #if("$!request.getParameter($redirectParam)" != '') 629: #set($redirect = $request.getParameter($redirectParam)) 630: #else 631: #set($redirect = $defaultRedirect) 632: #end 633: ## Display a "registration successful" message 634: 635: #evaluate($registrationSuccessMessage) 636: 637: ## Empty line prevents message from being forced into a <p> block. 638: 639: ## Give the user a login button which posts their username and password to loginsubmit 640: #if($loginButton) 641: 642: {{html clean=false wiki=false}} 643: <form id="loginForm" action="$loginURL" method="post"> 644: <div class="centered"> 645: <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> 646: <input id="j_username" name="j_username" type="hidden" value="$escapetool.xml($!userName)" /> 647: <input id="j_password" name="j_password" type="hidden" value="$escapetool.xml($!password)" /> 648: <input id="$redirectParam" name="$redirectParam" type="hidden" value="$escapetool.xml($redirect)" /> 649: <span class="buttonwrapper"> 650: <input type="submit" value="$services.localization.render('login')" class="button"/> 651: </span> 652: </div> 653: </form> 654: ## We don't want autoLogin if we are administrators adding users... 655: #if($autoLogin && !$assumeLightbox) 656: <script type='text/javascript'> 657: document.observe('xwiki:dom:loaded', function() { 658: document.forms['loginForm'].submit(); 659: }); 660: </script> 661: #end 662: {{/html}} 663: 664: #end 665: #end 666: ## 667: #end## createUser Macro 668: #* 669: * Generate HTML form, this is the only place where HTML is written. 670: * 671: * @param $fields The array of fields to use for generating html code. 672: * @param $fieldMandatoryStar The tag parameters for a * indicating a mandatory field. 673: * @param $failureMessageParams The tag parameters for a failure message. 674: *### 675: #macro(generateHtml, $fields, $fieldMandatoryStar, $failureMessageParams) 676: ## Put the same values back into the fields. 677: #getParams($fields) 678: ## 679: <dl> 680: #foreach($field in $fields) 681: #if($field.get('name')) 682: #set($fieldName = $field.get('name')) 683: #if($field.get('label')) 684: #set($label = $field.get('label')) 685: <dt><label for="$fieldName">$label 686: #if($field.get('validate').get('mandatory')) 687: <span ## 688: #foreach($entry in $fieldMandatoryStar.entrySet()) 689: $entry.getKey()="$entry.getValue()" ## 690: #end 691: >$services.localization.render('core.validation.required')</span> 692: #end 693: </label> 694: </dt> 695: #end 696: ## If no tag then default tag is <input> 697: #if($field.get('tag')) 698: #set($tag = $field.get('tag')) 699: #else 700: #set($tag = 'input') 701: #end 702: <dd><$tag id="$fieldName" ## 703: #set($params = $field.get('params')) 704: ## If no name parameter is spacified, then we use the field name 705: #if(!$params.get('name')) 706: #set($discard = $params.put('name', $fieldName)) 707: #end 708: #foreach($entry in $params.entrySet()) 709: ## If a parameter is specified as '' then we don't include it. 710: #if($entry.getValue() != '') 711: $entry.getKey()="$escapetool.xml($entry.getValue())" ## 712: #end 713: #end 714: ></$tag> 715: #if($field.get('error')) 716: <span ## 717: #foreach($entry in $failureMessageParams.entrySet()) 718: $entry.getKey()="$entry.getValue()" ## 719: #end 720: >$field.get('error')</span> 721: #end 722: </dd> 723: #else 724: ERROR: Field with no name. 725: #end##if fieldName exists 726: #end 727: </dl> 728: #end 729: #* 730: * Generate the Javascript for interacting with LiveValidation. 731: * 732: * @param $fields The array of fields which to validate. 733: *### 734: #macro(generateJavascript, $fields) 735: <script type='text/javascript'> 736: /* <![CDATA[ */ 737: document.observe('xwiki:dom:loaded', function() { 738: ## 739: #foreach($field in $fields) 740: #if($field.get('validate') && $field.get('name')) 741: #set($validate = $field.get('validate')) 742: #if(($validate.get('mandatory') && !$validate.get('mandatory').get('noscript')) 743: || ($validate.get('regex') && !$validate.get('regex').get('noscript')) 744: || ($validate.get('mustMatch') && !$validate.get('mustMatch').get('noscript'))) 745: #set($fieldName = $field.get('name')) 746: #if($validate.get('fieldOkayMessage')) 747: #set($okayMessage = $validate.get('fieldOkayMessage')) 748: #else 749: #set($okayMessage = $defaultFieldOkayMessage) 750: #end 751: var ${fieldName}Validator = new LiveValidation("$fieldName", { validMessage: "$okayMessage", wait: 500} ); 752: ## 753: #if($validate.get('mandatory')) 754: #set($mandatory = $validate.get('mandatory')) 755: #if($mandatory.get('failureMessage') && !$mandatory.get('noscript')) 756: ${fieldName}Validator.add( Validate.Presence, { failureMessage: "$!mandatory.get('failureMessage')"} ); 757: #end 758: #end 759: ## 760: #if($validate.get('mustMatch')) 761: #set($mustMatch = $validate.get('mustMatch')) 762: #if($mustMatch.get('name') && $mustMatch.get('failureMessage') && !$mustMatch.get('noscript')) 763: ${fieldName}Validator.add( Validate.Confirmation, { match: $$("input[name=$!mustMatch.get('name')]")[0], failureMessage: "$!mustMatch.get('failureMessage')"} ); 764: #end 765: #end 766: ## 767: #if($validate.get('regex')) 768: #set($regex = $validate.get('regex')) 769: #set($pattern = "") 770: #if($regex.get('jsPattern')) 771: #set($pattern = $regex.get('jsPattern')) 772: #elseif($regex.get('pattern')) 773: #set($pattern = $regex.get('pattern')) 774: #end 775: #set($failMessage = "") 776: #if($regex.get('jsFailureMessage')) 777: #set($failMessage = $regex.get('jsFailureMessage')) 778: #elseif($regex.get('failureMessage')) 779: #set($failMessage = $regex.get('failureMessage')) 780: #end 781: #if($pattern != '' && $failMessage != '' && !$regex.get('noscript')) 782: ${fieldName}Validator.add( Validate.Format, { pattern: $pattern, failureMessage: "$failMessage"} ); 783: #end 784: #end##if regex 785: #end##if contains js validateable fields. 786: #end##if validate 787: #end##loop 788: });// ]]> 789: </script> 790: #end##macro 791: #* 792: * Get parameters from request so that values will be filled in if there is a mistake 793: * in one of the entries. Entries will be returned to fields[n].params.value 794: * Fields will not be returned if they have either noReturn or error specified. 795: * 796: * @param $fields The array of fields to get parameters for. 797: *### 798: #macro(getParams $fields) 799: #foreach($field in $fields) 800: #if($field.get('name') && $request.get($field.get('name'))) 801: #if(!$field.get('noReturn') && !$field.get('error')) 802: #if(!$field.get('params')) 803: #set($params = {}) 804: #set($discard = $field.put('params', $params)) 805: #else 806: #set($params = $field.get('params')) 807: #end 808: #set($discard = $params.put('value', $request.get($field.get('name')))) 809: #end 810: #end 811: #end 812: #end 813: #* 814: * Get the configuration from the configuration object. 815: * 816: * @param $configDocumentName The name of the document to get the configuration from. 817: *### 818: #macro(loadConfig, $configDocumentName) 819: #set($configDocument = $xwiki.getDocument($configDocumentName)) 820: #if(!$configDocument || !$configDocument.getObject($documentName)) 821: ## No config document, load defaults. 822: #set($heading = "$services.localization.render('core.register.title')") 823: #set($welcomeMessage = "$services.localization.render('core.register.welcome')") 824: #set($useLiveValidation = true) 825: #set($defaultFieldOkayMessage = "$services.localization.render('core.validation.valid.message')") 826: #set($loginButton = true) 827: #set($defaultRedirect = "$xwiki.getURL($services.model.resolveDocument('', 'default', $doc.documentReference.extractReference('WIKI')))") 828: #set($userFullName = "$request.get('register_first_name') $request.get('register_last_name')") 829: #set($registrationSuccessMessage = '{{info}}$services.localization.render("core.register.successful", ["[[${userFullName}>>${userSpace}${userName}]]", ${userName}]){{/info}}') 830: #else 831: #set($configObject = $configDocument.getObject($documentName)) 832: #if ($xcontext.action == 'register') 833: #set ($heading = "(% id='document-title'%)((( = #evaluate($configObject.getProperty('heading').getValue()) = )))(%%)") 834: #else 835: #set ($heading = "= #evaluate($configObject.getProperty('heading').getValue()) =") 836: #end 837: #set($welcomeMessage = "#evaluate($configObject.getProperty('welcomeMessage').getValue())") 838: #if($configObject.getProperty('liveValidation_enabled').getValue() == 1) 839: #set($useLiveValidation = true) 840: #end 841: #set($defaultFieldOkayMessage = "#evaluate($configObject.getProperty('liveValidation_defaultFieldOkMessage').getValue())") 842: #if($configObject.getProperty('loginButton_enabled').getValue() == 1) 843: #set($loginButton = true) 844: #end 845: #if($configObject.getProperty('loginButton_autoLogin_enabled').getValue() == 1) 846: #set($autoLogin = true) 847: #end 848: #set($defaultRedirect = "#evaluate($configObject.getProperty('defaultRedirect').getValue())") 849: #set($registrationSuccessMessage = "$configObject.getProperty('registrationSuccessMessage').getValue()") 850: #if($configObject.getProperty('requireCaptcha').getValue() == 1) 851: #set($requireCaptcha = true) 852: #end 853: #end 854: #end 855: {{/velocity}}