Hak
Hak

Reputation: 1275

Laravel validation attributes "nice names"

I'm trying to use the validation attributes in "language > {language} > validation.php", to replace the :attribute name (input name) for a proper to read name (example: first_name > First name) . It seems very simple to use, but the validator doesn't show the "nice names".

I have this:

'attributes' => array(
    'first_name' => 'voornaam'
  , 'first name' => 'voornaam'
  , 'firstname'  => 'voornaam'
);

For showing the errors:

@if($errors->has())
  <ul>
  @foreach ($errors->all() as $error)
    <li class="help-inline errorColor">{{ $error }}</li>
  @endforeach
  </ul>
@endif

And the validation in the controller:

$validation = Validator::make($input, $rules, $messages);

The $messages array:

$messages = array(
    'required' => ':attribute is verplicht.'
  , 'email'    => ':attribute is geen geldig e-mail adres.'
  , 'min'      => ':attribute moet minimaal :min karakters bevatten.'
  , 'numeric'  => ':attribute mag alleen cijfers bevatten.'
  , 'url'      => ':attribute moet een valide url zijn.'
  , 'unique'   => ':attribute moet uniek zijn.'
  , 'max'      => ':attribute mag maximaal :max zijn.'
  , 'mimes'    => ':attribute moet een :mimes bestand zijn.'
  , 'numeric'  => ':attribute is geen geldig getal.'
  , 'size'     => ':attribute is te groot of bevat te veel karakters.'
);

Can someone tell me what i'm doing wrong. I want the :attribute name to be replaced by the "nice name" in the attributes array (language).

Thanks!

EDIT:

I noticed that the problem is I never set a default language for my Laravel projects. When I set the language to 'NL' the code above works. But, when I set my language, the language will appear in the url. And I prefer it doesn't.

So my next question: Is it possible to remove the language from the url, or set the default language so it just doesn't appear there?

Upvotes: 95

Views: 133373

Answers (11)

Javier Cadiz
Javier Cadiz

Reputation: 12536

Yeahh, the "nice name" attributes as you called it was a real "issue" a few month ago. Hopefully this feature is now implemented and is very simply to use.

For simplicity i will split the two options to tackle this problem:

  1. Global Probably the more widespread. This approach is very well explained here but basically you need to edit the application/language/XX/validation.php validation file where XX is the language you will use for the validation.

At the bottom you will see an attribute array; that will be your "nice name" attributes array. Following your example the final result will be something like this.

'attributes' => array('first_name' => 'First Name')
  1. Locally This is what Taylor Otwell was talking about in the issue when he says:

You may call setAttributeNames on a Validator instance now.

That's perfectly valid and if you check the source code you will see

public function setAttributeNames(array $attributes)
{
    $this->customAttributes = $attributes;

    return $this;
}

So, to use this way see the following straightforward example:

$niceNames = array(
    'first_name' => 'First Name'
);

$validator = Validator::make(Input::all(), $rules);
$validator->setAttributeNames($niceNames);

Resources

There is a really awesome repo on Github that have a lot of languages packages ready to go. Definitely you should check it out.

Upvotes: 161

Emre Macit
Emre Macit

Reputation: 89

if you have dynamic inputs and you validate your data inside Controller like this, then you can use $request->validate($rules, [], $attributes);

public function submitForm(Form $form, Request $request){

    $rules=[];
    $attributes = [];
        foreach($form->fields as $field){
            $rules[$field['name']] = $field['rules'] ?? '';
           
            $attributes[$field['name']] = $field["BeautifulName"] ?? $field['name'];
        }
    $request->validate($rules, [], $attributes);
}

Upvotes: -1

Talha Masood
Talha Masood

Reputation: 27

$customAttributes = [
'email' => 'email address',
];

$validator = Validator::make($input, $rules, $messages, $customAttributes);

Upvotes: 1

Wahyu Kodar
Wahyu Kodar

Reputation: 674

In Laravel 7.

use Illuminate\Support\Facades\Validator;

Then define niceNames

$niceNames = array(
   'name' => 'Name',
);

And the last, just put $niceNames in fourth parameter, like this:

$validator = Validator::make($request->all(), $rules, $messages, $niceNames);

Upvotes: 4

John Smith
John Smith

Reputation: 1814

