<commit_before><?xml version="1.0" encoding="UTF-8"?>
<xwikidoc>
<web>XWiki</web>
<name>Registration</name>
<language></language>
<defaultLanguage>en</defaultLanguage>
<translation>0</translation>
<parent>XWiki.WebHome</parent>
<creator>XWiki.Admin</creator>
<author>XWiki.Admin</author>
<customClass></customClass>
<contentAuthor>XWiki.Admin</contentAuthor>
<creationDate>1264284581000</creationDate>
<date>1267024497000</date>
<contentUpdateDate>1267024497000</contentUpdateDate>
<version>1.1</version>
<title>Registration</title>
<template></template>
<defaultTemplate></defaultTemplate>
<validationScript></validationScript>
<comment></comment>
<minorEdit>false</minorEdit>
<syntaxId>xwiki/2.0</syntaxId>
<hidden>false</hidden>
<class>
<name>XWiki.Registration</name>
<customClass></customClass>
<customMapping></customMapping>
<defaultViewSheet></defaultViewSheet>
<defaultEditSheet></defaultEditSheet>
<defaultWeb></defaultWeb>
<nameField></nameField>
<validationScript></validationScript>
<defaultRedirect>
<name>defaultRedirect</name>
<number>7</number>
<picker>0</picker>
<prettyName>Redirect here after registration</prettyName>
<size>30</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.StringClass</classType>
</defaultRedirect>
<heading>
<name>heading</name>
<number>1</number>
<picker>0</picker>
<prettyName>Registration page heading</prettyName>
<size>30</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.StringClass</classType>
</heading>
<liveValidation_defaultFieldOkMessage>
<name>liveValidation_defaultFieldOkMessage</name>
<number>4</number>
<picker>0</picker>
<prettyName>Default field okay message</prettyName>
<size>30</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.StringClass</classType>
</liveValidation_defaultFieldOkMessage>
<liveValidation_enabled>
<defaultValue></defaultValue>
<displayFormType>checkbox</displayFormType>
<displayType></displayType>
<name>liveValidation_enabled</name>
<number>3</number>
<prettyName>Enable Javascript field validation</prettyName>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
</liveValidation_enabled>
<loginButton_autoLogin_enabled>
<defaultValue></defaultValue>
<displayFormType>checkbox</displayFormType>
<displayType></displayType>
<name>loginButton_autoLogin_enabled</name>
<number>6</number>
<prettyName>Enable automatic login</prettyName>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
</loginButton_autoLogin_enabled>
<loginButton_enabled>
<defaultValue></defaultValue>
<displayFormType>checkbox</displayFormType>
<displayType></displayType>
<name>loginButton_enabled</name>
<number>5</number>
<prettyName>Enable login button</prettyName>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
</loginButton_enabled>
<registrationSuccessMessage>
<editor>PureText</editor>
<name>registrationSuccessMessage</name>
<number>9</number>
<picker>0</picker>
<prettyName>Registration Successful Message</prettyName>
<rows>12</rows>
<size>40</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
</registrationSuccessMessage>
<requireCaptcha>
<defaultValue></defaultValue>
<displayFormType>checkbox</displayFormType>
<displayType></displayType>
<name>requireCaptcha</name>
<number>8</number>
<prettyName>Require captcha to register</prettyName>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
</requireCaptcha>
<welcomeMessage>
<editor>PureText</editor>
<name>welcomeMessage</name>
<number>2</number>
<picker>0</picker>
<prettyName>Welcome message</prettyName>
<rows>12</rows>
<size>40</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
</welcomeMessage>
</class>
<content>{{velocity}}
## These are defined in other places around XWiki, changing them here will result in undefined behavior.
#set($redirectParam = 'xredirect')
#set($userSpace = 'XWiki.')
#set($loginPage = 'XWiki.XWikiLogin')
#set($loginAction = 'loginsubmit')
##
#set($documentName = 'XWiki.Registration')
##
## Security measure: 
## If this document is changed such that it must have programming permission in order to run, change this to false.
#set($sandbox = true)
##
## Load the configuration from a seperate document.
#loadConfig('XWiki.RegistrationConfig')
##
## Defines what server generated error messages should look like
## The error message when a field is entered incorrectly
#set($failureMessageParams = { 'class' : 'LV_validation_message LV_invalid'})
## 'LV_validation_message LV_invalid' depends on this:
$xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css')
##
## The * next to the fields to denote they are mandatory.
#set($fieldMandatoryStar = $failureMessageParams)
##
#*
 * You may include this document in other documents using {{include document="XWiki.Registration"/}}
 * To specify that the user is invited and should be allowed to register even if Guest does not have permission to
 * register, set $invited to true. NOTE: The including script must have programming permission to do this.
 *
 * To specify some code which should run after registration is successfully completed, set
 * $doAfterRegistration to a define block of velocity code like so:
 * #define($doAfterRegistration)
 *   some code
 * #end
 * Output from running this code will not be printed.
 *
 * The fields which will be seen on the registration page are defined here.
 * $fields is an array and each field is a Map. The names shown below are Map keys.
 * 
 * Each field must have:
 *   name - this is the name of the field, it will be the value for "name" and "id"
 * 
 * Each field may have:
 *   label - this String will be written above the field.
 *
 *   tag - the HTML tag which will be created, default is &lt;input&gt;, may also be a non form tag such as &lt;img&gt;
 *
 *   params - a Map, each key value pair will be in the html tag. eg: {"size" : "30"} becomes &lt;input size=30...
 *
 *   validate a Map describing how to validate the field, validation is done in javascript then redone in velocity
 *   |        for security and because not everyone has javascript.
 *   |
 *   +-mandatory (Optional) - Will fail if the field is not filled in.
 *   | +-failureMessage (Required) - The message to display if the field is not filled in.
 *   | +-noscript (Optional) - will not be checked by javascript
 *   |
 *   +-regex (Optional) - Will validate the field using a regular expression.
 *   | |                  because of character escaping, you must provide a different expression for the
 *   | |                  javascript validation and the server side validation. Both javascript and server side
 *   | |                  validation are optional, but if you provide neither, then your field will not be validated.
 *   | |
 *   | +-failureMessage (Optional) - The message to display if the regex evaluation returns false.
 *   | +-jsFailureMessage (Optional) - The message for Javascript to display if regex fails. 
 *   | |                               If jsFailureMessage is not defined Javascript uses failureMessage.
 *   | |                               NOTE: Javascript injects the failure message using createTextNode so &amp;lt; will
 *   | |                                     be displayed as &amp;lt;
 *   | |
 *   | +-pattern (Optional) - The regular expression to test the input at the server side, it's important to use
 *   | |                      this if you need to validate the field for security reasons, also it is good because not
 *   | |                      all browsers use javascript or have it enabled.
 *   | |
 *   | +-jsPattern (Optional) - The regular expression to use for client side, you can use escaped characters to avoid
 *   | |                        them being parsed as HTML or javascript. To get javascript to unescape characters use:
 *   | |                        {"jsPattern" : "'+unescape('%5E%5B%24')+'"}
 *   | |                        NOTE: If no jsPattern is specified, the jsValidator will try to validate 
 *   | |                              using the server pattern.
 *   | |
 *   | +-noscript (Optional) - will not be checked by javascript
 *   |
 *   +-mustMatch (Optional) - Will fail if the entry into the field is not the same as the entry in another field.
 *   | |                      Good for password confirmation.
 *   | |
 *   | +-failureMessage (Required) - The message to display if the field doesn't match the named field.
 *   | +-name (Required) - The name of the field which this field must match.
 *   | +-noscript (Optional) - will not be checked by javascript
 *   |
 *   +-programmaticValidation (Optional) - This form of validation executes a piece of code which you give it and
 *   | |                                   if the code returns the word "failed" then it gives the error message.
 *   | |                                   Remember to put the code in singel quotes ('') because you want the value
 *   | |                                   of 'code' to equal the literal code, not the output from running it.
 *   | |
 *   | +-code (Required) - The code which will be executed to test whether the field is filled in correctly.
 *   | +-failureMessage (Required) - The message which will be displayed if evaluating the code returns "false"
 *   |
 *   +-fieldOkayMessage (Optional) - The message which is displayed by LiveValidation when a field is validated as okay.
 *                                   If not specified, will be $defaultFieldOkayMessage
 *  
 *   noReturn - If this is specified, the field will not be filled in if there is an error and the user has to fix their
 *              registration information. If you don't want a password to be passed back in html then set this true
 *              for the password fields. Used for the captcha because it makes no sense to pass back a captcha answer.
 *  
 *   doAfterRegistration - Some Velocity code which will be executed after a successfull registration. 
 *                         This is used in the favorite color example.
 *                         Remember to put the code in singel quotes ('') because you want the 'code' entry to equal the literal
 *                         code, not the output from running it.
 *  
 * Each field may not have: (reserved names)
 *   error - This is used to pass back any error message from the server side code.
 *
 * NOTE: This template uses a registration method which requires:
 *        * register_first_name
 *        * register_last_name
 *        * xwikiname
 *        * register_password
 *        * register2_password
 *        * register_email
 *        * template
 *       Removing or renaming any of these fields will result in undefined behavior.
 *
 *###
