web-dev-qa-db-fra.com

Comment structurez-vous les fichiers i18n yaml dans Rails?

J'ai commencé à remplir un fichier en yaml en Rails et je peux déjà dire qu'il deviendra désordonné et incontrôlable avant trop longtemps. Existe-t-il une convention pour garder ce fichier organisé?

Jusqu'à présent, j'ai cette structure:

language:
  resource:
    pages: # index, show, new, edit
      page html elements: # h1, title
  activerecord:
    attributes:
      model:
        property:

Maintenant, j'ai les choses suivantes que je veux intégrer dans cette structure mais je ne sais pas comment:

  1. La navigation
  2. Texte du bouton (enregistrer les modifications, créer un compte, etc.)
  3. Messages d'erreur du flash du contrôleur
  4. Comment ajouter des clés multi-mots. Dois-je utiliser un espace ou un trait de soulignement? Pour exmaple, t(".update button")) ou t(".update_button")

Existe-t-il une convention pour la structure des fichiers locaux?

51
Mohamad

J'ai trouvé que la meilleure stratégie globale consiste à reproduire quelque peu la structure du fichier afin que, compte tenu de toute traduction, je puisse immédiatement trouver d'où elle a été appelée. Cela me donne une sorte de contexte pour faire la traduction.

La majorité des traductions d'applications se trouvent dans les vues, donc mon plus grand espace de noms de premier niveau est généralement views.

Je crée des sous-espaces de noms pour le nom du contrôleur et le nom de l'action ou partiel utilisé ex:

  • views.users.index.title
  • views.articles._sidebar.header

Ces deux exemples devraient indiquer clairement quelle partie de mon application nous traduisons et quel fichier rechercher pour le trouver.

Vous mentionnez la navigation et les boutons, s'ils doivent être génériques, alors ils appartiennent au views.application namespace tout comme leurs homologues de vue:

  • views.application._main_nav.links.about_us - un lien dans la navigation principale de notre application
  • views.application.buttons.save
  • views.application.buttons.create - J'ai un tas de ces boutons prêts à être utilisés en cas de besoin

Les messages Flash sont générés à partir du contrôleur, leur espace de noms de niveau supérieur est donc ... controllers! :)

Nous appliquons la même logique que pour les vues:

  • controllers.users.create.flash.success|alert|notice

Encore une fois, si vous vouliez fournir des messages flash génériques comme "Opération réussie", vous écririez quelque chose comme ceci:

  • controllers.application.create.flash.notice

Enfin, les clés peuvent être tout ce qui est YAML valide, mais veuillez vous en tenir aux points . comme séparateurs et soulignements _ entre les mots par convention.

La seule chose qui reste à régler maintenant, c'est d'obtenir les traductions de Rails dans son propre espace de noms pour nettoyer notre niveau supérieur :)

61
tigrish

Je sais qu'une réponse a déjà été acceptée, mais cette question m'a donné matière à réflexion et j'ai pensé partager une autre structure pour les fichiers Rails i18n yml pour votre considération/critique).

Étant donné que je voudrais

  1. conserver la structure d'application par défaut afin que je puisse utiliser des recherches abrégées "paresseuses" comme t('.some_translation') dans mes vues,
  2. éviter autant de répétitions de chaînes que possible, en particulier avec des mots qui ne sont pas seulement les mêmes, mais qui ont également des contextes/significations identiques,
  3. il suffit de changer une clé une fois pour la refléter partout où elle est référencée,

pour un fichier config/locales/en.yml qui ressemble à ceci:

activerecord:
  attributes:
    user:
      email: Email
      name: Name
      password: Password
      password_confirmation: Confirmation
  models:
    user: User
users:
  fields:
    email: Email
    name: Name
    password: Password
    confirmation: Confirmation
sessions:
  new:
    email: Email
    password: Password

Je peux voir qu'il y a une répétition importante et que le contexte de mots comme "Email" et "Mot de passe" est sans ambiguïté et a la même signification dans leurs vues respectives. Ce serait un peu ennuyeux de devoir les changer tous si je décide de changer "Email" en "e-mail", donc je voudrais refactoriser les chaînes pour référencer un dictionnaire. Alors, que diriez-vous d'ajouter un hachage de dictionnaire en haut du fichier avec un peu de & ancres comme celle-ci:

dictionary:
  email: &email Email
  name: &name Name
  password: &password Password
  confirmation: &confirmation Confirmation

activerecord:
  attributes:
    user:
      email: *email
      name: *name
      password: *password
      password_confirmation: *confirmation
  models:
    user: User
users:
  fields:  
    email: *email
    name: *name
    password: *password
    confirmation: *confirmation
sessions:
  new:
    email: *email
    password: *password

Chaque fois que vous obtenez plus d'une instance d'exactement le même mot/phrase dans vos vues, vous pouvez le refactoriser dans le dictionnaire. Si la traduction dans le dictionnaire d'une clé dans la langue de base n'a pas de sens pour une langue cible, remplacez simplement la valeur référencée dans la langue cible par une chaîne statique ou ajoutez-la comme entrée supplémentaire au dictionnaire de la langue cible. Je suis sûr que le dictionnaire de chaque langue pourrait être refactorisé dans un autre fichier s'il devient trop gros et trop lourd.

