Localisation The simplest way of adding textual information like labels and hints to
forms is to provide strings as arguments to the form helpers.
= f . govuk_text_field :name , label: { text: 'Your full name' }
On larger, more-complex projects, copy is spread throughout the application
and often duplicated, making it difficult for content designers to make
changes.
Many teams approach this problem by making use of
Rails’ excellent localisation functionality ,
allowing text to be stored in locale dictionaries. This allows editors to
make changes without the risk of breaking templates and having to learn
templating languages and hunt down content.
You can use HTML in locales if you append the suffix _html
to
the key.
Note that despite the text
attribute being omitted from
the label options hash, the other display and formatting parameters
can be supplied and work in the normal manner.
Localisation data
helpers :
label :
person :
favourite_kind_of_hat : Which style of hat do you prefer?
caption :
person :
favourite_kind_of_hat : Fashion choices
hint :
person :
favourite_kind_of_hat : |-
Trilby, Stetson, Deerstalker, Fez, Top and Beret are
the most-fashionable
Input
= f . govuk_text_field :favourite_kind_of_hat , label: { size: 'l' }
<%= f . govuk_text_field :favourite_kind_of_hat , label: { size: 'l' } %>
Output
<div class= "govuk-form-group" >
<label for= "person-favourite-kind-of-hat-field" class= "govuk-label govuk-label--l" >
<span class= "govuk-caption-m" >
Fashion choices
</span>
Which style of hat do you prefer?
</label>
<div class= "govuk-hint" id= "person-favourite-kind-of-hat-hint" >
Trilby, Stetson, Deerstalker, Fez, Top and Beret are
the most-fashionable
</div>
<input id= "person-favourite-kind-of-hat-field" class= "govuk-input" aria-describedby= "person-favourite-kind-of-hat-hint" type= "text" name= "person[favourite_kind_of_hat]" />
</div>
Radio and check box labels use a special key in the locale dictionary
composed from the attribute name and the suffix _options
. This
makes it possible to localise the fieldset legend and each of the
individual choices separately.
Data
contact_type = Struct . new ( :value , keyword_init: true )
contact_types = [
contact_type . new ( value: :email ),
contact_type . new ( value: :phone ),
contact_type . new ( value: :letter )
]
Localisation data
helpers :
caption :
person :
contact_type : Contacting you
legend :
person :
contact_type : What is your preferred method of contact?
hint :
person :
contact_type_html : |-
We recommend <strong>email</strong> at the moment
contact_type_options :
letter : Please be aware that this can delay your application
label :
person :
contact_type_options :
email : Email
phone : Mobile or landline phone
letter : Postal letter
Output
<div class= "govuk-form-group" >
<fieldset class= "govuk-fieldset" aria-describedby= "person-contact-type-hint" >
<legend class= "govuk-fieldset__legend govuk-fieldset__legend--m" >
<span class= "govuk-caption-m" >
Contacting you
</span>
What is your preferred method of contact?
</legend>
<input value= "" autocomplete= "off" type= "hidden" name= "person[contact_type]" id= "person_contact_type" />
<div class= "govuk-hint" id= "person-contact-type-hint" >
We recommend <strong>
email
</strong>
at the moment
</div>
<div class= "govuk-radios" data-module= "govuk-radios" >
<div class= "govuk-radios__item" >
<input id= "person-contact-type-email-field" class= "govuk-radios__input" type= "radio" value= "email" name= "person[contact_type]" />
<label for= "person-contact-type-email-field" class= "govuk-label govuk-radios__label" >
Email
</label>
</div>
<div class= "govuk-radios__item" >
<input id= "person-contact-type-phone-field" class= "govuk-radios__input" type= "radio" value= "phone" name= "person[contact_type]" />
<label for= "person-contact-type-phone-field" class= "govuk-label govuk-radios__label" >
Mobile or landline phone
</label>
</div>
<div class= "govuk-radios__item" >
<input id= "person-contact-type-letter-field" aria-describedby= "person-contact-type-letter-hint" class= "govuk-radios__input" type= "radio" value= "letter" name= "person[contact_type]" />
<label for= "person-contact-type-letter-field" class= "govuk-label govuk-radios__label" >
Postal letter
</label>
<div class= "govuk-hint govuk-radios__hint" id= "person-contact-type-letter-hint" >
Please be aware that this can delay your application
</div>
</div>
</div>
</fieldset>
</div>
Data
department = Struct . new ( :id , keyword_init: true )
departments = [
department . new ( id: :sales ),
department . new ( id: :marketing ),
department . new ( id: :finance ),
department . new ( id: :digital )
]
Localisation data
helpers :
caption :
person :
department_ids : Departments
legend :
person :
department_ids : Which department do you work in?
hint :
person :
department_ids : Select all that apply
label :
person :
department_ids_options :
sales : Sales
marketing : Marketing
finance : Finance
digital : Digital and Technology
Output
<div class= "govuk-form-group" >
<fieldset class= "govuk-fieldset" aria-describedby= "person-department-ids-hint" >
<legend class= "govuk-fieldset__legend govuk-fieldset__legend--m" >
<span class= "govuk-caption-m" >
Departments
</span>
Which department do you work in?
</legend>
<div class= "govuk-hint" id= "person-department-ids-hint" >
Select all that apply
</div>
<div class= "govuk-checkboxes" data-module= "govuk-checkboxes" >
<input type= "hidden" name= "person[department_ids][]" value= "" autocomplete= "off" />
<div class= "govuk-checkboxes__item" >
<input id= "person-department-ids-sales-field" class= "govuk-checkboxes__input" type= "checkbox" value= "sales" name= "person[department_ids][]" />
<label for= "person-department-ids-sales-field" class= "govuk-label govuk-checkboxes__label" >
Sales
</label>
</div>
<div class= "govuk-checkboxes__item" >
<input id= "person-department-ids-marketing-field" class= "govuk-checkboxes__input" type= "checkbox" value= "marketing" name= "person[department_ids][]" />
<label for= "person-department-ids-marketing-field" class= "govuk-label govuk-checkboxes__label" >
Marketing
</label>
</div>
<div class= "govuk-checkboxes__item" >
<input id= "person-department-ids-finance-field" class= "govuk-checkboxes__input" type= "checkbox" value= "finance" name= "person[department_ids][]" />
<label for= "person-department-ids-finance-field" class= "govuk-label govuk-checkboxes__label" >
Finance
</label>
</div>
<div class= "govuk-checkboxes__item" >
<input id= "person-department-ids-digital-field" class= "govuk-checkboxes__input" type= "checkbox" value= "digital" name= "person[department_ids][]" />
<label for= "person-department-ids-digital-field" class= "govuk-label govuk-checkboxes__label" >
Digital and Technology
</label>
</div>
</div>
</fieldset>
</div>
The form builder does not keep track of its contents so to ensure
the error summary correctly links to the first checkbox
link_errors
must be set to true
Localisation data
helpers :
legend :
person :
movie_genres : Which movie genres do you prefer?
hint :
person :
other_movie_genres : You can enter as many as you like
movie_genres : Select all that apply
movie_genres_options :
action : War, espionage, martial arts
comedy : Parody, dark comedy
horror : Zombies, slasher, found footage
label :
person :
other_movie_genres : Which additional movie genres do you like?
movie_genres_options :
action : Action
comedy : Comedy
horror : Horror
other : Other
Output
<div class= "govuk-form-group" >
<fieldset class= "govuk-fieldset" aria-describedby= "person-movie-genres-hint" >
<legend class= "govuk-fieldset__legend govuk-fieldset__legend--m" >
Which movie genres do you prefer?
</legend>
<div class= "govuk-hint" id= "person-movie-genres-hint" >
Select all that apply
</div>
<input value= "" name= "person[movie_genres][]" autocomplete= "off" type= "hidden" id= "person_movie_genres" />
<div class= "govuk-checkboxes" data-module= "govuk-checkboxes" >
<div class= "govuk-checkboxes__item" >
<input id= "person-movie-genres-action-field" class= "govuk-checkboxes__input" aria-describedby= "person-movie-genres-action-hint" type= "checkbox" value= "action" name= "person[movie_genres][]" />
<label for= "person-movie-genres-action-field" class= "govuk-label govuk-checkboxes__label" >
Action
</label>
<div class= "govuk-hint govuk-checkboxes__hint" id= "person-movie-genres-action-hint" >
War, espionage, martial arts
</div>
</div>
<div class= "govuk-checkboxes__item" >
<input id= "person-movie-genres-comedy-field" class= "govuk-checkboxes__input" aria-describedby= "person-movie-genres-comedy-hint" type= "checkbox" value= "comedy" name= "person[movie_genres][]" />
<label for= "person-movie-genres-comedy-field" class= "govuk-label govuk-checkboxes__label" >
Comedy
</label>
<div class= "govuk-hint govuk-checkboxes__hint" id= "person-movie-genres-comedy-hint" >
Parody, dark comedy
</div>
</div>
<div class= "govuk-checkboxes__item" >
<input id= "person-movie-genres-horror-field" class= "govuk-checkboxes__input" aria-describedby= "person-movie-genres-horror-hint" type= "checkbox" value= "horror" name= "person[movie_genres][]" />
<label for= "person-movie-genres-horror-field" class= "govuk-label govuk-checkboxes__label" >
Horror
</label>
<div class= "govuk-hint govuk-checkboxes__hint" id= "person-movie-genres-horror-hint" >
Zombies, slasher, found footage
</div>
</div>
<div class= "govuk-checkboxes__item" >
<input id= "person-movie-genres-other-field" class= "govuk-checkboxes__input" data-aria-controls= "person-movie-genres-other-conditional" type= "checkbox" value= "other" name= "person[movie_genres][]" />
<label for= "person-movie-genres-other-field" class= "govuk-label govuk-checkboxes__label" >
Other
</label>
</div>
<div class= "govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden" id= "person-movie-genres-other-conditional" >
<div class= "govuk-form-group" >
<label for= "person-other-movie-genres-field" class= "govuk-label" >
Which additional movie genres do you like?
</label>
<div class= "govuk-hint" id= "person-other-movie-genres-hint" >
You can enter as many as you like
</div>
<input id= "person-other-movie-genres-field" class= "govuk-input" aria-describedby= "person-other-movie-genres-hint" type= "text" name= "person[other_movie_genres]" />
</div>
</div>
</div>
</fieldset>
</div>
There are many approaches to organising localisation data and while the
default will work for most projects, sometimes a different approach can
be beneficial. This is especially true when working with external
localisation agencies or when dealing with large volumes of copy.
To customise the location of our localisation strings, we can
configure the schema as part of the application’s initialisation process.
Contexts There are four contexts supported by the form builder: label ,
legend , caption and hint . Custom locale
schemas are configured using an array of symbols that match your locale
structure.
The special value __context__
is used to represent the
current translation context. It will automatically be replaced with
either label , legend , caption or hint when the translation key is generated.
When retrieving a localised string the builder first checks whether
a contextual schema has been set for the context. If there hasn’t,
the localisation_schema_fallback
key will be used. It is the only schema set by default .
Captions are rendered inside the corresponding label
or
legend
tag. If the label or legend is hidden or not rendered, the caption won’t be either.
Configuration
Place your configuration in an
initializer to ensure
it’s loaded every time you start your Rails application.
GOVUKDesignSystemFormBuilder . configure do | conf |
conf . localisation_schema_fallback = %i(helpers __context__)
conf . localisation_schema_hint = %i(copy descriptions __context__ subdivision)
end
Localisation data
helpers :
label :
person :
role : What role do you play?
copy :
descriptions :
hint :
subdivision :
person :
role : |-
Roles may be achieved or ascribed or they can be accidental
in different situations. An achieved role is a position
that a person assumes voluntarily which reflects personal
skills, abilities, and effort.
Output
<div class= "govuk-form-group" >
<label for= "person-role-field" class= "govuk-label govuk-label--m" >
What role do you play?
</label>
<div class= "govuk-hint" id= "person-role-hint" >
Roles may be achieved or ascribed or they can be accidental
in different situations. An achieved role is a position
that a person assumes voluntarily which reflects personal
skills, abilities, and effort.
</div>
<input id= "person-role-field" class= "govuk-input" aria-describedby= "person-role-hint" type= "text" name= "person[role]" />
</div>