#set($fields = [])
##
## The first name field, no checking.
#set($field = 
  {'name' : 'register_first_name',
    'label' : $msg.get('core.register.firstName'),
    'params' : { 
      'type' : 'text', 
      'size' : '30' 
    }
  })
#set($discard = $fields.add($field))
##
## The last name field, no checking.
#set($field = 
  {'name' : 'register_last_name',
    'label' : $msg.get('core.register.lastName'),
    'params' : { 
      'type' : 'text', 
      'size' : '30' 
    }
  })
#set($discard = $fields.add($field))
##
## The user name field, mandatory and programmatically checked to make sure the username doesn't exist.
#set($field = 
  {'name' : 'xwikiname',
    'label' : $msg.get('core.register.username'),
    'params' : {
      'type' : 'text',
      'onfocus' : 'prepareName(document.forms.register);',
      'size' : '20'
    },
    'validate' : {
      'mandatory' : { 
        'failureMessage' : $msg.get('xe.admin.registration.fieldMandatory') 
      },
      'programmaticValidation' : {
        'code' : '#nameAvailable($request.get("xwikiname"))',
        'failureMessage' : $msg.get('core.register.userAlreadyExists')
      }
    }
  })
#set($discard = $fields.add($field))
## Make sure the chosen user name is not already taken
## This macro is called by programmaticValidation for xwikiname (above)
#macro(nameAvailable, $name)
  #if($xwiki.exists("$userSpace$name"))
    failed
  #end
#end
##
##The password field, mandatory and must be at least 6 characters long.
#set($field = 
  {'name' : 'register_password',
    'label' : $msg.get('core.register.password'),
    'params' : {
      'type' : 'password',
      'size' : '10'
    },
    'validate' : {
      'mandatory' : { 
        'failureMessage' : $msg.get('xe.admin.registration.fieldMandatory') 
      },
      'regex' : {
        'pattern' : '/.{6,}/',
        'failureMessage' : $msg.get('xe.admin.registration.passwordTooShort')
      }
    }
  })
#set($discard = $fields.add($field))
##
##The confirm password field, mandatory, must match password field, and must also be 6+ characters long.
#set($field = 
  {'name' : 'register2_password',
    'label' : $msg.get('core.register.passwordRepeat'),
    'params' : {
      'type' : 'password',
      'size' : '10'
    },
    'validate' : {
      'mandatory' : { 
        'failureMessage' : $msg.get('xe.admin.registration.fieldMandatory') 
      },
      'mustMatch' : {
        'name' : 'register_password',
        'failureMessage' : $msg.get('xe.admin.registration.passwordMismatch')
      },
      'regex' : {
        'pattern' : '/.{6,}/',
        'failureMessage' : $msg.get('xe.admin.registration.passwordTooShort')
      }
    }
  })
#set($discard = $fields.add($field))
##
## The email address field, regex checked with an email pattern.
#set($field = 
  {'name' : 'register_email',
    'label' : $msg.get('core.register.email'),
    'params' : { 
      'type' : 'text', 
      'size' : '30' 
    },
    'validate' : {
      'regex' : {
        'pattern' : '/^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/',
        'failureMessage' : $msg.get('xe.admin.registration.invalidEmail')
      }
    }
  })
#set($discard = $fields.add($field))
##
#* ## Uncomment this code to see an example of how you can easily add a field to the registration page
## Note: The user's favorite color is not saved anywhere, see above for information on how to save it.
#set($field = 
  {'name' : 'favorite_color',
    'label' : 'What is your favorite color',
    'params' : {
      'type' : 'text',
      'size' : '25'
    },
    'validate' : {
      'mandatory' : {
        'failureMessage' : $msg.get('xe.admin.registration.fieldMandatory')
      },
      'regex' : {
        'pattern' : '/^green$/i',
        'failureMessage' : 'You are not cool enough to register here.'
      },
      'fieldOkayMessage' : 'You are awesome.'
    },
    'doAfterRegistration' : '#saveFavoriteColor()'
  })
#set($discard = $fields.add($field))
## Save the user's favorite color on their user page.
#macro(saveFavoriteColor)
  #set($xwikiname = $request.get('xwikiname'))
  #set($userDoc = $xwiki.getDocument("$userSpace$xwikiname"))
  $userDoc.setContent("$userDoc.getContent() ${xwikiname}'s favorite color is $request.get('favorite_color')!")
  ## The user (who is not yet logged in) can't save documents so saveWithProgrammingRights
  ## will save the document as long as the user who last saved this registration page has programming rights.
  $userDoc.saveWithProgrammingRights("Saved favorite color from registration form.")
#end
## *###
## To disable the captcha on this page, comment out the next two entries.
## The captcha image, not an input field but still defined the same way.
#if($captchaservice
    &amp;&amp; !$invited
    &amp;&amp; $xcontext.getUser() == "XWiki.XWikiGuest"
    &amp;&amp; $requireCaptcha)
  ## Empty label field used for padding.
  ## Empty 'name' field overriddes name="captcha_image" with "" so name is not specified at all.
  #set($field = 
    {'name' : 'captcha_image',
      'label' : '',
      'tag' : 'img',
      'params' : {
        'src' : $doc.getURL('imagecaptcha'),
        'alt' : $msg.get('core.captcha.image.alternateText', [$msg.get('core.register.submit')]),
        'name' : ''
      }
    })
  #set($discard = $fields.add($field))
  ## The captcha field, mandatory, programmatically checked to make sure the captcha is right
  ## Not checked by javascript because javascript can't check the captcha and the Ok message because it passes the 
  ## mandatory test is misleading.
  ## and not filled back in if there is an error ('noReturn')
  #set($field = 
    {'name' : 'captcha_answer',
      'label' : $msg.get('core.captcha.image.instruction'),
      'params' : { 
        'type' : 'text', 
        'size' : '30' 
      },
      'validate' : {
        'mandatory' : {
          'failureMessage' : $msg.get('core.captcha.captchaAnswerIsWrong'),
          'noscript' : true
        },
        'programmaticValidation' : {
          'code' : '#checkCaptcha($request, $request.get("captcha_answer"))',
          'failureMessage' : $msg.get('core.captcha.captchaAnswerIsWrong')
        }
      },
      'noReturn' : true
    })
  #set($discard = $fields.add($field))
#end
##
## Checks the captcha answer; used by programmaticValidation above.
#macro(checkCaptcha, $request, $answer)
  #set($cv = $captchaservice.getCaptchaVerifier('image'))
  #if(!$cv.isAnswerCorrect($cv.getUserId($request), $answer))
    failed
  #end
#end
##
## Pass the name of the template to $xwiki.createUser so any contained information will be passed in.
#set($field = 
  {'name' : 'template',
    'params' : {
      'type' : 'hidden',
      'value' : 'XWiki.XWikiUserTemplate'
    }
  })
#set($discard = $fields.add($field))
##
## Pass the redirect parameter on so that the login page may redirect to the right place.
## Not necessary in Firefox 3.0.10 or Opera 9.64, I don't know about IE or Safari.
#set($field = 
  {'name' : $redirectParam,
    'params' : {
      'type' : 'hidden'
    }
  })
#set($discard = $fields.add($field))
##
#######################################################################
## The Code.
#######################################################################
##
#if($useLiveValidation)
  $xwiki.get('jsfx').use('uicomponents/widgets/validation/livevalidation_prototype.js')
  $xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css')
#end
## This application's HTML is dynamically generated and editing in WYSIWYG would not work
#if($xcontext.getAction() == 'edit')
  $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'edit')?editor=wiki")
#end
##
## If this document has PR and is not included from another document then it's author should be set to Guest 
## for the duration of it's execution in order to improve security.
## Note we compare document ids because
#if($sandbox
    &amp;&amp; $xcontext.hasProgrammingRights()
    &amp;&amp; $xcontext.getDoc().getDocumentReference().equals($xwiki.getDocument($documentName).getDocumentReference()))
##
  #set($discard = $xcontext.getDoc().setAuthor('XWiki.XWikiGuest'))
#end
##
## Access level to register must be explicitly checked because it is only checked in XWiki.prepareDocuments
## and this page is accessible through view action.
#if(!$xcontext.hasAccessLevel('register', 'XWiki.XWikiPreferences'))
  ## Make an exception if another document with programming permission (Invitation app) has included this 
  ## document and set $invited to true.
  #if(!$invited || !$xcontext.hasProgrammingRights())
    $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'login')")
  #end
#end
## If this is true, then assume the registration page is being viewed inside of a lightbox
#if($request.get('xpage'))
  #set($assumeLightbox = true)
#end
##
## Display the heading
$heading
## If the submit button has been pressed, then we test the input and maybe create the user.
#if($request.getParameter('xwikiname'))
  ## Do server side validation of input fields.
  #set($discard = "#validateFields($fields, $request)")
  ## If server side validation was successfull, create the user
  #if(!$registrationFailed)
    #createUser($fields, $request, $response, $doAfterRegistration)
  #end
