Revel provides built-in functionality for validating parameters. The main parts are:
- A Validation context collects and manages validation errors (keys and messages).
- Helper functions that checks data and put errors into the context.
- A template function that gets error messages from the Validation context by key.
See the validation sample app for some in-depth examples.
Inline Error Messages
This example demonstrates field validation with inline error messages.
func (c MyApp) SaveUser(username string) revel.Result {
// Username (required) must be between 4 and 15 letters (inclusive).
c.Validation.Required(username)
c.Validation.MaxSize(username, 15)
c.Validation.MinSize(username, 4)
c.Validation.Match(username, regexp.MustCompile("^\\w*$"))
if c.Validation.HasErrors() {
// Store the validation errors in the flash context and redirect.
c.Validation.Keep()
c.FlashParams()
return c.Redirect(Hotels.Settings)
}
// All the data checked out!
...
}
In this second implementation we have the model validating the object, note
v.MaxSize(username, 15).MessageKey("Name must be between 4-15 characters long")
vs
v.MinSize(username, 4).Message("Name must be between 4-15 characters long")
The MessageKey function tells Revel for the error message use that message key
(ie lookup the message in the i18n translation)
The Message function tells Revel for the error message use that message
func (c MyApp) SaveUser(user User) revel.Result {
user.Validate(c.Validation)
if c.Validation.HasErrors() {
// Store the validation errors in the flash context and redirect.
c.Validation.Keep()
c.FlashParams()
return c.Redirect(Hotels.Settings)
}
// All the data checked out!
...
}
...
func (u *User) Validate(v *revel.Validation) {
v.Required(u.Name)
v.MaxSize(username, 15).MessageKey("Name must be between 4-15 characters long")
v.MinSize(username, 4).Message("Name must be between 4-15 characters long")
v.Match(username, regexp.MustCompile("^\\w*$"))
return
}
Step by step:
- Evaluate four different conditions on
username(Required, MinSize, MaxSize, Match). - Each evaluation returns a ValidationResult. Failed
ValidationResult’s are stored in theValidationcontext. - As part of building an app, Revel records the name of the variable being validated, and uses that as the default key in the validation context (to be looked up later).
- Validation.HasErrors() returns
trueif the the context is non-empty. - Validation.Keep() tells Revel to serialize the
ValidationErrorsto the Flash cookie. - Revel returns a redirect to the
Hotels.Settingsaction.
The Hotels.Settings action renders a template:
{{/* app/views/Hotels/Settings.html */}}
...
{{if .errors}}Please fix errors marked below!{{end}}
...
<p class="{{if .errors.username}}error{{end}}">
Username:
<input name="username" value="{{.flash.username}}"/>
<span class="error">{{.errors.username.Message}}</span>
</p>It does three things:
- Checks the
errorsmap for theusernamekey to see if that field had an error. - Prefills the input with the flashed
usernameparam value. - Shows the error message next to the field. (We didn’t specify any error message, but each validation function provides one by default.)
Note: The field template helper function makes writing templates that use the validation error framework a little more convenient.
Top Error Messages
The template can be simplified if error messages are collected in a single place (e.g. a big red box at the top of the screen.)
There are only two differences from the previous example:
- We specify a
Messageinstead of aKeyon theValidationError - We print all messages at the top of the form.
Here’s the code.
func (c MyApp) SaveUser(username string) revel.Result {
// Username (required) must be between 4 and 15 letters (inclusive).
c.Validation.Required(username).Message("Please enter a username")
c.Validation.MaxSize(username, 15).Message("Username must be at most 15 characters long")
c.Validation.MinSize(username, 4).Message("Username must be at least 4 characters long")
c.Validation.Match(username, regexp.MustCompile("^\\w*$")).Message("Username must be all letters")
if c.Validation.HasErrors() {
// Store the validation errors in the flash context and redirect.
c.Validation.Keep()
c.FlashParams()
return c.Redirect(Hotels.Settings)
}
// All the data checked out!
...
}
.. and the template:
{{/* app/views/Hotels/Settings.html */}}
...
{{if .errors}}
<div class="error">
<ul>
{{range .errors}}
<li> {{.Message}}</li>
{{end}}
</ul>
</div>
{{end}}
...