Commits

cboos  committed 4dae6a3

i18n: improve upon r8526, use `tngettext` to handle plural form.

Added a `tagn_` synonym for `tngettext` and use that for extraction.

This is still not a "perfect" solution... what about gender?

  • Participants
  • Parent commits 71b73d3
  • Branches trunk

Comments (0)

Files changed (5)

 copyright_holder = Edgewall Software
 msgid_bugs_address = trac-dev@googlegroups.com
 output_file = trac/locale/messages.pot
-keywords = _ ngettext:1,2 N_ tag_
+keywords = _ ngettext:1,2 N_ tag_ tagn_:1,2
 
 [init_catalog]
 input_file = trac/locale/messages.pot

File trac/locale/fr_FR/LC_MESSAGES/messages.po

 msgstr "Ajouter"
 
 #: trac/admin/templates/admin_components.html:80 trac/ticket/admin.py:202
-#: trac/ticket/api.py:222 trac/ticket/web_ui.py:1150
+#: trac/ticket/api.py:222 trac/ticket/web_ui.py:1151
 msgid "Owner"
 msgstr "Propriétaire"
 
 msgid "and"
 msgstr "et"
 
-#: trac/templates/diff_view.html:22 trac/ticket/web_ui.py:772
+#: trac/templates/diff_view.html:22 trac/ticket/web_ui.py:773
 #: trac/ticket/templates/ticket.html:107
 msgid "Initial Version"
 msgstr "Version Initiale"
 msgid "Page %(page)s is beyond the number of pages in the query"
 msgstr "La page %(page)s dépasse le nombre de pages de la requête"
 
-#: trac/ticket/query.py:628 trac/ticket/web_ui.py:605
+#: trac/ticket/query.py:628 trac/ticket/web_ui.py:606
 msgid "Ticket"
 msgstr "Ticket"
 
 msgid "updated"
 msgstr "modifié"
 
-#: trac/ticket/web_ui.py:277
+#: trac/ticket/web_ui.py:278
 #, python-format
 msgid "%(labels)s changed"
-msgstr "%(labels)s modifié(s)"
-
-#: trac/ticket/web_ui.py:357
+msgid_plural "%(labels)s changed"
+msgstr[0] "%(labels)s modifié"
+msgstr[1] "%(labels)s modifiés"
+
+#: trac/ticket/web_ui.py:358
 #, python-format
 msgid "Ticket %(ticketref)s (%(summary)s) %(verb)s"
 msgstr "Le ticket %(ticketref)s (%(summary)s) a été %(verb)s"
 
-#: trac/ticket/web_ui.py:485
+#: trac/ticket/web_ui.py:486
 #, python-format
 msgid "Invalid action \"%(name)s\""
 msgstr "Action invalide \"%(name)s\""
 
-#: trac/ticket/web_ui.py:605
+#: trac/ticket/web_ui.py:606
 msgid "Back to Query"
 msgstr "Retour à"
 
-#: trac/ticket/web_ui.py:681 trac/ticket/web_ui.py:835
+#: trac/ticket/web_ui.py:682 trac/ticket/web_ui.py:836
 msgid "Ticket History"
 msgstr "Historique des Tickets"
 
-#: trac/ticket/web_ui.py:726
+#: trac/ticket/web_ui.py:727
 msgid "No differences to show"
 msgstr "Pas de différences"
 
-#: trac/ticket/web_ui.py:769 trac/ticket/web_ui.py:825
-#: trac/ticket/web_ui.py:833 trac/wiki/web_ui.py:376 trac/wiki/web_ui.py:382
+#: trac/ticket/web_ui.py:770 trac/ticket/web_ui.py:826
+#: trac/ticket/web_ui.py:834 trac/wiki/web_ui.py:376 trac/wiki/web_ui.py:382
 #: trac/wiki/web_ui.py:547 trac/wiki/web_ui.py:561
 #, python-format
 msgid "Version %(num)s"
 msgstr "Version %(num)s"
 
-#: trac/ticket/web_ui.py:772
+#: trac/ticket/web_ui.py:773
 msgid "initial"
 msgstr "initial"
 
