Atributos de validación de Laravel "buenos nombres"

81

Estoy tratando de usar los atributos de validación en "idioma> {idioma}> validación.php", para reemplazar el: nombre del atributo (nombre de entrada) por un nombre apropiado para leer (ejemplo: nombre> nombre). Parece muy simple de usar, pero el validador no muestra los "buenos nombres".

Tengo esto:

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

Para mostrar los errores:

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

Y la validación en el controlador:

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

La matriz de $ mensajes:

$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.'
);

¿Alguien puede decirme qué estoy haciendo mal? Quiero que: nombre del atributo sea reemplazado por el "nombre agradable" en la matriz de atributos (idioma).

¡Gracias!

EDITAR:

Noté que el problema es que nunca configuro un idioma predeterminado para mis proyectos de Laravel. Cuando configuro el idioma en 'NL', el código anterior funciona. Pero, cuando configuro mi idioma, el idioma aparecerá en la URL. Y prefiero que no lo haga.

Entonces, mi siguiente pregunta: ¿Es posible eliminar el idioma de la URL o establecer el idioma predeterminado para que no aparezca allí?

Hak
fuente
No estoy seguro de haberlo entendido correctamente, pero puede configurar el idioma predeterminado en app / config / app.php, que será utilizado por el proveedor de servicios de traducción. Para cada idioma, debe crear la carpeta correspondiente en app / lang /. Por ejemplo, si tiene "en" y "nl" como idiomas que usa en su aplicación, debe tener ambas carpetas en app / lang / con los archivos correspondientes (en este ejemplo validation.php), así que siempre que cambie el idioma, ese archivo se cargará. En cuanto a eliminar el idioma de la URL, no estoy del todo seguro, pero creo que se puede lograr con las rutas.
Altrim
Sé cómo configurar los idiomas y ahora está funcionando la traducción de los nombres de entrada. Solo necesito saber cómo eliminar el idioma de la URL. Buscaré eso. ¡Gracias!
Hak
Definitivamente esto se puede hacer, vea mi respuesta a continuación.
Javier Cadiz
pero es para 5.3 stackoverflow.com/a/41904035/1076753
Vixed

Respuestas:

142

Sí, los atributos de "buen nombre" como lo llamaste fue un "problema" real hace unos meses. Con suerte, esta función ahora está implementada y es muy fácil de usar.

Para simplificar, dividiré las dos opciones para abordar este problema:

  1. Global Probablemente el más extendido. Este enfoque está muy bien explicado aquí, pero básicamente necesitas editar el archivo de validación application / language / XX / validation.php donde XX es el idioma que usarás para la validación.

    En la parte inferior verá una matriz de atributos; esa será su matriz de atributos de "buen nombre". Siguiendo tu ejemplo, el resultado final será algo así.

    'attributes' => array('first_name' => 'First Name')
    
  2. A nivel local Esto es de lo que hablaba Taylor Otwell en el número cuando dice:

    Puede llamar a setAttributeNames en una instancia de Validator ahora.

    Eso es perfectamente válido y si comprueba el código fuente verá

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

    Entonces, para usar de esta manera, vea el siguiente ejemplo sencillo:

    $niceNames = array(
        'first_name' => 'First Name'
    );
    
    $validator = Validator::make(Input::all(), $rules);
    $validator->setAttributeNames($niceNames); 
    

Recursos

Hay un repositorio realmente impresionante en Github que tiene muchos paquetes de idiomas listos para usar. Definitivamente deberías comprobarlo.

Espero que esto ayude.

Javier Cádiz
fuente
2
Hay un problema con la solución global: en una forma podría tener 'name' => 'Customer name'y en otra forma podría ser 'name'=>'Seller name'. Prefiero tener mis traducciones por módulo, por lo que puedo reutilizar estos valores también como etiquetas para campos de formulario. Por lo tanto, voto por una solución local, pero ¿cómo recupero esa matriz $ niceNames de mi archivo de idioma? ¿Y cómo llamo setAttributeNamessin crear una nueva instancia de Validator pero usando el método $ this-> validate () que está disponible en los controladores?
JustAMartin
2
En respuesta a este comentario y para completar la solución de @javiercadiz, desde Laravel 5.1 puedes usar un cuarto parámetro $this->validate(Request $request, $rules, $messages, $customAttributes)para tener esos bonitos nombres. Véalo
Fran Arjona
¿Dónde pones el código en la última opción? Me refiero a esta parte: $validator = Validator::make(Input::all(), $rules); $validator->setAttributeNames($niceNames);
Jenthe
Por cierto, si usted está utilizando la solución "local", puede cargar los nombres de los atributos de un archivo de lenguaje de la siguiente manera: $validator->setAttributeNames(Lang::get('my-language-file')).
2016
31

