Skip to content

Commit 7d23c54

Browse files
authored
Merge pull request #94 from noi-techpark/feature/registerformadaptations
applying changes to register form
2 parents fbd44e5 + 811dcbf commit 7d23c54

File tree

9 files changed

+402
-6
lines changed

9 files changed

+402
-6
lines changed

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ services:
2323
volumes:
2424
- ./themes/sankt-virtual:/opt/keycloak/themes/sankt-virtual
2525
- ./themes/noiV2:/opt/keycloak/themes/noiV2
26+
- ./themes/noi-community:/opt/keycloak/themes/noi-community
2627
- ./native-s3-ping/target/native-s3-ping-jar-with-dependencies.jar:/opt/keycloak/providers/native-s3-ping-jar-with-dependencies.jar
2728
- ./registration-event-listener/target/registration-event-listener.jar:/opt/keycloak/providers/registration-event-listener.jar
2829
healthcheck:

themes/noi-community/login/messages/messages_de.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
# default values https://github.com/keycloak/keycloak/blob/main/themes/src/main/resources/theme/base/login/messages/messages_en.properties
33
identity-provider-login-label=Oder melde dich an mit
44
noAccount=Neu hier?
5-
doRegister=Jetzt registrieren
5+
doRegister=Jetzt registrieren
6+
registerAdditionaltext=(con cui sei iscritto/a alla NOI-Community)

themes/noi-community/login/messages/messages_en.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
# default values https://github.com/keycloak/keycloak/blob/main/themes/src/main/resources/theme/base/login/messages/messages_en.properties
33
identity-provider-login-label=Or sign in with
44
noAccount=New here?
5-
doRegister=Register now
5+
doRegister=Register now
6+
registerAdditionaltext=(you used to register in the NOI-Community)