-#: trac/ticket/web_ui.py:835 trac/versioncontrol/web_ui/changeset.py:345
+#: trac/ticket/web_ui.py:836 trac/versioncontrol/web_ui/changeset.py:345
 #: trac/wiki/web_ui.py:395
 msgid "Change"
 msgstr "Modifications"
 
-#: trac/ticket/web_ui.py:840
+#: trac/ticket/web_ui.py:841
 msgid "Ticket Diff"
 msgstr "Différence sur le Ticket"
 
-#: trac/ticket/web_ui.py:916
+#: trac/ticket/web_ui.py:917
 #, 
 msgid "No permission to edit description."
 msgstr "Pas le droit de modifier la description."
 
-#: trac/ticket/web_ui.py:919
+#: trac/ticket/web_ui.py:920
 msgid "No permission to change ticket fields."
 msgstr "Pas le droit de changer les champs du ticket."
 
-#: trac/ticket/web_ui.py:935
+#: trac/ticket/web_ui.py:936
 msgid "No permissions to add a comment."
 msgstr "Pas le droit d'ajouter un commentaire."
 
-#: trac/ticket/web_ui.py:941
+#: trac/ticket/web_ui.py:942
 msgid ""
 "Sorry, can not save your changes. This ticket has been modified by "
 "someone else since you started"
 "Desolé, les changements ne peuvent pas étre enregistrés. Ce ticket a été "
 "modifié par un autre utilisateur depuis que l'édition a debuté"
 
-#: trac/ticket/web_ui.py:948
+#: trac/ticket/web_ui.py:949
 msgid "Tickets must contain a summary."
 msgstr "Les Tickets doivent avoir un résumé"
 
-#: trac/ticket/web_ui.py:971
+#: trac/ticket/web_ui.py:972
 #, python-format
 msgid "Ticket description is too long (must be less than %(num)s characters)"
 msgstr ""
 "La description du ticket est trop longue (elle doit être inférieure\n"
 "à %(num)s caractères)"
 
-#: trac/ticket/web_ui.py:978
+#: trac/ticket/web_ui.py:979
 #, python-format
 msgid "Ticket comment is too long (must be less than %(num)s characters)"
 msgstr ""
 "Le commentaire du ticket est trop long (il doit être inférieure\n"
 "à %(num)s caractères)"
 
-#: trac/ticket/web_ui.py:993
+#: trac/ticket/web_ui.py:994
 msgid "Invalid comment threading identifier"
 msgstr "Identifiant du commentaire invalide"
 
-#: trac/ticket/web_ui.py:1000
+#: trac/ticket/web_ui.py:1001
 #, python-format
 msgid "The ticket field '%(field)s' is invalid: %(message)s"
 msgstr "Le champ du ticket '%(field)s' est invalide : %(message)s"
 
-#: trac/ticket/web_ui.py:1180
+#: trac/ticket/web_ui.py:1181
 msgid "Add to Cc"
 msgstr "Ajouter en Copie"
 
-#: trac/ticket/web_ui.py:1181
+#: trac/ticket/web_ui.py:1182
 msgid "Remove from Cc"
 msgstr "Supprimer de Copie"
 
-#: trac/ticket/web_ui.py:1182
+#: trac/ticket/web_ui.py:1183
 msgid "Add/Remove from Cc"
 msgstr "Ajouter/Supprimer en Copie"
 
-#: trac/ticket/web_ui.py:1183
+#: trac/ticket/web_ui.py:1184
 msgid "<Author field>"
 msgstr "<Champ auteur>"
 
-#: trac/ticket/web_ui.py:1204 trac/ticket/templates/query.html:91
+#: trac/ticket/web_ui.py:1205 trac/ticket/templates/query.html:91
 msgid "yes"
 msgstr "oui"
 
-#: trac/ticket/web_ui.py:1204 trac/ticket/templates/query.html:94
+#: trac/ticket/web_ui.py:1205 trac/ticket/templates/query.html:94
 msgid "no"
 msgstr "non"
 