La respuesta correcta a este problema en particular sería ir a la carpeta app / lang y editar el archivo validation.php en la parte inferior del archivo, hay una matriz llamada atributos :

/*
|--------------------------------------------------------------------------
| 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
),

Así que creo que esta matriz se creó para personalizar específicamente estos nombres de atributos.

Logus
fuente
3
Esta es la mejor respuesta para hacer respuestas en español 'attributes' => [ 'name' => 'nombre', 'mail' => 'correo', 'password' => 'contraseña', 'password2' => 'confirmación de contraseña', ],
1
Funciona en Laravel 5.6
Yevgeniy Afanasyev
25

Desde Laravel 5.2 podrías ...

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

    // correct validation 
ShirleyCC
fuente
8

En la matriz de "atributos", la clave es el nombre de entrada y el valor es la cadena que desea mostrar en el mensaje.

Un ejemplo si tiene una entrada como esta

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

La matriz (en el archivo validation.php) debe ser

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

Intenté lo mismo y funciona muy bien. Espero que esto ayude.

EDITAR

También me doy cuenta de que no le pasas un parámetro, $errors->has()así que tal vez ese sea el problema.

Para solucionar esto, consulte el controlador si tiene un código como este

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

entonces tienes que pasar al has()método la clave "registrar" (o lo que sea que estés usando) así

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

Otra forma de mostrar mensajes de error es la siguiente que prefiero (yo uso Twitter Bootstrap para el diseño pero, por supuesto, puedes cambiarlos con tu propio diseño)

 @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>
Altrim
fuente
1
¿Qué pasa si el nombre del campo es una matriz? Por ejemplo <input type="text" name="txt[]" />",. El error generará algo como The txt.0 is required.. ¿Cómo puedes reemplazarlo con buenos nombres?
Anna Fortuna
@AnnaFortuna Consulte esta publicación para ver si podría ayudarlo a stackoverflow.com/questions/17974231/…
Altrim
Gracias @Altrim, lo comprobaré.
Anna Fortuna
2

Utilizo mis archivos de idioma personalizados como entrada para los "nombres agradables" como este:

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

// translate attributes
if(Lang::has($customLanguageFile)) {
    $validator->setAttributeNames($customLanguageFile);
}
Jan Schwingneschlögl
fuente
2

En Laravel 4.1, la forma fácil de hacer esto es ir a la carpeta lang -> su idioma (predeterminado en) -> validation.php.

Cuando tienes esto en tu modelo, por ejemplo:

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

Y no quiere que el error sea "por favor ingrese un ID de grupo", puede crear mensajes de validación "agradables" agregando una matriz personalizada en validation.php. Entonces, en nuestro ejemplo, la matriz personalizada se vería así:

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

Esto también funciona con aplicaciones en varios idiomas, solo necesita editar (crear) el archivo de validación de idioma correcto.

El idioma predeterminado se almacena en el archivo de configuración app / config / app.php y es el inglés de manera predeterminada. Esto se puede cambiar en cualquier momento utilizando el App::setLocalemétodo.

Puede encontrar más información sobre errores e idiomas aquí validación y localización .

John Smith
fuente
1

El atributo: solo puede usar el nombre del atributo (first_name en su caso), no nombres agradables.

Pero puede definir mensajes personalizados para cada atributo + validación mediante mensajes definidos como este:

$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!',
);
Alexandre Danault
fuente
1

En Laravel 7.

use Illuminate\Support\Facades\Validator;

Luego defina niceNames

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

Y el último, simplemente ponga $ niceNames en el cuarto parámetro, así:

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

Bueno, es una pregunta bastante antigua, pero debo señalar que el problema de que el idioma aparezca en la URL se puede resolver mediante:

  • Cambiar el idioma y fallback_language en config/app.php;
  • o configurando \ App :: setLocale ($ lang)

Si es necesario persistirlo durante la sesión, actualmente uso el "AppServiceProvider" para hacer esto, pero creo que un middleware podría ser un mejor enfoque si se necesita cambiar el idioma por URL, así que me gusta esto en mi proveedor:

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

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

De esta manera manejo la sesión y no se queda en mi URL.

Para aclarar, actualmente estoy usando Laravel 5.1+, pero no debería ser un comportamiento diferente al de 4.x;

Víctor Moura
fuente
0
$customAttributes = [
'email' => 'email address',
];

$validator = Validator::make($input, $rules, $messages, $customAttributes);
Talha Masood
fuente
5
Si bien este código puede proporcionar una solución al problema, se recomienda encarecidamente que brinde un contexto adicional sobre por qué y / o cómo este código responde a la pregunta. Las respuestas de solo código generalmente se vuelven inútiles a largo plazo porque los futuros espectadores que experimentan problemas similares no pueden comprender el razonamiento detrás de la solución.
E. Zeytinci