#end
## If the registration was not successful or if the user hasn't submitted the info yet
## Then we display the registration form.
#if(!$registrationDone)
  $welcomeMessage

  {{html clean=false wiki=false}}
    &lt;form id="register" action="" method="post"&gt;
    &lt;div&gt;
    &lt;input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /&gt;
    #generateHtml($fields, $fieldMandatoryStar, $failureMessageParams)
    &lt;div class="wikimodel-emptyline"&gt;&lt;/div&gt;
    &lt;span class="buttonwrapper"&gt;
    #if($assumeLightbox)
      ## LightBox detected...
      &lt;script type="text/javascript"&gt;
        ## Make the X button not reload the page. (overriding LbClose)
        window.lb.lbClose = function() {
          this.lbHide();
          this.lbClearData();
          ##return false;
        }
        ## Post the form entry to the page and load the result. (we override lbSaveForm)
        window.lb.lbSaveForm = function() {
          var formParams = Form.serialize(this.form);
          Form.disable(this.form);
          var ajaxRequest = new Ajax.Request(this.saveUrl, {
            parameters: formParams,
            asynchronous: false
          });
          window.lb.lbFormDataLoaded(ajaxRequest.transport);
        }
      &lt;/script&gt;
      ## It doesn't really matter where these are, the scripts will be relocated to the head.
      &lt;!-- com.xpn.xwiki.plugin.skinx.CssSkinFileExtensionPlugin --&gt;
      &lt;!-- com.xpn.xwiki.plugin.skinx.JsSkinFileExtensionPlugin --&gt;
      ##
      &lt;input class="button" type="submit" value="$msg.get('save')" onclick="window.lb.lbSaveForm();"/&gt;
      &lt;/span&gt;#* End ButtonWrapper then start another...*#&lt;span class="buttonwrapper"&gt;
      &lt;input class="button" type="submit" value="$msg.get("cancel")" onclick="Form.disable(window.lb.form); window.lb.lbClose();"/&gt;
    #else
      ## Not using the LightBox
      &lt;input type="submit" value="$msg.get('core.register.submit')" class="button"/&gt;
    #end
    &lt;/span&gt;## ButtonWrapper
    &lt;/div&gt;
    &lt;/form&gt;
    #if($useLiveValidation)
      #generateJavascript($fields)
    #end
  {{/html}}

  ##
  ## Allow permitted users to configure this application.
  #if($xcontext.getUser() != 'XWiki.XWikiGuest' &amp;&amp; $xcontext.hasAccessLevel("edit", $documentName))
    [[$msg.get('xe.admin.registration.youCanConfigureRegistrationHere')&gt;&gt;XWiki.XWikiPreferences?section=Registration&amp;editor=globaladmin#HCustomizeXWikiRegistration]]
    {{html}}&lt;a href="$xwiki.getURL($documentName, 'edit', 'editor=wiki')"&gt;$msg.get('xe.admin.registration.youCanConfigureRegistrationFieldsHere')&lt;/a&gt;{{/html}}
  #end
## If the registration is done (successful) and we detect the Lightbox simply send the user back to the original page.
#elseif($assumeLightbox)
  {{html clean=false wiki=false}}
    &lt;script type="text/javascript"&gt;
        var url = window.lb.redirectUrl;
        window.lb.lbClose;
        if (url != undefined) {
          if(window.location.pathname + window.location.search == url) {
            ## Under certain circumstances (bug) Opera will not load a page if the location is the same as the current page.
            ## In these cases, location.reload() doesn't work either, the only solution (I could find) was to change the URL.
            window.location.href = url + "&amp;";
          } else {
            window.location.href = url;
          }
        }
    &lt;/script&gt;
  {{/html}}
#end
##
####### The Macros (nothing below this point is run directly) #########
#*
 * Server side validation, this is necessary for security and because not everyone has Javascript
 *
 * @param $fields The array of fields to validate.
 * @param $request An XWikiRequest object which made the register request, used to get parameters.
 *###
#macro(validateFields, $fields, $request)
  #foreach($field in $fields)
    #if($field.get('validate') &amp;&amp; $field.get('name'))
      #set($fieldName = $field.get('name'))
      #set($validate = $field.get('validate'))
      #set($error = '')
      #set($value = $request.get($fieldName))
      #if($value &amp;&amp; $value != '')
        ##
        ## mustMatch validation
        #if($error == '' &amp;&amp; $validate.get('mustMatch'))
          #set($mustMatch = $validate.get('mustMatch'))
          #if($mustMatch.get('name') &amp;&amp; $mustMatch.get('failureMessage'))
            #if($request.get($fieldName) != $request.get($mustMatch.get('name')))
              #set($error = $mustMatch.get('failureMessage'))
            #end
          #else
            ERROR: In field: ${fieldName}: mustMatch validation required both name 
                   (of field which this field must match) and failureMessage.
          #end
        #end
        ##
        ## Regex validation
        ## We won't bother with regex validation if there is no entry, that would defeat the purpose of 'mandatory'
        #if($error == '' &amp;&amp; $validate.get('regex') &amp;&amp; $value &amp;&amp; $value != '')
          #set($regex = $validate.get('regex'))
          #if($regex.get('pattern') &amp;&amp; $regex.get('failureMessage'))
            #if(!$xcontext.getUtil().match($regex.get('pattern'), $value))
              #set($error = $regex.get('failureMessage'))
            #end
          #elseif($regex.get('pattern'))
            ERROR: In field: ${fieldName}: regex validation must include failureMessage.
          #end
        #end
        ##
        ## If regex and mustMatch validation passed, try programmatic validation
        #if($error == '' &amp;&amp; $validate.get('programmaticValidation'))
          #set($pv = $validate.get('programmaticValidation'))
          #if($pv.get('code') &amp;&amp; $pv.get('failureMessage'))
            #set($pvReturn = "#evaluate($pv.get('code'))")
            #if($pvReturn.indexOf('failed') != -1)
              #set($error = $pv.get('failureMessage'))
            #end
          #else
            ERROR: In field: ${fieldName}: programmaticValidation requires code and failureMessage
          #end
        #end
      #else
        ##
        ## If no content, check if content is mandatory
        #if($validate.get('mandatory'))
          #set($mandatory = $validate.get('mandatory'))
          #if($mandatory.get('failureMessage'))
            #set($error = $mandatory.get('failureMessage'))
          #else
            ERROR: In field: ${fieldName}: mandatory validation requires a failureMessage
          #end
        #end
      #end
      #if($error != '')
        #set($discard = $field.put('error', $error))
        #set($registrationFailed = true)
      #end
    #elseif(!$field.get('name'))
      ERROR: Field with no name.
    #end##if(validate)
  #end##loop
#end##macro
#*
 * Create the user.
 * Calls $xwiki.createUser to create a new user.
 *
 * @param $request An XWikiRequest object which made the register request.
 * @param $response The XWikiResponse object to send any redirects to.
 * @param $doAfterRegistration code block to run after registration completes successfully.
 *###
#macro(createUser, $fields, $request, $response, $doAfterRegistration)
  ## CSRF check
  #if(${services.csrf.isTokenValid("$!{request.getParameter('form_token')}")})
    ## See if email verification is required and register the user.
    #if($xwiki.getXWikiPreferenceAsInt('use_email_verification', 0) == 1)
      #set($reg = $xwiki.createUser(true))
    #else
      #set($reg = $xwiki.createUser(false))
    #end
  #else
    $response.sendRedirect("$!{services.csrf.getResubmissionURL()}")
  #end
  ##
  ## Handle output from the registration.
  #if($reg &amp;&amp; $reg &lt;= 0)
    {{error}}
    #if($reg == -2)
      $msg.get('core.register.passwordMismatch')
    ## -3 means username taken, -8 means username is superadmin name
    #elseif($reg == -3 || $reg == -8)
      $msg.get('core.register.userAlreadyExists')
    #elseif($reg == -4)
      $msg.get('core.register.invalidUsername')
    #else
      $msg.get('core.register.registerFailed', [$reg])
    #end
    {{/error}}
  #elseif($reg)
  ## Registration was successful
    #set($registrationDone = true)
    ##
    ## If there is any thing to "doAfterRegistration" then do it.
    #foreach($field in $fields)
      #if($field.get('doAfterRegistration'))
        #evaluate($field.get('doAfterRegistration'))
      #end
    #end
    ## If there is a "global" doAfterRegistration, do that as well.
    #if($doAfterRegistration)
      #set($discard = $doAfterRegistration.toString())
    #end
    ## Define some strings which may be used by autoLogin or loginButton
    #set($userName = $!request.get('xwikiname'))
    #set($password = $!request.get('register_password'))
    #set($loginURL = $xwiki.getURL($loginPage, $loginAction))
    #if($request.getParameter($redirectParam) != '')
      #set($redirect = $request.getParameter($redirectParam))
    #else
      #set($redirect = $defaultRedirect)
    #end
    ## Display a "registration successful" message

    #evaluate($registrationSuccessMessage)

    ## Empty line prevents message from being forced into a &lt;p&gt; block.

    ## Give the user a login button which posts their username and password to loginsubmit
    #if($loginButton)

      {{html clean=false wiki=false}}
        &lt;form id="loginForm" action="$loginURL" method="post"&gt;
          &lt;div&gt;
          &lt;input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /&gt;
          &lt;input id="j_username" name="j_username" type="hidden" value="$escapetool.xml($!userName)" /&gt;
          &lt;input id="j_password" name="j_password" type="hidden" value="$escapetool.xml($!password)" /&gt;
          &lt;input id="$redirectParam" name="$redirectParam" type="hidden" value="$escapetool.xml($redirect)" /&gt;
          &lt;span class="buttonwrapper" style="margin-left:47%;"&gt;
            &lt;input type="submit" value="$msg.get('login')" class="button"/&gt;
          &lt;/span&gt;
          &lt;/div&gt;
        &lt;/form&gt;
        ## We don't want autoLogin if we are administrators adding users...
        #if($autoLogin &amp;&amp; !$assumeLightbox)
          &lt;script type='text/javascript'&gt;
            document.observe('dom:loaded', function() {
              document.forms['loginForm'].submit();
            });
          &lt;/script&gt;
        #end
      {{/html}}

    #end
  #end
  ##
#end## createUser Macro
#*
 * Generate HTML form, this is the only place where HTML is written.
 *
 * @param $fields The array of fields to use for generating html code.
 * @param $fieldMandatoryStar The tag parameters for a * indicating a mandatory field.
 * @param $failureMessageParams The tag parameters for a failure message.
 *###
#macro(generateHtml, $fields, $fieldMandatoryStar, $failureMessageParams)
  ## Put the same values back into the fields.
  #getParams($fields)
  ##
  &lt;dl&gt;
  #foreach($field in $fields)
    #if($field.get('name'))
      #set($fieldName = $field.get('name'))
      #if($field.get('label'))
        #set($label = $field.get('label'))
        &lt;dt&gt;&lt;label for="$fieldName"&gt;$label&lt;/label&gt;
        #if($field.get('validate').get('mandatory'))
          &lt;span ##
          #foreach($entry in $fieldMandatoryStar.entrySet())
            $entry.getKey()="$entry.getValue()" ##
          #end
          &gt;*&lt;/span&gt;
        #end
        &lt;/dt&gt;
      #end
      ## If no tag then default tag is &lt;input&gt;
      #if($field.get('tag'))
        #set($tag = $field.get('tag'))
      #else
        #set($tag = 'input')
      #end
      &lt;dd&gt;&lt;$tag id="$fieldName" ##
      #set($params = $field.get('params'))
      ## If no name parameter is spacified, then we use the field name
      #if(!$params.get('name'))
        #set($discard = $params.put('name', $fieldName))
      #end
      #foreach($entry in $params.entrySet())
        ## If a parameter is specified as '' then we don't include it.
        #if($entry.getValue() != '')
          $entry.getKey()="$escapetool.xml($entry.getValue())" ##
        #end
      #end
      &gt;&lt;/$tag&gt;
      #if($field.get('error'))
        &lt;span ##
        #foreach($entry in $failureMessageParams.entrySet())
          $entry.getKey()="$entry.getValue()" ##
        #end
        &gt;$field.get('error')&lt;/span&gt;
      #end
      &lt;/dd&gt;
    #else
      ERROR: Field with no name.
    #end##if fieldName exists
  #end
  &lt;/dl&gt;
#end
#*
 * Generate the Javascript for interacting with LiveValidation.
 *
 * @param $fields The array of fields which to validate.
 *###
#macro(generateJavascript, $fields)
  &lt;script type='text/javascript'&gt;
  /* &lt;![CDATA[ */
  document.observe('dom:loaded', function() {
  ##
  #foreach($field in $fields)
    #if($field.get('validate') &amp;&amp; $field.get('name'))
      #set($validate = $field.get('validate'))
      #if(($validate.get('mandatory') &amp;&amp; !$validate.get('mandatory').get('noscript'))
          || ($validate.get('regex') &amp;&amp; !$validate.get('regex').get('noscript'))
          || ($validate.get('mustMatch') &amp;&amp; !$validate.get('mustMatch').get('noscript')))
        #set($fieldName = $field.get('name'))
        #if($validate.get('fieldOkayMessage'))
          #set($okayMessage = $validate.get('fieldOkayMessage'))
        #else
          #set($okayMessage = $defaultFieldOkayMessage)
        #end
        var ${fieldName}Validator = new LiveValidation("$fieldName", { validMessage: "$okayMessage", wait: 500} );
        ##
        #if($validate.get('mandatory'))
          #set($mandatory = $validate.get('mandatory'))
          #if($mandatory.get('failureMessage') &amp;&amp; !$mandatory.get('noscript'))
            ${fieldName}Validator.add( Validate.Presence, { failureMessage: "$!mandatory.get('failureMessage')"} );
          #end
        #end
        ##
        #if($validate.get('mustMatch'))
          #set($mustMatch = $validate.get('mustMatch'))
          #if($mustMatch.get('name') &amp;&amp; $mustMatch.get('failureMessage')  &amp;&amp; !$mustMatch.get('noscript'))
            ${fieldName}Validator.add( Validate.Confirmation, { match: $$("input[name=$!mustMatch.get('name')]")[0], failureMessage: "$!mustMatch.get('failureMessage')"} );
          #end
        #end
        ##
        #if($validate.get('regex'))
          #set($regex = $validate.get('regex'))
          #set($pattern = "")
          #if($regex.get('jsPattern'))
            #set($pattern = $regex.get('jsPattern'))
          #elseif($regex.get('pattern'))
            #set($pattern = $regex.get('pattern'))
          #end
          #set($failMessage = "")
          #if($regex.get('jsFailureMessage'))
            #set($failMessage = $regex.get('jsFailureMessage'))
          #elseif($regex.get('failureMessage'))
            #set($failMessage = $regex.get('failureMessage'))
          #end          
          #if($pattern != '' &amp;&amp; $failMessage != '' &amp;&amp; !$regex.get('noscript'))
            ${fieldName}Validator.add( Validate.Format, { pattern: $pattern, failureMessage: "$failMessage"} );
          #end
        #end##if regex
      #end##if contains js validateable fields.
    #end##if validate
  #end##loop
    });// ]]&gt;
    &lt;/script&gt;
#end##macro
#*
 * Get parameters from request so that values will be filled in if there is a mistake
 * in one of the entries. Entries will be returned to fields[n].params.value
 * Fields will not be returned if they have either noReturn or error specified.
 *
 * @param $fields The array of fields to get parameters for.
 *###
#macro(getParams $fields)
  #foreach($field in $fields)
    #if($field.get('name') &amp;&amp; $request.get($field.get('name')))
      #if(!$field.get('noReturn') &amp;&amp; !$field.get('error'))
        #if(!$field.get('params'))
          #set($params = {})
          #set($discard = $field.put('params', $params))
        #else
          #set($params = $field.get('params'))
        #end
        #set($discard = $params.put('value', $request.get($field.get('name'))))
      #end
    #end
  #end
#end
#*
 * Get the configuration from the configuration object.
 *
 * @param $configDocumentName The name of the document to get the configuration from.
 *###
#macro(loadConfig, $configDocumentName)
  #set($configDocument = $xwiki.getDocument($configDocumentName))
  #if(!$configDocument || !$configDocument.getObject($documentName))
    ## No config document, load defaults.
    #set($heading = "= $msg.get('core.register.title') =")
    #set($welcomeMessage = "$msg.get('core.register.welcome')")
    #set($useLiveValidation = true)
    #set($defaultFieldOkayMessage = "$msg.get('xe.admin.registration.fieldOkay')")
    #set($loginButton = true)
    #set($defaultRedirect = "$xwiki.getURL('Main.WebHome')")
    #set($userFullName = "$request.get('register_first_name') $request.get('register_last_name')")
    #set($registrationSuccessMessage = '{{info}}$msg.get("core.register.successful", ["[[$fullName&gt;&gt;$userSpace$userName]]", $userName]){{/info}}')
  #else
    #set($configObject = $configDocument.getObject($documentName))
    #set($heading = "= #evaluate($configObject.getProperty('heading').getValue()) =")
    #set($welcomeMessage = "#evaluate($configObject.getProperty('welcomeMessage').getValue())")
    #if($configObject.getProperty('liveValidation_enabled').getValue() == 1)
      #set($useLiveValidation = true)
    #end
    #set($defaultFieldOkayMessage = "#evaluate($configObject.getProperty('liveValidation_defaultFieldOkMessage').getValue())")
    #if($configObject.getProperty('loginButton_enabled').getValue() == 1)
      #set($loginButton = true)
    #end
    #if($configObject.getProperty('loginButton_autoLogin_enabled').getValue() == 1)
      #set($autoLogin = true)
    #end
    #set($defaultRedirect = "#evaluate($configObject.getProperty('defaultRedirect').getValue())")
    #set($registrationSuccessMessage = "$configObject.getProperty('registrationSuccessMessage').getValue()")
    #if($configObject.getProperty('requireCaptcha').getValue() == 1)
      #set($requireCaptcha = true)
    #end
  #end
#end
{{/velocity}}</content>
</xwikidoc>
<commit_msg>XAADMINISTRATION-178 : Default redirect for registration is never taken into account<commit_after><?xml version="1.0" encoding="UTF-8"?>
<xwikidoc>
<web>XWiki</web>
<name>Registration</name>
<language></language>
<defaultLanguage>en</defaultLanguage>
<translation>0</translation>
<parent>XWiki.WebHome</parent>
<creator>XWiki.Admin</creator>
<author>XWiki.Admin</author>
<customClass></customClass>
<contentAuthor>XWiki.Admin</contentAuthor>
<creationDate>1264284581000</creationDate>
<date>1267024497000</date>
<contentUpdateDate>1267024497000</contentUpdateDate>
<version>1.1</version>
<title>Registration</title>
<template></template>
<defaultTemplate></defaultTemplate>
<validationScript></validationScript>
<comment></comment>
<minorEdit>false</minorEdit>
<syntaxId>xwiki/2.0</syntaxId>
<hidden>false</hidden>
<class>
<name>XWiki.Registration</name>
<customClass></customClass>
<customMapping></customMapping>
<defaultViewSheet></defaultViewSheet>
<defaultEditSheet></defaultEditSheet>
<defaultWeb></defaultWeb>
<nameField></nameField>
<validationScript></validationScript>
<defaultRedirect>
<name>defaultRedirect</name>
<number>7</number>
<picker>0</picker>
<prettyName>Redirect here after registration</prettyName>
<size>30</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.StringClass</classType>
</defaultRedirect>
<heading>
<name>heading</name>
<number>1</number>
<picker>0</picker>
<prettyName>Registration page heading</prettyName>
<size>30</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.StringClass</classType>
</heading>
<liveValidation_defaultFieldOkMessage>
<name>liveValidation_defaultFieldOkMessage</name>
<number>4</number>
<picker>0</picker>
<prettyName>Default field okay message</prettyName>
<size>30</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.StringClass</classType>
</liveValidation_defaultFieldOkMessage>
<liveValidation_enabled>
<defaultValue></defaultValue>
<displayFormType>checkbox</displayFormType>
<displayType></displayType>
<name>liveValidation_enabled</name>
<number>3</number>
<prettyName>Enable Javascript field validation</prettyName>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
</liveValidation_enabled>
<loginButton_autoLogin_enabled>
<defaultValue></defaultValue>
<displayFormType>checkbox</displayFormType>
<displayType></displayType>
<name>loginButton_autoLogin_enabled</name>
<number>6</number>
<prettyName>Enable automatic login</prettyName>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
</loginButton_autoLogin_enabled>
<loginButton_enabled>
<defaultValue></defaultValue>
<displayFormType>checkbox</displayFormType>
<displayType></displayType>
<name>loginButton_enabled</name>
<number>5</number>
<prettyName>Enable login button</prettyName>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
</loginButton_enabled>
<registrationSuccessMessage>
<editor>PureText</editor>
<name>registrationSuccessMessage</name>
<number>9</number>
<picker>0</picker>
<prettyName>Registration Successful Message</prettyName>
<rows>12</rows>
<size>40</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
</registrationSuccessMessage>
<requireCaptcha>
<defaultValue></defaultValue>
<displayFormType>checkbox</displayFormType>
<displayType></displayType>
<name>requireCaptcha</name>
<number>8</number>
<prettyName>Require captcha to register</prettyName>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
</requireCaptcha>
<welcomeMessage>
<editor>PureText</editor>
<name>welcomeMessage</name>
<number>2</number>
<picker>0</picker>
<prettyName>Welcome message</prettyName>
<rows>12</rows>
<size>40</size>
<unmodifiable>0</unmodifiable>
<validationMessage></validationMessage>
<validationRegExp></validationRegExp>
<classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
</welcomeMessage>
</class>
<content>{{velocity}}
## These are defined in other places around XWiki, changing them here will result in undefined behavior.
#set($redirectParam = 'xredirect')
#set($userSpace = 'XWiki.')
#set($loginPage = 'XWiki.XWikiLogin')
#set($loginAction = 'loginsubmit')
##
#set($documentName = 'XWiki.Registration')
##
## Security measure: 
## If this document is changed such that it must have programming permission in order to run, change this to false.
#set($sandbox = true)
##
## Load the configuration from a seperate document.
#loadConfig('XWiki.RegistrationConfig')
##
## Defines what server generated error messages should look like
## The error message when a field is entered incorrectly
#set($failureMessageParams = { 'class' : 'LV_validation_message LV_invalid'})
## 'LV_validation_message LV_invalid' depends on this:
$xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css')
##
## The * next to the fields to denote they are mandatory.
#set($fieldMandatoryStar = $failureMessageParams)
##
#*
 * You may include this document in other documents using {{include document="XWiki.Registration"/}}
 * To specify that the user is invited and should be allowed to register even if Guest does not have permission to
 * register, set $invited to true. NOTE: The including script must have programming permission to do this.
 *
 * To specify some code which should run after registration is successfully completed, set
 * $doAfterRegistration to a define block of velocity code like so:
 * #define($doAfterRegistration)
 *   some code
 * #end
 * Output from running this code will not be printed.
 *
 * The fields which will be seen on the registration page are defined here.
 * $fields is an array and each field is a Map. The names shown below are Map keys.
 * 
 * Each field must have:
 *   name - this is the name of the field, it will be the value for "name" and "id"
 * 
 * Each field may have:
 *   label - this String will be written above the field.
 *
 *   tag - the HTML tag which will be created, default is &lt;input&gt;, may also be a non form tag such as &lt;img&gt;
 *
 *   params - a Map, each key value pair will be in the html tag. eg: {"size" : "30"} becomes &lt;input size=30...
 *
 *   validate a Map describing how to validate the field, validation is done in javascript then redone in velocity
 *   |        for security and because not everyone has javascript.
 *   |
 *   +-mandatory (Optional) - Will fail if the field is not filled in.
 *   | +-failureMessage (Required) - The message to display if the field is not filled in.
 *   | +-noscript (Optional) - will not be checked by javascript
 *   |
 *   +-regex (Optional) - Will validate the field using a regular expression.
 *   | |                  because of character escaping, you must provide a different expression for the
 *   | |                  javascript validation and the server side validation. Both javascript and server side
 *   | |                  validation are optional, but if you provide neither, then your field will not be validated.
 *   | |
 *   | +-failureMessage (Optional) - The message to display if the regex evaluation returns false.
 *   | +-jsFailureMessage (Optional) - The message for Javascript to display if regex fails. 
 *   | |                               If jsFailureMessage is not defined Javascript uses failureMessage.
 *   | |                               NOTE: Javascript injects the failure message using createTextNode so &amp;lt; will
 *   | |                                     be displayed as &amp;lt;
 *   | |
 *   | +-pattern (Optional) - The regular expression to test the input at the server side, it's important to use
 *   | |                      this if you need to validate the field for security reasons, also it is good because not
 *   | |                      all browsers use javascript or have it enabled.
 *   | |
 *   | +-jsPattern (Optional) - The regular expression to use for client side, you can use escaped characters to avoid
 *   | |                        them being parsed as HTML or javascript. To get javascript to unescape characters use:
 *   | |                        {"jsPattern" : "'+unescape('%5E%5B%24')+'"}
 *   | |                        NOTE: If no jsPattern is specified, the jsValidator will try to validate 
 *   | |                              using the server pattern.
 *   | |
 *   | +-noscript (Optional) - will not be checked by javascript
 *   |
 *   +-mustMatch (Optional) - Will fail if the entry into the field is not the same as the entry in another field.
 *   | |                      Good for password confirmation.
 *   | |
 *   | +-failureMessage (Required) - The message to display if the field doesn't match the named field.
 *   | +-name (Required) - The name of the field which this field must match.
 *   | +-noscript (Optional) - will not be checked by javascript
 *   |
 *   +-programmaticValidation (Optional) - This form of validation executes a piece of code which you give it and
 *   | |                                   if the code returns the word "failed" then it gives the error message.
 *   | |                                   Remember to put the code in singel quotes ('') because you want the value
 *   | |                                   of 'code' to equal the literal code, not the output from running it.
 *   | |
 *   | +-code (Required) - The code which will be executed to test whether the field is filled in correctly.
 *   | +-failureMessage (Required) - The message which will be displayed if evaluating the code returns "false"
 *   |
 *   +-fieldOkayMessage (Optional) - The message which is displayed by LiveValidation when a field is validated as okay.
 *                                   If not specified, will be $defaultFieldOkayMessage
 *  
 *   noReturn - If this is specified, the field will not be filled in if there is an error and the user has to fix their
 *              registration information. If you don't want a password to be passed back in html then set this true
 *              for the password fields. Used for the captcha because it makes no sense to pass back a captcha answer.
 *  
 *   doAfterRegistration - Some Velocity code which will be executed after a successfull registration. 
 *                         This is used in the favorite color example.
 *                         Remember to put the code in singel quotes ('') because you want the 'code' entry to equal the literal
 *                         code, not the output from running it.
 *  
 * Each field may not have: (reserved names)
 *   error - This is used to pass back any error message from the server side code.
 *
 * NOTE: This template uses a registration method which requires:
 *        * register_first_name
 *        * register_last_name
 *        * xwikiname
 *        * register_password
 *        * register2_password
 *        * register_email
 *        * template
 *       Removing or renaming any of these fields will result in undefined behavior.
 *
 *###
#set($fields = [])
##
## The first name field, no checking.
#set($field = 
  {'name' : 'register_first_name',
    'label' : $msg.get('core.register.firstName'),
    'params' : { 
      'type' : 'text', 
      'size' : '30' 
    }
  })