-#: trac/ticket/web_ui.py:1398 trac/versioncontrol/templates/changeset.html:134
+#: trac/ticket/web_ui.py:1399 trac/versioncontrol/templates/changeset.html:134
 msgid "modified"
 msgstr "modifié"
 

File trac/locale/messages.pot

 msgstr ""
 
 #: trac/admin/templates/admin_components.html:80 trac/ticket/admin.py:202
-#: trac/ticket/api.py:222 trac/ticket/web_ui.py:1150
+#: trac/ticket/api.py:222 trac/ticket/web_ui.py:1151
 msgid "Owner"
 msgstr ""
 
 msgid "and"
 msgstr ""
 
-#: trac/templates/diff_view.html:22 trac/ticket/web_ui.py:772
+#: trac/templates/diff_view.html:22 trac/ticket/web_ui.py:773
 #: trac/ticket/templates/ticket.html:107
 msgid "Initial Version"
 msgstr ""
 msgid "Page %(page)s is beyond the number of pages in the query"
 msgstr ""
 
-#: trac/ticket/query.py:628 trac/ticket/web_ui.py:605
+#: trac/ticket/query.py:628 trac/ticket/web_ui.py:606
 msgid "Ticket"
 msgstr ""
 
 msgid "updated"
 msgstr ""
 
-#: trac/ticket/web_ui.py:277
+#: trac/ticket/web_ui.py:278
 #, python-format
 msgid "%(labels)s changed"
-msgstr ""
-
-#: trac/ticket/web_ui.py:357
+msgid_plural "%(labels)s changed"
+msgstr[0] ""
+msgstr[1] ""
+
+#: trac/ticket/web_ui.py:358
 #, python-format
 msgid "Ticket %(ticketref)s (%(summary)s) %(verb)s"
 msgstr ""
 
-#: trac/ticket/web_ui.py:485
+#: trac/ticket/web_ui.py:486
 #, python-format
 msgid "Invalid action \"%(name)s\""
 msgstr ""
 
-#: trac/ticket/web_ui.py:605
+#: trac/ticket/web_ui.py:606
 msgid "Back to Query"
 msgstr ""
 
-#: trac/ticket/web_ui.py:681 trac/ticket/web_ui.py:835
+#: trac/ticket/web_ui.py:682 trac/ticket/web_ui.py:836
 msgid "Ticket History"
 msgstr ""
 
-#: trac/ticket/web_ui.py:726
+#: trac/ticket/web_ui.py:727
 msgid "No differences to show"
 msgstr ""
 
-#: trac/ticket/web_ui.py:769 trac/ticket/web_ui.py:825
-#: trac/ticket/web_ui.py:833 trac/wiki/web_ui.py:376 trac/wiki/web_ui.py:382
+#: trac/ticket/web_ui.py:770 trac/ticket/web_ui.py:826
+#: trac/ticket/web_ui.py:834 trac/wiki/web_ui.py:376 trac/wiki/web_ui.py:382
 #: trac/wiki/web_ui.py:547 trac/wiki/web_ui.py:561
 #, python-format
 msgid "Version %(num)s"
 msgstr ""
 
-#: trac/ticket/web_ui.py:772
+#: trac/ticket/web_ui.py:773
 msgid "initial"
 msgstr ""
 
-#: trac/ticket/web_ui.py:835 trac/versioncontrol/web_ui/changeset.py:345
+#: trac/ticket/web_ui.py:836 trac/versioncontrol/web_ui/changeset.py:345
 #: trac/wiki/web_ui.py:395
 msgid "Change"
 msgstr ""
 
-#: trac/ticket/web_ui.py:840
+#: trac/ticket/web_ui.py:841
 msgid "Ticket Diff"
 msgstr ""
 
-#: trac/ticket/web_ui.py:916
+#: trac/ticket/web_ui.py:917
 msgid "No permission to edit description."
 msgstr ""
 
-#: trac/ticket/web_ui.py:919
+#: trac/ticket/web_ui.py:920
 msgid "No permission to change ticket fields."
 msgstr ""
 