In Laravel 4.1 the easy way to do this is go to the lang folder -> your language(default en) -> validation.php.

When you have this in your model, for example:

'group_id' => 'Integer|required',
'adult_id' => 'Integer|required',

And you do not want the error to be "please enter a group id", you can create "nice" validation messages by adding a custom array in validation.php. So in our example, the custom array would look like this:

'custom' => array(
    'adult_id' => array(
        'required' => 'Please choose some parents!',
    ),
    'group_id' => array(
        'required' => 'Please choose a group or choose temp!',
    ),
),

This also works with multi-language apps, you just need to edit (create) the correct language validation file.

The default language is stored in the app/config/app.php configuration file, and is English by default. This can be changed at any time using the App::setLocale method.

More info to both errors and languages can be found here validation and localization.

Upvotes: 4

ShirleyCC
ShirleyCC

Reputation: 805

Since Laravel 5.2 you could...

public function validForm(\Illuminate\Http\Request $request)
{
    $rules = [
        'first_name' => 'max:130'
    ];  
    $niceNames = [
        'first_name' => 'First Name'
    ]; 
    $this->validate($request, $rules, [], $niceNames);

    // correct validation 

Upvotes: 34

I use my custom language files as Input for the "nice names" like this:

$validator = Validator::make(Input::all(), $rules);
$customLanguageFile = strtolower(class_basename(get_class($this)));

// translate attributes
if(Lang::has($customLanguageFile)) {
    $validator->setAttributeNames($customLanguageFile);
}

Upvotes: 1

Victor Moura
Victor Moura

Reputation: 124

Well, it's quite an old question but I few I should point that problem of having the language appearing at the URL can be solved by:

  • Changing the language and fallback_language at config/app.php;
  • or by setting \App::setLocale($lang)

If needed to persist it through session, I currently use the "AppServiceProvider" to do this, but, I think a middleware might be a better approach if changing the language by URL is needed, so, I do like this at my provider:

    if(!Session::has('locale'))
    {
        $locale = MyLocaleService::whatLocaleShouldIUse();
        Session::put('locale', $locale);
    }

    \App::setLocale(Session::get('locale'));

This way I handle the session and it don't stick at my url.

To clarify I'm currently using Laravel 5.1+ but shouldn't be a different behavior from 4.x;

Upvotes: -1

Logus Graphics
Logus Graphics

Reputation: 1933

The correct answer to this particular problem would be to go to your app/lang folder and edit the validation.php file at the bottom of the file there is an array called attributes:

/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/

'attributes' => array(
    'username' => 'The name of the user',
    'image_id' => 'The related image' // if it's a relation
),

So I believe this array was built to customise specifically these attribute names.

Upvotes: 44

Altrim
Altrim

Reputation: 6756

In the "attributes" array the key is the input name and the value is the string you want to show in the message.

An example if you have an input like this

 <input id="first-name" name="first-name" type="text" value="">

The array (in the validation.php file) should be

 'attributes' => array(
    'first-name' => 'Voornaam'),

I tried the same thing and it works great. Hope this helps.

EDIT

Also I am noticing you don't pass a parameter to $errors->has() so maybe that's the problem.

To fix this check out in the controller if you have a code like this

return Redirect::route('page')->withErrors(array('register' => $validator));

then you have to pass to the has() method the "register" key (or whatever you are using) like this

@if($errors->has('register')
.... //code here
@endif

Another way to display error messages is the following one which I prefer (I use Twitter Bootstrap for the design but of course you can change those with your own design)

 @if (isset($errors) and count($errors->all()) > 0)
 <div class="alert alert-error">
    <h4 class="alert-heading">Problem!</h4>
     <ul>
        @foreach ($errors->all('<li>:message</li>') as $message)
         {{ $message }}
       @endforeach
    </ul>
</div>

Upvotes: 8

Alexandre Danault
Alexandre Danault

Reputation: 8672

The :attribute can only use the attribute name (first_name in your case), not nice names.

But you can define custom messages for each attribute+validation by definine messages like this:

$messages = array(
  'first_name_required' => 'Please supply your first name',
  'last_name_required' => 'Please supply your last name',
  'email_required' => 'We need to know your e-mail address!',
  'email_email' => 'Invalid e-mail address!',
);

Upvotes: 0

Related Questions