themes/noi-community/login/messages/messages_it.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
# default values https://github.com/keycloak/keycloak/blob/main/themes/src/main/resources/theme/base/login/messages/messages_en.properties
33
identity-provider-login-label=o fai login tramite
44
noAccount=Primo accesso?
5-
doRegister=Registrati
5+
doRegister=Registrati
6+
registerAdditionaltext=(mit der du in der NOI-Community registriert bist)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<#macro termsAcceptance>
2+
<#if termsAcceptanceRequired??>
3+
<div class="form-group">
4+
<div class="${properties.kcInputWrapperClass!}">
5+
${msg("termsTitle")}
6+
<div id="kc-registration-terms-text">
7+
${kcSanitize(msg("termsText"))?no_esc}
8+
</div>
9+
</div>
10+
</div>
11+
<div class="form-group">
12+
<div class="${properties.kcLabelWrapperClass!}">
13+
<input type="checkbox" id="termsAccepted" name="termsAccepted" class="${properties.kcCheckboxInputClass!}"
14+
aria-invalid="<#if messagesPerField.existsError('termsAccepted')>true</#if>"
15+
/>
16+
<label for="termsAccepted" class="${properties.kcLabelClass!}">${msg("acceptTerms")}</label>
17+
</div>
18+
<#if messagesPerField.existsError('termsAccepted')>
19+
<div class="${properties.kcLabelWrapperClass!}">
20+
<span id="input-error-terms-accepted" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
21+
${kcSanitize(messagesPerField.get('termsAccepted'))?no_esc}
22+
</span>
23+
</div>
24+
</#if>
25+
</div>
26+
</#if>
27+
</#macro>
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<#import "template.ftl" as layout>
2+
<#import "user-profile-commons.ftl" as userProfileCommons>
3+
<#import "register-commons.ftl" as registerCommons>
4+
<@layout.registrationLayout displayMessage=messagesPerField.exists('global') displayRequiredFields=true; section>
5+
<#if section = "header">
6+
<#if messageHeader??>
7+
${kcSanitize(msg("${messageHeader}"))?no_esc}
8+
<#else>
9+
${msg("registerTitle")}
10+
</#if>
11+
<#elseif section = "form">
12+
<form id="kc-register-form" class="${properties.kcFormClass!}" action="${url.registrationAction}" method="post">
13+
14+
<@userProfileCommons.userProfileFormFields; callback, attribute>
15+
<#if callback = "afterField">
16+
<#-- render password fields just under the username or email (if used as username) -->
17+
<#if passwordRequired?? && (attribute.name == 'username' || (attribute.name == 'email' && realm.registrationEmailAsUsername))>
18+
<div class="${properties.kcFormGroupClass!}">
19+
<div class="${properties.kcLabelWrapperClass!}">
20+
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label> *
21+
</div>
22+
<div class="${properties.kcInputWrapperClass!}">
23+
<div class="${properties.kcInputGroup!}" dir="ltr">
24+
<input type="password" id="password" class="${properties.kcInputClass!}" name="password"
25+
autocomplete="new-password"
26+
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
27+
/>
28+
<button class="${properties.kcFormPasswordVisibilityButtonClass!}" type="button" aria-label="${msg('showPassword')}"
29+
aria-controls="password" data-password-toggle
30+
data-icon-show="${properties.kcFormPasswordVisibilityIconShow!}" data-icon-hide="${properties.kcFormPasswordVisibilityIconHide!}"
31+
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
32+
<i class="${properties.kcFormPasswordVisibilityIconShow!}" aria-hidden="true"></i>
33+
</button>
34+
</div>
35+
36+
<#if messagesPerField.existsError('password')>
37+
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
38+
${kcSanitize(messagesPerField.get('password'))?no_esc}
39+
</span>
40+
</#if>
41+
</div>
42+
</div>
43+
44+
<div class="${properties.kcFormGroupClass!}">
45+
<div class="${properties.kcLabelWrapperClass!}">
46+
<label for="password-confirm"
47+
class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label> *
48+
</div>
49+
<div class="${properties.kcInputWrapperClass!}">
50+
<div class="${properties.kcInputGroup!}" dir="ltr">
51+
<input type="password" id="password-confirm" class="${properties.kcInputClass!}"
52+
name="password-confirm" autocomplete="new-password"
53+
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
54+
/>
55+
<button class="${properties.kcFormPasswordVisibilityButtonClass!}" type="button" aria-label="${msg('showPassword')}"
56+
aria-controls="password-confirm" data-password-toggle
57+
data-icon-show="${properties.kcFormPasswordVisibilityIconShow!}" data-icon-hide="${properties.kcFormPasswordVisibilityIconHide!}"
58+
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
59+
<i class="${properties.kcFormPasswordVisibilityIconShow!}" aria-hidden="true"></i>
60+
</button>
61+
</div>
62+
63+
<#if messagesPerField.existsError('password-confirm')>
64+
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
65+
${kcSanitize(messagesPerField.get('password-confirm'))?no_esc}
66+
</span>
67+
</#if>
68+
</div>
69+
</div>
70+
</#if>
71+
</#if>
72+
</@userProfileCommons.userProfileFormFields>
73+
74+
<@registerCommons.termsAcceptance/>
75+
76+
<#if recaptchaRequired?? && (recaptchaVisible!false)>
77+
<div class="form-group">
78+
<div class="${properties.kcInputWrapperClass!}">
79+
<div class="g-recaptcha" data-size="compact" data-sitekey="${recaptchaSiteKey}" data-action="${recaptchaAction}"></div>
80+
</div>
81+
</div>
82+
</#if>
83+
84+
<div class="${properties.kcFormGroupClass!}">
85+
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
86+
<div class="${properties.kcFormOptionsWrapperClass!}">
87+
<span><a href="${url.loginUrl}">${kcSanitize(msg("backToLogin"))?no_esc}</a></span>
88+
</div>
89+
</div>
90+
91+
<#if recaptchaRequired?? && !(recaptchaVisible!false)>
92+
<script>
93+
function onSubmitRecaptcha(token) {
94+
document.getElementById("kc-register-form").requestSubmit();
95+
}
96+
</script>
97+
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
98+
<button class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!} g-recaptcha"
99+
data-sitekey="${recaptchaSiteKey}" data-callback='onSubmitRecaptcha' data-action='${recaptchaAction}' type="submit">
100+
${msg("doRegister")}
101+
</button>
102+
</div>
103+
<#else>
104+
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
105+
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doRegister")}"/>
106+
</div>
107+
</#if>
108+
</div>
109+
</form>
110+
<script type="module" src="${url.resourcesPath}/js/passwordVisibility.js"></script>
111+
</#if>
112+
</@layout.registrationLayout>
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
<#macro userProfileFormFields>
2+
<#assign currentGroup="">
3+
4+
<#list profile.attributes as attribute>
5+
6+
<#if attribute.name=='locale' && realm.internationalizationEnabled && locale.currentLanguageTag?has_content>
7+
<input type="hidden" id="${attribute.name}" name="${attribute.name}" value="${locale.currentLanguageTag}"/>
8+
<#else>
9+
10+
<#assign group = (attribute.group)!"">
11+
<#if group != currentGroup>
12+
<#assign currentGroup=group>
13+
<#if currentGroup != "">
14+
<div class="${properties.kcFormGroupClass!}"
15+
<#list group.html5DataAnnotations as key, value>
16+
data-${key}="${value}"
17+
</#list>
18+
>
19+
20+
<#assign groupDisplayHeader=group.displayHeader!"">
21+
<#if groupDisplayHeader != "">
22+
<#assign groupHeaderText=advancedMsg(groupDisplayHeader)!group>
23+
<#else>
24+
<#assign groupHeaderText=group.name!"">
25+
</#if>
26+
<div class="${properties.kcContentWrapperClass!}">
27+
<label id="header-${attribute.group.name}" class="${kcFormGroupHeader!}">${groupHeaderText}</label>
28+
</div>
29+
30+
<#assign groupDisplayDescription=group.displayDescription!"">
31+
<#if groupDisplayDescription != "">
32+
<#assign groupDescriptionText=advancedMsg(groupDisplayDescription)!"">
33+
<div class="${properties.kcLabelWrapperClass!}">
34+
<label id="description-${group.name}" class="${properties.kcLabelClass!}">${groupDescriptionText}</label>
35+
</div>
36+
</#if>
37+
</div>
38+
</#if>
39+
</#if>
40+
41+
<#nested "beforeField" attribute>
42+
<div class="${properties.kcFormGroupClass!}">
43+
<div class="${properties.kcLabelWrapperClass!}">
44+
<label for="${attribute.name}" class="${properties.kcLabelClass!}">${advancedMsg(attribute.displayName!'')}</label>
45+
<#if attribute.required>*</#if>
46+
<#if attribute.name == "email">${msg("registerAdditionaltext")}</#if>
47+
</div>
48+
<div class="${properties.kcInputWrapperClass!}">
49+
<#if attribute.annotations.inputHelperTextBefore??>
50+
<div class="${properties.kcInputHelperTextBeforeClass!}" id="form-help-text-before-${attribute.name}" aria-live="polite">${kcSanitize(advancedMsg(attribute.annotations.inputHelperTextBefore))?no_esc}</div>
51+
</#if>
52+
<@inputFieldByType attribute=attribute/>
53+
<#if messagesPerField.existsError('${attribute.name}')>
54+
<span id="input-error-${attribute.name}" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
55+
${kcSanitize(messagesPerField.get('${attribute.name}'))?no_esc}
56+
</span>
57+
</#if>
58+
<#if attribute.annotations.inputHelperTextAfter??>
59+
<div class="${properties.kcInputHelperTextAfterClass!}" id="form-help-text-after-${attribute.name}" aria-live="polite">${kcSanitize(advancedMsg(attribute.annotations.inputHelperTextAfter))?no_esc}</div>
60+
</#if>
61+
</div>
62+
</div>
63+
<#nested "afterField" attribute>
64+
65+
</#if>
66+
</#list>
67+
68+
<#list profile.html5DataAnnotations?keys as key>
69+
<script type="module" src="${url.resourcesPath}/js/${key}.js"></script>
70+
</#list>
71+
</#macro>
72+
73+
<#macro inputFieldByType attribute>
74+
<#switch attribute.annotations.inputType!''>
75+
<#case 'textarea'>
76+
<@textareaTag attribute=attribute/>
77+
<#break>
78+
<#case 'select'>
79+
<#case 'multiselect'>
80+
<@selectTag attribute=attribute/>
81+
<#break>
82+
<#case 'select-radiobuttons'>
83+
<#case 'multiselect-checkboxes'>
84+
<@inputTagSelects attribute=attribute/>
85+
<#break>
86+
<#default>
87+
<#if attribute.multivalued && attribute.values?has_content>
88+
<#list attribute.values as value>
89+
<@inputTag attribute=attribute value=value!''/>
90+
</#list>
91+
<#else>
92+
<@inputTag attribute=attribute value=attribute.value!''/>
93+
</#if>
94+
</#switch>
95+
</#macro>
96+
97+
<#macro inputTag attribute value>
98+
<input type="<@inputTagType attribute=attribute/>" id="${attribute.name}" name="${attribute.name}" value="${(value!'')}" class="${properties.kcInputClass!}"
99+
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
100+
<#if attribute.readOnly>disabled</#if>
101+
<#if attribute.autocomplete??>autocomplete="${attribute.autocomplete}"</#if>
102+
<#if attribute.annotations.inputTypePlaceholder??>placeholder="${advancedMsg(attribute.annotations.inputTypePlaceholder)}"</#if>
103+
<#if attribute.annotations.inputTypePattern??>pattern="${attribute.annotations.inputTypePattern}"</#if>
104+
<#if attribute.annotations.inputTypeSize??>size="${attribute.annotations.inputTypeSize}"</#if>
105+
<#if attribute.annotations.inputTypeMaxlength??>maxlength="${attribute.annotations.inputTypeMaxlength}"</#if>
106+
<#if attribute.annotations.inputTypeMinlength??>minlength="${attribute.annotations.inputTypeMinlength}"</#if>
107+
<#if attribute.annotations.inputTypeMax??>max="${attribute.annotations.inputTypeMax}"</#if>
108+
<#if attribute.annotations.inputTypeMin??>min="${attribute.annotations.inputTypeMin}"</#if>
109+
<#if attribute.annotations.inputTypeStep??>step="${attribute.annotations.inputTypeStep}"</#if>
110+
<#list attribute.html5DataAnnotations as key, value>
111+
data-${key}="${value}"
112+
</#list>
113+
/>
114+
</#macro>
115+
116+
<#macro inputTagType attribute>
117+
<#compress>
118+
<#if attribute.annotations.inputType??>
119+
<#if attribute.annotations.inputType?starts_with("html5-")>
120+
${attribute.annotations.inputType[6..]}
121+
<#else>
122+
${attribute.annotations.inputType}
123+
</#if>
124+
<#else>
125+
text
126+
</#if>
127+
</#compress>
128+
</#macro>
129+
130+
<#macro textareaTag attribute>
131+
<textarea id="${attribute.name}" name="${attribute.name}" class="${properties.kcInputClass!}"
132+
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
133+
<#if attribute.readOnly>disabled</#if>
134+
<#if attribute.annotations.inputTypeCols??>cols="${attribute.annotations.inputTypeCols}"</#if>
135+
<#if attribute.annotations.inputTypeRows??>rows="${attribute.annotations.inputTypeRows}"</#if>
136+
<#if attribute.annotations.inputTypeMaxlength??>maxlength="${attribute.annotations.inputTypeMaxlength}"</#if>
137+
>${(attribute.value!'')}</textarea>
138+
</#macro>
139+
140+
<#macro selectTag attribute>
141+
<select id="${attribute.name}" name="${attribute.name}" class="${properties.kcInputClass!}"
142+
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
143+
<#if attribute.readOnly>disabled</#if>
144+
<#if attribute.annotations.inputType=='multiselect'>multiple</#if>
145+
<#if attribute.annotations.inputTypeSize??>size="${attribute.annotations.inputTypeSize}"</#if>
146+
>
147+
<#if attribute.annotations.inputType=='select'>
148+
<option value=""></option>
149+
</#if>
150+
151+
<#if attribute.annotations.inputOptionsFromValidation?? && attribute.validators[attribute.annotations.inputOptionsFromValidation]?? && attribute.validators[attribute.annotations.inputOptionsFromValidation].options??>
152+
<#assign options=attribute.validators[attribute.annotations.inputOptionsFromValidation].options>
153+
<#elseif attribute.validators.options?? && attribute.validators.options.options??>
154+
<#assign options=attribute.validators.options.options>
155+
<#else>
156+
<#assign options=[]>
157+
</#if>
158+
159+
<#list options as option>
160+
<option value="${option}" <#if attribute.values?seq_contains(option)>selected</#if>><@selectOptionLabelText attribute=attribute option=option/></option>
161+
</#list>
162+
163+
</select>
164+
</#macro>
165+
166+
<#macro inputTagSelects attribute>
167+
<#if attribute.annotations.inputType=='select-radiobuttons'>
168+
<#assign inputType='radio'>
169+
<#assign classDiv=properties.kcInputClassRadio!>
170+
<#assign classInput=properties.kcInputClassRadioInput!>
171+
<#assign classLabel=properties.kcInputClassRadioLabel!>
172+
<#else>
173+
<#assign inputType='checkbox'>
174+
<#assign classDiv=properties.kcInputClassCheckbox!>
175+
<#assign classInput=properties.kcInputClassCheckboxInput!>
176+
<#assign classLabel=properties.kcInputClassCheckboxLabel!>
177+
</#if>
178+
179+
<#if attribute.annotations.inputOptionsFromValidation?? && attribute.validators[attribute.annotations.inputOptionsFromValidation]?? && attribute.validators[attribute.annotations.inputOptionsFromValidation].options??>
180+
<#assign options=attribute.validators[attribute.annotations.inputOptionsFromValidation].options>
181+
<#elseif attribute.validators.options?? && attribute.validators.options.options??>
182+
<#assign options=attribute.validators.options.options>
183+
<#else>
184+
<#assign options=[]>
185+
</#if>
186+
187+
<#list options as option>
188+
<div class="${classDiv}">
189+
<input type="${inputType}" id="${attribute.name}-${option}" name="${attribute.name}" value="${option}" class="${classInput}"
190+
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
191+
<#if attribute.readOnly>disabled</#if>
192+
<#if attribute.values?seq_contains(option)>checked</#if>
193+
/>
194+
<label for="${attribute.name}-${option}" class="${classLabel}<#if attribute.readOnly> ${properties.kcInputClassRadioCheckboxLabelDisabled!}</#if>"><@selectOptionLabelText attribute=attribute option=option/></label>
195+
</div>
196+
</#list>
197+
</#macro>
198+
199+
<#macro selectOptionLabelText attribute option>
200+
<#compress>
201+
<#if attribute.annotations.inputOptionLabels??>
202+
${advancedMsg(attribute.annotations.inputOptionLabels[option]!option)}
203+
<#else>
204+
<#if attribute.annotations.inputOptionLabelsI18nPrefix??>
205+
${msg(attribute.annotations.inputOptionLabelsI18nPrefix + '.' + option)}
206+
<#else>
207+
${option}
208+
</#if>
209+
</#if>
210+
</#compress>
211+
</#macro>

0 commit comments

Comments
 (0)