Comment traduire les messages d’erreurs de Ruby on Rails
Rails nous offre beaucoup de fonctions et d’outils qui facilitent et accélère le développement d’un site. Prenez l’affichage des messages d’erreurs de saisie par exemple. Il suffit d’ajouter <%= error_messages_for(“nom_du_modele”) %> à notre page afin que s’affiche « auto-magiquement » le ou les messages d’erreurs à l’usager. Le problème ici c’est qu’Auto, le magicien, semble être unilingue anglais.
La technique décrite dans cet article vous permettra de traduire les messages d’erreurs rendus par la fonction error_messages_for. Cependant, il faut souligner que cette méthode ne servira que dans le cadre d’un site unilingue. Si vous souhaitez créer un site multilingue, vous devriez considérer une librairie complète de localisation telle que Globalize. Cela dit, quoique possible, je crois que l’utilisation d’un tel plug-in pour la gestion d’une seule langue générerait beaucoup d’ overhead inutile (recherche des mots et formats d’affichages dans la BD ou fichiers YAML) comparativement à la méthode qui sera décrite ici.
Anatomie du message d’erreur
Avant de commencer à traduire les messages d’erreurs, il faut savoir d’où provient l’information affichée (donc, à traduire). Alors, voici comment se présente un message d’erreur rendu par la fonction error_messages_for :

L’ensemble du code XHTML, incluant le titre et sous-titre, provient évidemment de la fonction error_messages_for (ActionView::Helpers::ActiveRecordHelper). La collection de messages d’erreurs, en vert, est retournée par la fonction full_messages (ActiveRecord::Errors). En bleu, c’est le nom du champ humanisé via la fonction humanize (ActiveSupport::CoreExtensions::String::Inflections). Le message de validation, en jaune, provient de la collection de messages default_error_messages qui se trouve également dans la classe ActiveRecord::Errors.
Traduction des messages de validations
La première étape consiste à redéfinir les messages d’erreurs de validation qui sont utilisés lorsque des validations faites via les méthodes validates_presence_of ou validates_uniqueness_of par exemple, échouent. Ces messages peuvent être redéfinis comme suit :
module ActiveRecord class Errors @@default_error_messages.update( { :inclusion => "n'est pas inclut dans la liste", :exclusion => "est réservé", :invalid => "est invalide", :confirmation => "ne correspond pas à la confirmation", :accepted => "doit être accepté", :empty => "ne peut pas être vide", :blank => "est requis", :too_long => "est trop long (%d caractères maximum)", :too_short => "est trop court(%d caractères minimum)", :wrong_length => "n'est pas de la bonne longueur (devrait être de %d caractères)", :taken => "est déjà prit", :not_a_number => "n'est pas un nombre", }) end end
Attention, si vous définissez un message personnalisé via l’attribut :message, ce message ne sera pas traduit (ou retraduit si vous changez de langue). Il serait préférable d’ajouter le message personnalisé à la collection default_error_messages. Aussi, lorsque vous faites des validations via les événements d’un modèle, vous pouvez utiliser les messages de la collection via ActiveRecord::Errors::default_error_messages[:key]. Voici un exemple :
def validate_on_create if self.password.empty? errors.add(:password, ActiveRecord::Errors::default_error_messages[:empty]) end end
Après implémentation, notre message d’erreur ressemble à ceci :

Traduction et « Humanisation » des noms de champs
L’objet modèle des versions antérieures à Rails 1.2 exposait une fonction nommée « human_attribute_name ». Pour traduire et/ou donner un nom d’affichage plus significatif à vos champs, il suffisait d’ overrider cette méthode afin qu’elle retourne le nom désiré selon l’attribut demandé. Puisqu’elle n’existe plus, il suffit de la créer :
module ActiveRecord class Errors class Base class << self def localized_human_attribute_name(attr) attr.humanize end end end end end
Si elle n’est pas overridée par votre modèle, la fonction localized_human_attribute_name retournera le nom du champ « humanisé » (comportement standard de Rails 1.2). Cependant, pour chaque modèle qui requiert des noms de champs traduits, nous devons redéfinir la fonction comme suit:
class User < ActiveRecord::Base def self.localized_human_attribute_name(attr) return case attr when "email" then "Adresse courriel" when "name" then "Nom" when "password" then "Mot de passe" else attr.humanize end end end
Traduction des messages d’erreurs
Le message d’erreur complet (composé du nom du champ et de l’erreur de validation) provient de la collection de messages retournée par la fonction full_messages (ActiveRecord::Errors). Il s’agit donc de redéfinir cette fonction afin que le nom localisé et/ou « humanisé » du champ (retourné par localized_human_attribute_name) soit utilisé lors de la construction d’un message d’erreur :
module ActiveRecord class Errors def full_messages full_messages = [] @errors.each_key do |attr| @errors[attr].each do |msg| next if msg.nil? if attr == "base" full_messages << msg else full_messages << @base.class.localized_human_attribute_name(attr) + " " + msg end end end full_messages end end end
Les messages d’erreurs de validation affichés sont à présent, complètement traduits :

Traduction du Titre et sous-titre
La dernière étape consiste à traduire le titre et le sous-titre. Pour ce faire, nous devons redéfinir la fonction error_messages_for.
module ActionView module Helpers module ActiveRecordHelper def error_messages_for(object_name, options = {}) options = options.symbolize_keys object = instance_variable_get("@#{object_name}") unless object.errors.empty? content_tag("div", content_tag( options[:header_tag] || "h2", "#{pluralize(object.errors.count, "erreurs")} empêche(nt) cette forme d'être sauvegardée" ) + content_tag("p", "Veuillez vérifier les informations et apporter les modifications aux champs suivants :" ) + content_tag("ul", object.errors.full_messages.collect { |msg| content_tag("li", "Le champ " + msg) }), "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation" ) end end end end end
Ici, comme vous pouvez le constater, vous avez également la possibilité de modifier les balises qui sont utilisées à la construction du message d’erreur.
Note : Puisqu’il serait plus complexe de gérer le genre du nom des modèles dans un message d’erreur (« ce livre n’a pu être sauvegardé » versus « cette photo n’a pu être sauvegardée »), j’ai remplacé le nom du modèle par « forme » dans le titre du message. Si vous désirez utiliser le nom du modèle, remplacer « forme » par #{object_name.to_s.gsub(”_”, ” “)}.
Notre message d’erreurs est maintenant traduit :

Implémentation
Il vous suffit de placer le code dans le répertoire /lib de votre application et d’ajouter la ligne suivante à la fin de votre fichier /config/environment.rb :
require 'french_errors_localization'
Il y a 0 commentaires pour cet article
La discussion est fermée pour les non-membres. Vous pouvez lire les commentaires. Pour ajouter votre commentaire, vous devrez vous identifier ou vous enregistrer si vous n'êtes pas déjà membre.