In this recipe, we will learn different approaches for the same need: translating model validation messages.
To go through this recipe, we need a basic application skeleton to work with. Go through the previous recipe.
Edit the file article.php
located in your app/models
folder and make the following changes to the validate
property:
public $validate = array(
'title' => array(
'required' => 'notEmpty'
),
'body' => array(
'required' => 'notEmpty'
)
);
There are two ways to have validation messages translated. The first one requires you to override the model constructor by adding the following implementation to the Article
class defined in your app/models/article.php
file:
public function __construct($id = false, $table = null, $ds = null) { foreach($this->validate as $field => $rules) { if (!is_array($rules)) { $rules = (array) $rules; } foreach($rules as $key => $rule) { if (!is_array($rule)) { $rules[$key] = compact('rule'), } } $this->validate[$field] = $rules; } $this->validate = Set::merge($this->validate, array( 'title' => array( 'required' => array('message' => __('A title must be specified', true)) ), 'body' => array( 'required' => array('message' => __('You must define the body', true)) ) )); parent::__construct($id, $table, $ds); }
The alternative way to translate validation messages is to move these messages to the view. Instead of overriding and defining the messages in the model constructor, edit your app/views/articles/add.ctp
view file and make the following changes to it:
<?php
echo $this->Form->create();
echo $this->Form->inputs(array(
'title' => array(
'label' => __('Title:', true),
'error' => array(
'required' => __('A title must be specified', true)
)
),
'body' => array(
'label' => __('Body:', true),
'error' => array(
'required' => __('You must define the body', true)
)
)
));
echo $this->Form->end(__('Save', true));
?>
Both ways should produce the same result. If you now browse to http://localhost/articles/add
and submit the form without entering any values, you should see the validation messages shown in the following screenshot:
Before attempting to provide the error messages for each validation rule, we need to name each of our rules. We do so by modifying the Article
model so that each rule defined is indexed by a name. In our case we choose required
as the name for the validation based on CakePHP's built-in notEmpty
rule.
The first method we used to specify the validation messages shows a practical approach when we want to centralize all validation messages in the model. We override the model constructor so that from within this constructor we specify the error messages that should be translated. We needed to implement the constructor because class property values cannot use an expression other than a static assignment, so the following block of code would produce a PHP syntax error:
public $validate = array( 'title' => array( 'required' => array( 'rule' => 'notEmpty', 'message' => __('Nothing defined!', true) // SYNTAX ERROR ) ) );
In this constructor implementation, we start by making sure that the validate
property is an array of rules, indexed by field name, and that each set of rules is itself an array indexed by name, having as its value another array where at the very least the rule
setting is defined.
Once we are sure that the validate
property has the right format, we merge the validation messages for each rule using the __()
translator function to translate the messages. Finally, we call the parent constructor to ensure that the model is built properly.
The second method described in this recipe moves the responsibility of declaring each validation error message to the view, by means of the error
setting available in the input()
method of the FormHelper
class. This setting is set to an array, indexed by validation name, and the value is set to the error message shown when the respective validation fails.
3.144.82.154