#set($discard = $fields.add($field))
##
## The last name field, no checking.
#set($field = 
  {'name' : 'register_last_name',
    'label' : $msg.get('core.register.lastName'),
    'params' : { 
      'type' : 'text', 
      'size' : '30' 
    }
  })
#set($discard = $fields.add($field))
##
## The user name field, mandatory and programmatically checked to make sure the username doesn't exist.
#set($field = 
  {'name' : 'xwikiname',
    'label' : $msg.get('core.register.username'),
    'params' : {
      'type' : 'text',
      'onfocus' : 'prepareName(document.forms.register);',
      'size' : '20'
    },
    'validate' : {
      'mandatory' : { 
        'failureMessage' : $msg.get('xe.admin.registration.fieldMandatory') 
      },
      'programmaticValidation' : {
        'code' : '#nameAvailable($request.get("xwikiname"))',
        'failureMessage' : $msg.get('core.register.userAlreadyExists')
      }
    }
  })
#set($discard = $fields.add($field))
## Make sure the chosen user name is not already taken
## This macro is called by programmaticValidation for xwikiname (above)
#macro(nameAvailable, $name)
  #if($xwiki.exists("$userSpace$name"))
    failed
  #end
#end
##
##The password field, mandatory and must be at least 6 characters long.
#set($field = 
  {'name' : 'register_password',
    'label' : $msg.get('core.register.password'),
    'params' : {
      'type' : 'password',
      'size' : '10'
    },
    'validate' : {
      'mandatory' : { 
        'failureMessage' : $msg.get('xe.admin.registration.fieldMandatory') 
      },
      'regex' : {
        'pattern' : '/.{6,}/',
        'failureMessage' : $msg.get('xe.admin.registration.passwordTooShort')
      }
    }
  })