-#: trac/ticket/web_ui.py:935
+#: trac/ticket/web_ui.py:936
 msgid "No permissions to add a comment."
 msgstr ""
 
-#: trac/ticket/web_ui.py:941
+#: trac/ticket/web_ui.py:942
 msgid ""
 "Sorry, can not save your changes. This ticket has been modified by "
 "someone else since you started"
 msgstr ""
 
-#: trac/ticket/web_ui.py:948
+#: trac/ticket/web_ui.py:949
 msgid "Tickets must contain a summary."
 msgstr ""
 
-#: trac/ticket/web_ui.py:971
+#: trac/ticket/web_ui.py:972
 #, python-format
 msgid "Ticket description is too long (must be less than %(num)s characters)"
 msgstr ""
 
-#: trac/ticket/web_ui.py:978
+#: trac/ticket/web_ui.py:979
 #, python-format
 msgid "Ticket comment is too long (must be less than %(num)s characters)"
 msgstr ""
 
-#: trac/ticket/web_ui.py:993
+#: trac/ticket/web_ui.py:994
 msgid "Invalid comment threading identifier"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1000
+#: trac/ticket/web_ui.py:1001
 #, python-format
 msgid "The ticket field '%(field)s' is invalid: %(message)s"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1180
+#: trac/ticket/web_ui.py:1181
 msgid "Add to Cc"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1181
+#: trac/ticket/web_ui.py:1182
 msgid "Remove from Cc"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1182
+#: trac/ticket/web_ui.py:1183
 msgid "Add/Remove from Cc"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1183
+#: trac/ticket/web_ui.py:1184
 msgid "<Author field>"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1204 trac/ticket/templates/query.html:91
+#: trac/ticket/web_ui.py:1205 trac/ticket/templates/query.html:91
 msgid "yes"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1204 trac/ticket/templates/query.html:94
+#: trac/ticket/web_ui.py:1205 trac/ticket/templates/query.html:94
 msgid "no"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1398 trac/versioncontrol/templates/changeset.html:134
+#: trac/ticket/web_ui.py:1399 trac/versioncontrol/templates/changeset.html:134
 msgid "modified"
 msgstr ""
 

File trac/ticket/web_ui.py

 from trac.util.text import CRLF, shorten_line, obfuscate_email_address, \
                            exception_to_unicode
 from trac.util.presentation import separated
-from trac.util.translation import _, tag_, N_, gettext
+from trac.util.translation import _, tag_, tagn_, N_, gettext
 from trac.versioncontrol.diff import get_diff_options, diff_blocks
 from trac.web import parse_query_string, IRequestHandler
 from trac.web.chrome import add_link, add_script, add_stylesheet, \
                     if len(fields) > 0:
                         labels = [tag.i(field_labels.get(k, k.capitalize()))
                                   for k in fields.keys()]
-                        info = tag_('%(labels)s changed',
+                        info = tagn_('%(labels)s changed',
+                                     '%(labels)s changed', len(labels),
                                     labels=separated(labels, ', ')) + tag.br()
                 else:
                     return None

File trac/util/translation.py

       'tgettext': tgettext_noop,
       'tag_': tgettext_noop,
       'tngettext': tngettext_noop,
+      'tagn_': tngettext_noop,
       'add_domain': lambda env_path, locale_dir: None,
       }
     return [_functions[s] for s in symbols]
           'tgettext': translations.dtgettext,
           'tag_': translations.dtgettext,
           'tngettext': translations.dtngettext,
+          'tagn_': translations.dtngettext,
           'add_domain': translations.add_domain,
           }
         def wrapdomain(symbol):
     tag_ = tgettext 
     dtgettext = translations.dtgettext 
     tngettext = translations.tngettext 
+    tagn_ = tngettext 
     dtngettext = translations.dtngettext 
     
     def deactivate():
     dngettext = dngettext_noop
     tgettext = tag_ = tgettext_noop
     dtgettext = dtgettext_noop
-    tngettext = tngettext_noop
+    tngettext = tagn_ = tngettext_noop
     dtngettext = dtngettext_noop
 
     def activate(locale, env_path=None):