Cette façon de structurer les fichiers yaml i18n semblait bien fonctionner avec certaines applications de test locales sur lesquelles je l'ai essayé. J'espère que le merveilleux Localeapp fournira un support pour ce type d'ancrage/référencement à l'avenir. Mais de toute façon, toutes ces discussions sur le dictionnaire ne peuvent pas être une idée originale, donc y a-t-il d'autres problèmes avec le référencement d'ancrage dans YAML, ou peut-être simplement avec le concept de "dictionnaire" en général? Ou est-il simplement préférable d'extraire entièrement le backend par défaut et de le remplacer par Redis ou quelque chose?

50
Paul Fioravanti

C'est presque deux ans après avoir posé cette question, et je veux partager quelques idées. Je crois que la structure optimale est de traduire les espaces de noms en fonction de leur rôle MVC (modèles, vues, contrôleurs). Cela maintient le fichier de paramètres régionaux bien rangé et empêche les collisions d'espace de noms (par exemple, la portée en.users Peut représenter une vue ou un contrôleur).

en:
  controllers:
    users:
      show:
        welcome_flash: "Welcome back!"
  mailers:
    users_mailer:
      welcome_email:
        subject: "Good of you to join us"
  views:
    users:
      show:
        notice: "Oh no!

Mais l'utilisation d'espaces de noms bien rangés comme cela rompt la fonctionnalité de recherche paresseuse dans Rails. Si vous utilisez la recherche paresseuse, Rails insérera automatiquement l'espace de noms pour vous et n'inclura pas les espaces de noms de niveau supérieur que vous avez créés (views, controllers, etc...).

Par exemple, la portée de t('.welcome_flash') se résout en en.users.show. Ce qui pue parce que les utilisateurs ne sont pas clairement définis. Qu'Est-ce que c'est? Un contrôleur? Une vue? Autre chose?

Pour résoudre ce problème j'ai créé la gemme I18nLazyLookup . Il vous permet d'utiliser la recherche paresseuse avec vos propres espaces de noms personnalisés.

Au lieu d'utiliser t, vous pouvez utiliser t_scoped('welcome_flash'), ce qui résoudrait automatiquement la portée en en.controllers.users.show. Il fonctionne également pour les vues et les expéditeurs, et vous pouvez personnaliser l'espace de noms comme vous le souhaitez.

8
Mohamad

Il n'est pas facile de répondre à votre question et il n'y a pas beaucoup de matériel disponible sur ce sujet. J'ai trouvé que les meilleures ressources sont:

  • Rails Styleguide , section Internationalisation
  • Il y a beaucoup de ressources dans le wiki I18n , mais je n'en ai pas trouvé qui répondent à vos questions.

Je vais donc essayer directement ici:

  • La navigation

    Je pense que vous voulez dire ici les éléments de navigation comme le fil d'Ariane, les onglets, ... Vous devez définir des vues pour eux, et respectez ensuite la règle pour déplacer tous les éléments de vue dans des fichiers séparés dans le répertoire views (voir le guide de style pour la règle).

  • Texte du bouton (enregistrer les modifications, créer un compte, etc.)

    Affichez les éléments, accédez également aux mêmes fichiers. Si vous utilisez les mêmes boutons dans différentes vues, définissez un fichier commun et utilisez-le ensuite.

  • Messages d'erreur du flash du contrôleur

    J'utiliserais la même règle que pour les vues. Définissez un répertoire séparé, incluez-y les fichiers des contrôleurs.

  • Comment ajouter des clés multi-mots. Dois-je utiliser un espace ou un trait de soulignement? Pour exmaple, t (". Update button")) ou t (". Update_button")

    Personnellement, je préférerais utiliser .update_button, ne pas .update button, car cela rend plus explicite qu'il s'agit d'une clé.

8
mliebelt

Modifier directement les fichiers yaml conduit à des fichiers en désordre et illisibles.
De plus, il vous sera difficile de fournir un accès aux traducteurs si, un jour, vous souhaitez qu'un non-développeur ajoute une nouvelle langue.

Je recommanderais d'utiliser localeapp , qui génère un seul fichier yaml.
Mais vous permet de voir et de gérer facilement vos traductions dans une interface Web.
Et pour créer un accès supplémentaire aux traducteurs.

6
Damien MATHIEU

À venir plusieurs années après la bataille, mais voici une réponse (quelque peu totalement) différente.

Pour commencer, je n'aime pas le style standard t('.xxx') avec l'espace de noms par défaut basé sur la structure du fichier. Je n'aime pas non plus vraiment la catégorisation des traductions en fonction de la structure DOM. Bien qu'il s'agisse d'une bonne approche pour les traductions très structurées, elle est souvent répétitive et peu intuitive.

Je préfère regrouper mes traductions en catégories plus utiles, afin de faciliter la tâche de mes traducteurs, car ils peuvent travailler sur des thèmes concrets plutôt que sur des styles étranges (certains traducteurs ne savent même pas ce que MVC signifie)

donc mon fichier de traduction est structuré comme ceci

fr:
  theme1:
    theme11:
      translationxxx: blabla
  theme2:
    translationyyy: blabla

Selon les besoins, les "thèmes" peuvent être un modèle, un contexte plus abstrait, etc. qui est le plus intuitif pour les traducteurs.

Parce que ce serait compliqué d'écrire à chaque fois la portée de mes vues, j'ai ajouté quelques méthodes pratiques dans mes assistants pour avoir un contexte de traduction basé sur la pile.

  • I Étend la traduction Push/pop sur une pile dans mes vues en appelant t_scope([new_scope] et pop_t
  • Je remplace l'aide t pour utiliser la dernière étendue de la pile

Le code pour les méthodes de portée de traduction est disponible dans cette réponse

0
Cyril Duchon-Doris