#set($discard = $fields.add($field))
##
##The confirm password field, mandatory, must match password field, and must also be 6+ characters long.
#set($field = 
  {'name' : 'register2_password',
    'label' : $msg.get('core.register.passwordRepeat'),
    'params' : {
      'type' : 'password',
      'size' : '10'
    },
    'validate' : {
      'mandatory' : { 
        'failureMessage' : $msg.get('xe.admin.registration.fieldMandatory') 
      },
      'mustMatch' : {
        'name' : 'register_password',
        'failureMessage' : $msg.get('xe.admin.registration.passwordMismatch')
      },
      'regex' : {
        'pattern' : '/.{6,}/',
        'failureMessage' : $msg.get('xe.admin.registration.passwordTooShort')
      }
    }
  })
#set($discard = $fields.add($field))
##
## The email address field, regex checked with an email pattern.
#set($field = 
  {'name' : 'register_email',
    'label' : $msg.get('core.register.email'),
    'params' : { 
      'type' : 'text', 
      'size' : '30' 
    },
    'validate' : {
      'regex' : {
        'pattern' : '/^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/',
        'failureMessage' : $msg.get('xe.admin.registration.invalidEmail')
      }
    }
  })
#set($discard = $fields.add($field))
##
#* ## Uncomment this code to see an example of how you can easily add a field to the registration page
## Note: The user's favorite color is not saved anywhere, see above for information on how to save it.
#set($field = 
  {'name' : 'favorite_color',
    'label' : 'What is your favorite color',
    'params' : {
      'type' : 'text',
      'size' : '25'
    },
    'validate' : {
      'mandatory' : {
        'failureMessage' : $msg.get('xe.admin.registration.fieldMandatory')
      },
      'regex' : {
        'pattern' : '/^green$/i',
        'failureMessage' : 'You are not cool enough to register here.'
      },
      'fieldOkayMessage' : 'You are awesome.'
    },
    'doAfterRegistration' : '#saveFavoriteColor()'
  })
#set($discard = $fields.add($field))
## Save the user's favorite color on their user page.
#macro(saveFavoriteColor)
  #set($xwikiname = $request.get('xwikiname'))
  #set($userDoc = $xwiki.getDocument("$userSpace$xwikiname"))
  $userDoc.setContent("$userDoc.getContent() ${xwikiname}'s favorite color is $request.get('favorite_color')!")
  ## The user (who is not yet logged in) can't save documents so saveWithProgrammingRights
  ## will save the document as long as the user who last saved this registration page has programming rights.
  $userDoc.saveWithProgrammingRights("Saved favorite color from registration form.")
#end
## *###
## To disable the captcha on this page, comment out the next two entries.
## The captcha image, not an input field but still defined the same way.
#if($captchaservice
    &amp;&amp; !$invited
    &amp;&amp; $xcontext.getUser() == "XWiki.XWikiGuest"
    &amp;&amp; $requireCaptcha)
  ## Empty label field used for padding.
  ## Empty 'name' field overriddes name="captcha_image" with "" so name is not specified at all.
  #set($field = 
    {'name' : 'captcha_image',
      'label' : '',
      'tag' : 'img',
      'params' : {
        'src' : $doc.getURL('imagecaptcha'),
        'alt' : $msg.get('core.captcha.image.alternateText', [$msg.get('core.register.submit')]),
        'name' : ''
      }
    })
  #set($discard = $fields.add($field))
  ## The captcha field, mandatory, programmatically checked to make sure the captcha is right
  ## Not checked by javascript because javascript can't check the captcha and the Ok message because it passes the 
  ## mandatory test is misleading.
  ## and not filled back in if there is an error ('noReturn')
  #set($field = 
    {'name' : 'captcha_answer',
      'label' : $msg.get('core.captcha.image.instruction'),
      'params' : { 
        'type' : 'text', 
        'size' : '30' 
      },
      'validate' : {
        'mandatory' : {
          'failureMessage' : $msg.get('core.captcha.captchaAnswerIsWrong'),
          'noscript' : true
        },
        'programmaticValidation' : {
          'code' : '#checkCaptcha($request, $request.get("captcha_answer"))',
          'failureMessage' : $msg.get('core.captcha.captchaAnswerIsWrong')
        }
      },
      'noReturn' : true
    })
  #set($discard = $fields.add($field))
#end
##
## Checks the captcha answer; used by programmaticValidation above.
#macro(checkCaptcha, $request, $answer)
  #set($cv = $captchaservice.getCaptchaVerifier('image'))
  #if(!$cv.isAnswerCorrect($cv.getUserId($request), $answer))
    failed
  #end
#end
##
## Pass the name of the template to $xwiki.createUser so any contained information will be passed in.
#set($field = 
  {'name' : 'template',
    'params' : {
      'type' : 'hidden',
      'value' : 'XWiki.XWikiUserTemplate'
    }
  })
#set($discard = $fields.add($field))
##
## Pass the redirect parameter on so that the login page may redirect to the right place.
## Not necessary in Firefox 3.0.10 or Opera 9.64, I don't know about IE or Safari.
#set($field = 
  {'name' : $redirectParam,
    'params' : {
      'type' : 'hidden'
    }
  })
#set($discard = $fields.add($field))
##
#######################################################################
## The Code.
#######################################################################
##
#if($useLiveValidation)
  $xwiki.get('jsfx').use('uicomponents/widgets/validation/livevalidation_prototype.js')
  $xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css')
#end
## This application's HTML is dynamically generated and editing in WYSIWYG would not work
#if($xcontext.getAction() == 'edit')
  $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'edit')?editor=wiki")
#end
##
## If this document has PR and is not included from another document then it's author should be set to Guest 
## for the duration of it's execution in order to improve security.
## Note we compare document ids because
#if($sandbox
    &amp;&amp; $xcontext.hasProgrammingRights()
    &amp;&amp; $xcontext.getDoc().getDocumentReference().equals($xwiki.getDocument($documentName).getDocumentReference()))
##
  #set($discard = $xcontext.getDoc().setAuthor('XWiki.XWikiGuest'))
#end
##
## Access level to register must be explicitly checked because it is only checked in XWiki.prepareDocuments
## and this page is accessible through view action.
#if(!$xcontext.hasAccessLevel('register', 'XWiki.XWikiPreferences'))
  ## Make an exception if another document with programming permission (Invitation app) has included this 
  ## document and set $invited to true.
  #if(!$invited || !$xcontext.hasProgrammingRights())
    $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'login')")
  #end
#end
## If this is true, then assume the registration page is being viewed inside of a lightbox
#if($request.get('xpage'))
  #set($assumeLightbox = true)
#end
##
## Display the heading
$heading
## If the submit button has been pressed, then we test the input and maybe create the user.
#if($request.getParameter('xwikiname'))
  ## Do server side validation of input fields.
  #set($discard = "#validateFields($fields, $request)")
  ## If server side validation was successfull, create the user
  #if(!$registrationFailed)
    #createUser($fields, $request, $response, $doAfterRegistration)
  #end
#end
## If the registration was not successful or if the user hasn't submitted the info yet
## Then we display the registration form.
#if(!$registrationDone)
  $welcomeMessage

  {{html clean=false wiki=false}}
    &lt;form id="register" action="" method="post"&gt;
    &lt;div&gt;
    &lt;input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /&gt;
    #generateHtml($fields, $fieldMandatoryStar, $failureMessageParams)
    &lt;div class="wikimodel-emptyline"&gt;&lt;/div&gt;
    &lt;span class="buttonwrapper"&gt;
    #if($assumeLightbox)
      ## LightBox detected...
      &lt;script type="text/javascript"&gt;
        ## Make the X button not reload the page. (overriding LbClose)
        window.lb.lbClose = function() {
          this.lbHide();
          this.lbClearData();
          ##return false;
        }
        ## Post the form entry to the page and load the result. (we override lbSaveForm)
        window.lb.lbSaveForm = function() {
          var formParams = Form.serialize(this.form);
          Form.disable(this.form);
          var ajaxRequest = new Ajax.Request(this.saveUrl, {
            parameters: formParams,
            asynchronous: false
          });
          window.lb.lbFormDataLoaded(ajaxRequest.transport);
        }
      &lt;/script&gt;
      ## It doesn't really matter where these are, the scripts will be relocated to the head.
      &lt;!-- com.xpn.xwiki.plugin.skinx.CssSkinFileExtensionPlugin --&gt;
      &lt;!-- com.xpn.xwiki.plugin.skinx.JsSkinFileExtensionPlugin --&gt;
      ##
      &lt;input class="button" type="submit" value="$msg.get('save')" onclick="window.lb.lbSaveForm();"/&gt;
      &lt;/span&gt;#* End ButtonWrapper then start another...*#&lt;span class="buttonwrapper"&gt;
      &lt;input class="button" type="submit" value="$msg.get("cancel")" onclick="Form.disable(window.lb.form); window.lb.lbClose();"/&gt;
    #else
      ## Not using the LightBox
      &lt;input type="submit" value="$msg.get('core.register.submit')" class="button"/&gt;
    #end
    &lt;/span&gt;## ButtonWrapper
    &lt;/div&gt;
    &lt;/form&gt;
    #if($useLiveValidation)
      #generateJavascript($fields)
    #end
  {{/html}}

  ##
  ## Allow permitted users to configure this application.
  #if($xcontext.getUser() != 'XWiki.XWikiGuest' &amp;&amp; $xcontext.hasAccessLevel("edit", $documentName))
    [[$msg.get('xe.admin.registration.youCanConfigureRegistrationHere')&gt;&gt;XWiki.XWikiPreferences?section=Registration&amp;editor=globaladmin#HCustomizeXWikiRegistration]]
    {{html}}&lt;a href="$xwiki.getURL($documentName, 'edit', 'editor=wiki')"&gt;$msg.get('xe.admin.registration.youCanConfigureRegistrationFieldsHere')&lt;/a&gt;{{/html}}
  #end
## If the registration is done (successful) and we detect the Lightbox simply send the user back to the original page.
#elseif($assumeLightbox)
  {{html clean=false wiki=false}}
    &lt;script type="text/javascript"&gt;
        var url = window.lb.redirectUrl;
        window.lb.lbClose;
        if (url != undefined) {
          if(window.location.pathname + window.location.search == url) {
            ## Under certain circumstances (bug) Opera will not load a page if the location is the same as the current page.
            ## In these cases, location.reload() doesn't work either, the only solution (I could find) was to change the URL.
            window.location.href = url + "&amp;";
          } else {
            window.location.href = url;
          }
        }
    &lt;/script&gt;
  {{/html}}
#end
##
####### The Macros (nothing below this point is run directly) #########
#*
 * Server side validation, this is necessary for security and because not everyone has Javascript
 *
 * @param $fields The array of fields to validate.
 * @param $request An XWikiRequest object which made the register request, used to get parameters.
 *###
#macro(validateFields, $fields, $request)
  #foreach($field in $fields)
    #if($field.get('validate') &amp;&amp; $field.get('name'))
      #set($fieldName = $field.get('name'))
      #set($validate = $field.get('validate'))
      #set($error = '')
      #set($value = $request.get($fieldName))
      #if($value &amp;&amp; $value != '')
        ##
        ## mustMatch validation
        #if($error == '' &amp;&amp; $validate.get('mustMatch'))
          #set($mustMatch = $validate.get('mustMatch'))
          #if($mustMatch.get('name') &amp;&amp; $mustMatch.get('failureMessage'))
            #if($request.get($fieldName) != $request.get($mustMatch.get('name')))
              #set($error = $mustMatch.get('failureMessage'))
            #end
          #else
            ERROR: In field: ${fieldName}: mustMatch validation required both name 
                   (of field which this field must match) and failureMessage.
          #end
        #end
        ##
        ## Regex validation
        ## We won't bother with regex validation if there is no entry, that would defeat the purpose of 'mandatory'
        #if($error == '' &amp;&amp; $validate.get('regex') &amp;&amp; $value &amp;&amp; $value != '')
          #set($regex = $validate.get('regex'))
          #if($regex.get('pattern') &amp;&amp; $regex.get('failureMessage'))
            #if(!$xcontext.getUtil().match($regex.get('pattern'), $value))
              #set($error = $regex.get('failureMessage'))
            #end
          #elseif($regex.get('pattern'))
            ERROR: In field: ${fieldName}: regex validation must include failureMessage.
          #end
        #end
        ##
        ## If regex and mustMatch validation passed, try programmatic validation
        #if($error == '' &amp;&amp; $validate.get('programmaticValidation'))
          #set($pv = $validate.get('programmaticValidation'))
          #if($pv.get('code') &amp;&amp; $pv.get('failureMessage'))
            #set($pvReturn = "#evaluate($pv.get('code'))")
            #if($pvReturn.indexOf('failed') != -1)
              #set($error = $pv.get('failureMessage'))
            #end
          #else
            ERROR: In field: ${fieldName}: programmaticValidation requires code and failureMessage
          #end
        #end
      #else
        ##
        ## If no content, check if content is mandatory
        #if($validate.get('mandatory'))
          #set($mandatory = $validate.get('mandatory'))
          #if($mandatory.get('failureMessage'))
            #set($error = $mandatory.get('failureMessage'))
          #else
            ERROR: In field: ${fieldName}: mandatory validation requires a failureMessage
          #end
        #end
      #end
      #if($error != '')
        #set($discard = $field.put('error', $error))
        #set($registrationFailed = true)
      #end
    #elseif(!$field.get('name'))
      ERROR: Field with no name.
    #end##if(validate)
  #end##loop
#end##macro
#*
 * Create the user.
 * Calls $xwiki.createUser to create a new user.
 *
 * @param $request An XWikiRequest object which made the register request.
 * @param $response The XWikiResponse object to send any redirects to.
 * @param $doAfterRegistration code block to run after registration completes successfully.
 *###
#macro(createUser, $fields, $request, $response, $doAfterRegistration)
  ## CSRF check
  #if(${services.csrf.isTokenValid("$!{request.getParameter('form_token')}")})
    ## See if email verification is required and register the user.
    #if($xwiki.getXWikiPreferenceAsInt('use_email_verification', 0) == 1)
      #set($reg = $xwiki.createUser(true))
    #else
      #set($reg = $xwiki.createUser(false))
    #end
  #else
    $response.sendRedirect("$!{services.csrf.getResubmissionURL()}")
  #end
  ##
  ## Handle output from the registration.
  #if($reg &amp;&amp; $reg &lt;= 0)
    {{error}}
    #if($reg == -2)
      $msg.get('core.register.passwordMismatch')
    ## -3 means username taken, -8 means username is superadmin name
    #elseif($reg == -3 || $reg == -8)
      $msg.get('core.register.userAlreadyExists')
    #elseif($reg == -4)
      $msg.get('core.register.invalidUsername')
    #else
      $msg.get('core.register.registerFailed', [$reg])
    #end
    {{/error}}
  #elseif($reg)
  ## Registration was successful
    #set($registrationDone = true)
    ##
    ## If there is any thing to "doAfterRegistration" then do it.
    #foreach($field in $fields)
      #if($field.get('doAfterRegistration'))
        #evaluate($field.get('doAfterRegistration'))
      #end
    #end
    ## If there is a "global" doAfterRegistration, do that as well.
    #if($doAfterRegistration)
      #set($discard = $doAfterRegistration.toString())
    #end
    ## Define some strings which may be used by autoLogin or loginButton
    #set($userName = $!request.get('xwikiname'))
    #set($password = $!request.get('register_password'))
    #set($loginURL = $xwiki.getURL($loginPage, $loginAction))
    #if("$!request.getParameter($redirectParam)" != '')
      #set($redirect = $request.getParameter($redirectParam))
    #else
      #set($redirect = $defaultRedirect)
    #end
    ## Display a "registration successful" message

    #evaluate($registrationSuccessMessage)

    ## Empty line prevents message from being forced into a &lt;p&gt; block.

    ## Give the user a login button which posts their username and password to loginsubmit
    #if($loginButton)

      {{html clean=false wiki=false}}
        &lt;form id="loginForm" action="$loginURL" method="post"&gt;
          &lt;div&gt;
          &lt;input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /&gt;
          &lt;input id="j_username" name="j_username" type="hidden" value="$escapetool.xml($!userName)" /&gt;
          &lt;input id="j_password" name="j_password" type="hidden" value="$escapetool.xml($!password)" /&gt;
          &lt;input id="$redirectParam" name="$redirectParam" type="hidden" value="$escapetool.xml($redirect)" /&gt;
          &lt;span class="buttonwrapper" style="margin-left:47%;"&gt;
            &lt;input type="submit" value="$msg.get('login')" class="button"/&gt;
          &lt;/span&gt;
          &lt;/div&gt;
        &lt;/form&gt;
        ## We don't want autoLogin if we are administrators adding users...
        #if($autoLogin &amp;&amp; !$assumeLightbox)
          &lt;script type='text/javascript'&gt;
            document.observe('dom:loaded', function() {
              document.forms['loginForm'].submit();
            });
          &lt;/script&gt;
        #end
      {{/html}}

    #end
  #end
  ##
#end## createUser Macro
#*
 * Generate HTML form, this is the only place where HTML is written.
 *
 * @param $fields The array of fields to use for generating html code.
 * @param $fieldMandatoryStar The tag parameters for a * indicating a mandatory field.
 * @param $failureMessageParams The tag parameters for a failure message.
 *###
#macro(generateHtml, $fields, $fieldMandatoryStar, $failureMessageParams)
  ## Put the same values back into the fields.
  #getParams($fields)
  ##
  &lt;dl&gt;
  #foreach($field in $fields)
    #if($field.get('name'))
      #set($fieldName = $field.get('name'))
      #if($field.get('label'))
        #set($label = $field.get('label'))
        &lt;dt&gt;&lt;label for="$fieldName"&gt;$label&lt;/label&gt;
        #if($field.get('validate').get('mandatory'))
          &lt;span ##
          #foreach($entry in $fieldMandatoryStar.entrySet())
            $entry.getKey()="$entry.getValue()" ##
          #end
          &gt;*&lt;/span&gt;
        #end
        &lt;/dt&gt;
      #end
      ## If no tag then default tag is &lt;input&gt;
      #if($field.get('tag'))
        #set($tag = $field.get('tag'))
      #else
        #set($tag = 'input')
      #end
      &lt;dd&gt;&lt;$tag id="$fieldName" ##
      #set($params = $field.get('params'))
      ## If no name parameter is spacified, then we use the field name
      #if(!$params.get('name'))
        #set($discard = $params.put('name', $fieldName))
      #end
      #foreach($entry in $params.entrySet())
        ## If a parameter is specified as '' then we don't include it.
        #if($entry.getValue() != '')
          $entry.getKey()="$escapetool.xml($entry.getValue())" ##
        #end
      #end
      &gt;&lt;/$tag&gt;
      #if($field.get('error'))
        &lt;span ##
        #foreach($entry in $failureMessageParams.entrySet())
          $entry.getKey()="$entry.getValue()" ##
        #end
        &gt;$field.get('error')&lt;/span&gt;
      #end
      &lt;/dd&gt;
    #else
      ERROR: Field with no name.
    #end##if fieldName exists
  #end
  &lt;/dl&gt;
#end
#*
 * Generate the Javascript for interacting with LiveValidation.
 *
 * @param $fields The array of fields which to validate.
 *###
#macro(generateJavascript, $fields)
  &lt;script type='text/javascript'&gt;
  /* &lt;![CDATA[ */
  document.observe('dom:loaded', function() {
  ##
  #foreach($field in $fields)
    #if($field.get('validate') &amp;&amp; $field.get('name'))
      #set($validate = $field.get('validate'))
      #if(($validate.get('mandatory') &amp;&amp; !$validate.get('mandatory').get('noscript'))
          || ($validate.get('regex') &amp;&amp; !$validate.get('regex').get('noscript'))
          || ($validate.get('mustMatch') &amp;&amp; !$validate.get('mustMatch').get('noscript')))
        #set($fieldName = $field.get('name'))
        #if($validate.get('fieldOkayMessage'))
          #set($okayMessage = $validate.get('fieldOkayMessage'))
        #else
          #set($okayMessage = $defaultFieldOkayMessage)
        #end
        var ${fieldName}Validator = new LiveValidation("$fieldName", { validMessage: "$okayMessage", wait: 500} );
        ##
        #if($validate.get('mandatory'))
          #set($mandatory = $validate.get('mandatory'))
          #if($mandatory.get('failureMessage') &amp;&amp; !$mandatory.get('noscript'))
            ${fieldName}Validator.add( Validate.Presence, { failureMessage: "$!mandatory.get('failureMessage')"} );
          #end
        #end
        ##
        #if($validate.get('mustMatch'))
          #set($mustMatch = $validate.get('mustMatch'))
          #if($mustMatch.get('name') &amp;&amp; $mustMatch.get('failureMessage')  &amp;&amp; !$mustMatch.get('noscript'))
            ${fieldName}Validator.add( Validate.Confirmation, { match: $$("input[name=$!mustMatch.get('name')]")[0], failureMessage: "$!mustMatch.get('failureMessage')"} );
          #end
        #end
        ##
        #if($validate.get('regex'))
          #set($regex = $validate.get('regex'))
          #set($pattern = "")
          #if($regex.get('jsPattern'))
            #set($pattern = $regex.get('jsPattern'))
          #elseif($regex.get('pattern'))
            #set($pattern = $regex.get('pattern'))
          #end
          #set($failMessage = "")
          #if($regex.get('jsFailureMessage'))
            #set($failMessage = $regex.get('jsFailureMessage'))
          #elseif($regex.get('failureMessage'))
            #set($failMessage = $regex.get('failureMessage'))
          #end          
          #if($pattern != '' &amp;&amp; $failMessage != '' &amp;&amp; !$regex.get('noscript'))
            ${fieldName}Validator.add( Validate.Format, { pattern: $pattern, failureMessage: "$failMessage"} );
          #end
        #end##if regex
      #end##if contains js validateable fields.
    #end##if validate
  #end##loop
    });// ]]&gt;
    &lt;/script&gt;
#end##macro
#*
 * Get parameters from request so that values will be filled in if there is a mistake
 * in one of the entries. Entries will be returned to fields[n].params.value
 * Fields will not be returned if they have either noReturn or error specified.
 *
 * @param $fields The array of fields to get parameters for.
 *###
#macro(getParams $fields)
  #foreach($field in $fields)
    #if($field.get('name') &amp;&amp; $request.get($field.get('name')))
      #if(!$field.get('noReturn') &amp;&amp; !$field.get('error'))
        #if(!$field.get('params'))
          #set($params = {})
          #set($discard = $field.put('params', $params))
        #else
          #set($params = $field.get('params'))
        #end
        #set($discard = $params.put('value', $request.get($field.get('name'))))
      #end
    #end
  #end
#end
#*
 * Get the configuration from the configuration object.
 *
 * @param $configDocumentName The name of the document to get the configuration from.
 *###
#macro(loadConfig, $configDocumentName)
  #set($configDocument = $xwiki.getDocument($configDocumentName))
  #if(!$configDocument || !$configDocument.getObject($documentName))
    ## No config document, load defaults.
    #set($heading = "= $msg.get('core.register.title') =")
    #set($welcomeMessage = "$msg.get('core.register.welcome')")
    #set($useLiveValidation = true)
    #set($defaultFieldOkayMessage = "$msg.get('xe.admin.registration.fieldOkay')")
    #set($loginButton = true)
    #set($defaultRedirect = "$xwiki.getURL('Main.WebHome')")
    #set($userFullName = "$request.get('register_first_name') $request.get('register_last_name')")
    #set($registrationSuccessMessage = '{{info}}$msg.get("core.register.successful", ["[[$fullName&gt;&gt;$userSpace$userName]]", $userName]){{/info}}')
  #else
    #set($configObject = $configDocument.getObject($documentName))
    #set($heading = "= #evaluate($configObject.getProperty('heading').getValue()) =")
    #set($welcomeMessage = "#evaluate($configObject.getProperty('welcomeMessage').getValue())")
    #if($configObject.getProperty('liveValidation_enabled').getValue() == 1)
      #set($useLiveValidation = true)
    #end
    #set($defaultFieldOkayMessage = "#evaluate($configObject.getProperty('liveValidation_defaultFieldOkMessage').getValue())")
    #if($configObject.getProperty('loginButton_enabled').getValue() == 1)
      #set($loginButton = true)
    #end
    #if($configObject.getProperty('loginButton_autoLogin_enabled').getValue() == 1)
      #set($autoLogin = true)
    #end
    #set($defaultRedirect = "#evaluate($configObject.getProperty('defaultRedirect').getValue())")
    #set($registrationSuccessMessage = "$configObject.getProperty('registrationSuccessMessage').getValue()")
    #if($configObject.getProperty('requireCaptcha').getValue() == 1)
      #set($requireCaptcha = true)
    #end
  #end
#end
{{/velocity}}</content>
</xwikidoc>

{'fraction_non_alphanumeric': 0.1538510714468368, 'fraction_numerical': 0.003720656676724799, 'mean_word_length': 3.484690366972477, 'pattern_counts': {'":': 0, '<': 529, '<?xml version=': 2, '>': 529, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6273813', 'n_tokens_mistral': 23725, 'n_tokens_neox': 23097, 'n_words': 5951}