Christian Boos wrote:
> Hello Richard,
>
> Thanks for pointing out the problematic places left.
>
> Richard Liao wrote:
>   
>> Hi,
>>
>> I'm trying to make a fully translated trac 0.12 based on the trunk(r7002).
>>
>> What I have done:
>> 1. Fully translated the messages.po file.
>> 2. Fully translated the default wiki pages into our local language: zh_CN.
>>  (I have noticed new help branch in sandbox, but currently, I have to
>> translate these wiki pages.)
>>
>> The problem is: the UI elements are not fully i18n-ed.
>> 1. Some string is not i18n-ed in py files.
>> e.g.
>> trac/ticket/web_ui.py: line 308:309
>>             return tag('Ticket ', tag.em('#', ticket.id, title=title),
>>                        ' (', shorten_line(summary), ') ', verb)
>> those should be:
>>             return tag(_('Ticket '), tag.em('#', ticket.id, title=title),
>>                        ' (', shorten_line(summary), ') ', _(verb))
>> How do I submit a patch?
>>   
>>     
>
> _(verb) won't work. We rather have to spot the original string 
> definitions that can end up in this variable.
>
> The above will be rewritten differently:
>
> M_('Ticket %(ticketref)s (%(summary)s) %(verb)s'), 
>    ticketref=tag.em('#', ticket.id, title=title),
>    summary=shorten_line(summary), verb=verb))
>
>
> with M_ a new keyword for indicating Markup strings.
> I'll try to find some time later today to prototype it.
>
>   

Well, here it is. The code in trac.util.translation could certainly be 
simplified a bit, but that's a first step.
You can see it at works in the fr_FR locale, looking at ticket changes 
in the timeline.
You can also see that there's a problem with the "by" which remains 
untranslated.
Seems to be the same issue as below:

>>
>> 3. Since some template strings in pot file can't be displayed
>> correctly by current Genshi ticket #129.
>> And I want to make all template work for now. Can we make all template
>> strings i18n-ed by hand?
>> e.g.
>>  trac/ticket/template/ticket.html: line 139
>>               <th id="h_reporter">Reported by:</th>
>>               <th id="h_reporter">${_('Reported by:')}</th>
>>   
>>     
>
> What's the problem here? A text node inside a  <th>, why is that not 
> extracted?
>   

I'm not sure if it's related to Genshi #129.
For example, for the "by" in the timeline.html template, the source is:

41                <span class="time">${format_time(event.date, 
str('%H:%M'))}</span> ${event.render('title', context)}
42                <py:if test="event.author">by <span 
class="author">${format_author(event.author)}</span></py:if>

and in the message.pot file, we have:

#: trac/timeline/templates/timeline.html:42
msgid "by"

Should have been "by ".
In the message.po, neither the translation for "by" nor "by " as msgid 
gets picked up when rendering.

-- Christian


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Trac 
Development" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/trac-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Index: trac/ticket/web_ui.py
===================================================================
--- trac/ticket/web_ui.py	(revision 7039)
+++ trac/ticket/web_ui.py	(working copy)
@@ -43,7 +43,7 @@
 from trac.util.datefmt import to_timestamp, utc
 from trac.util.text import CRLF, shorten_line, obfuscate_email_address
 from trac.util.presentation import separated
-from trac.util.translation import _
+from trac.util.translation import _, M_, N_, gettext
 from trac.versioncontrol.diff import get_diff_options, diff_blocks
 from trac.web import IRequestHandler
 from trac.web.chrome import add_link, add_script, add_stylesheet, \
@@ -208,10 +208,10 @@
         ts_start = to_timestamp(start)
         ts_stop = to_timestamp(stop)
 
-        status_map = {'new': ('newticket', 'created'),
-                      'reopened': ('reopenedticket', 'reopened'),
-                      'closed': ('closedticket', 'closed'),
-                      'edit': ('editedticket', 'updated')}
+        status_map = {'new': ('newticket', N_('created')),
+                      'reopened': ('reopenedticket', N_('reopened')),
+                      'closed': ('closedticket', N_('closed')),
+                      'edit': ('editedticket', N_('updated'))}
 
         ticket_realm = Resource('ticket')
 
@@ -305,8 +305,9 @@
         elif field == 'title':
             title = TicketSystem(self.env).format_summary(summary, status,
                                                           resolution, type)
-            return tag('Ticket ', tag.em('#', ticket.id, title=title),
-                       ' (', shorten_line(summary), ') ', verb)
+            return M_('Ticket %(ticketref)s (%(summary)s) %(verb)s', 
+                      ticketref=tag.em('#', ticket.id, title=title),
+                      summary=shorten_line(summary), verb=gettext(verb))
         elif field == 'description':
             descr = message = ''
             if status == 'new':
Index: trac/locale/fr_FR/LC_MESSAGES/messages.po
===================================================================
--- trac/locale/fr_FR/LC_MESSAGES/messages.po	(revision 7039)
+++ trac/locale/fr_FR/LC_MESSAGES/messages.po	(working copy)
@@ -9,7 +9,7 @@
 "Project-Id-Version: Trac 0.12\n"
 "Report-Msgid-Bugs-To: [EMAIL PROTECTED]"
 "POT-Creation-Date: 2007-08-15 09:47+0200\n"
-"PO-Revision-Date: 2008-05-06 11:57+0200\n"
+"PO-Revision-Date: 2008-05-09 19:15+0200\n"
 "Last-Translator: Emmanuel Blot <[EMAIL PROTECTED]>\n"
 "Language-Team: fr_FR <[email protected]>\n"
 "Plural-Forms: nplurals=2; plural=(n > 1)\n"
@@ -51,7 +51,7 @@
 
 #: trac/attachment.py:474
 msgid " attached to "
-msgstr " attaché à"
+msgstr " attaché à "
 
 #: trac/attachment.py:513
 #, python-format
@@ -97,7 +97,7 @@
 msgstr "%(attachment)s (suppression)"
 
 #: trac/attachment.py:664 trac/versioncontrol/web_ui/browser.py:511
-#: trac/wiki/web_ui.py:63
+#: trac/wiki/web_ui.py:66
 msgid "Plain Text"
 msgstr "Texte Brut"
 
@@ -699,35 +699,35 @@
 msgid "Released"
 msgstr "Livrée"
 
-#: trac/db/api.py:97
+#: trac/db/api.py:98
 #, python-format
 msgid "Unsupported database type \"%(scheme)s\""
 msgstr ""
 
-#: trac/db/api.py:120
+#: trac/db/api.py:121
 msgid "Database connection string must start with scheme:/"
 msgstr ""
 
-#: trac/db/mysql_backend.py:148
+#: trac/db/mysql_backend.py:149
 msgid "MySQL servers older than 4.1 are not supported!"
 msgstr ""
 
-#: trac/db/pool.py:107
+#: trac/db/pool.py:108
 #, python-format
 msgid "Unable to get database connection within %(time)d seconds"
 msgstr ""
 
-#: trac/db/sqlite_backend.py:131
+#: trac/db/sqlite_backend.py:132
 #, python-format
 msgid "Database already exists at %(path)s"
 msgstr ""
 
-#: trac/db/sqlite_backend.py:159
+#: trac/db/sqlite_backend.py:160
 #, fuzzy, python-format
 msgid "Database \"%(path)s\" not found."
 msgstr ""
 
-#: trac/db/sqlite_backend.py:168
+#: trac/db/sqlite_backend.py:169
 #, python-format
 msgid ""
 "The user %(user)s requires read _and_ write permission to the database "
@@ -899,13 +899,12 @@
 "\"Greenwich (GMT)."
 
 #: trac/prefs/templates/prefs_datetime.html:36
-#, fuzzy
 msgid ""
 "A positive offset is used to indicate a timezone at the east of "
 "Greenwich, i.e. ahead of Universal Time."
 msgstr ""
 "Un décalage positif est utilisé pour indiquer un fuseau horaire situé à "
-"l'Est de Greenwhich, c.à.d. en avance sur l'Heure Universelle."
+"l'Est de Greenwich, c.à.d. en avance sur l'Heure Universelle."
 
 #: trac/prefs/templates/prefs_general.html:15
 msgid "Full name:"
@@ -1257,7 +1256,7 @@
 
 #: trac/templates/diff_view.html:19 trac/templates/diff_view.html:25
 #: trac/templates/history_view.html:26 trac/ticket/templates/ticket.html:100
-#: trac/wiki/web_ui.py:511 trac/wiki/templates/wiki_view.html:25
+#: trac/wiki/web_ui.py:519 trac/wiki/templates/wiki_view.html:25
 msgid "Version"
 msgstr "Version"
 
@@ -1266,7 +1265,7 @@
 msgid "and"
 msgstr "et"
 
-#: trac/templates/diff_view.html:22 trac/ticket/web_ui.py:716
+#: trac/templates/diff_view.html:22 trac/ticket/web_ui.py:717
 #: trac/ticket/templates/ticket.html:97
 msgid "Initial Version"
 msgstr "Version Initiale"
@@ -1374,7 +1373,7 @@
 #: trac/templates/error.html:84
 #, fuzzy
 msgid "Create"
-msgstr "Crée"
+msgstr "Créer"
 
 #: trac/templates/error.html:99
 msgid "Oops…"
@@ -1449,13 +1448,13 @@
 "Néanmoins, avant de rapporter ce problème, merci de vérifier avant tout "
 "de [1:rechercher] des erreurs similaires, car il est fortement probable "
 "que ce problème ait déjà été rapporté précédemment. Pour toutes les "
-"questions relatives a l'installation et/ou la configuration de Trac, merci "
-"de poster un message dans la [2:liste de discussion] plutôt que de remplir "
-"un nouveau ticket."
+"questions relatives a l'installation et/ou la configuration de Trac, "
+"merci de poster un message dans la [2:liste de discussion] plutôt que de "
+"remplir un nouveau ticket."
 
 #: trac/templates/error.html:136
 msgid "Otherwise, please"
-msgstr "Sinon, merci"
+msgstr "Sinon, merci de"
 
 #: trac/templates/error.html:136
 msgid ""
@@ -1821,17 +1820,21 @@
 msgid "Next status will be '%(name)s'"
 msgstr "Le prochain status sera '%(name)s'"
 
-#: trac/ticket/model.py:361
+#: trac/ticket/model.py:128
+msgid "Multi-values fields not supported yet"
+msgstr ""
+
+#: trac/ticket/model.py:363
 #, fuzzy, python-format
 msgid "%(type)s %(name)s does not exist."
 msgstr "%(type)s %(name)s n'existe pas"
 
-#: trac/ticket/model.py:505
+#: trac/ticket/model.py:507
 #, fuzzy, python-format
 msgid "Component %(name)s does not exist."
 msgstr "Composant %(name)s n'existe pas."
 
-#: trac/ticket/model.py:735
+#: trac/ticket/model.py:737
 #, fuzzy, python-format
 msgid "Version %(name)s does not exist."
 msgstr "Version %(name)s n'existe pas"
@@ -1855,7 +1858,7 @@
 msgid "Created"
 msgstr "Crée"
 
-#: trac/ticket/query.py:590 trac/ticket/web_ui.py:548
+#: trac/ticket/query.py:590 trac/ticket/web_ui.py:549
 msgid "Ticket"
 msgstr "Ticket"
 
@@ -2050,59 +2053,80 @@
 msgid "Ticket details"
 msgstr "Détails du Ticket"
 
-#: trac/ticket/web_ui.py:437
+#: trac/ticket/web_ui.py:211
+msgid "created"
+msgstr "créé"
+
+#: trac/ticket/web_ui.py:212
+msgid "reopened"
+msgstr "ouvert"
+
+#: trac/ticket/web_ui.py:213
+msgid "closed"
+msgstr "fermé"
+
+#: trac/ticket/web_ui.py:214
+msgid "updated"
+msgstr "modifié"
+
+#: trac/ticket/web_ui.py:310
+#, 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:438
 #, fuzzy, python-format
 msgid "Invalid action \"%(name)s\""
 msgstr "Action invalide \"%(name)s\""
 
-#: trac/ticket/web_ui.py:548
+#: trac/ticket/web_ui.py:549
 #, fuzzy
 msgid "Back to Query"
 msgstr "Retour à"
 
-#: trac/ticket/web_ui.py:628 trac/ticket/web_ui.py:778
+#: trac/ticket/web_ui.py:629 trac/ticket/web_ui.py:779
 msgid "Ticket History"
 msgstr "Historique des Tickets"
 
-#: trac/ticket/web_ui.py:673
+#: trac/ticket/web_ui.py:674
 #, fuzzy
 msgid "No differences to show"
 msgstr "Pas de différences"
 
-#: trac/ticket/web_ui.py:713 trac/ticket/web_ui.py:768
-#: trac/ticket/web_ui.py:776 trac/wiki/web_ui.py:347 trac/wiki/web_ui.py:353
-#: trac/wiki/web_ui.py:499 trac/wiki/web_ui.py:507
+#: trac/ticket/web_ui.py:714 trac/ticket/web_ui.py:769
+#: trac/ticket/web_ui.py:777 trac/wiki/web_ui.py:355 trac/wiki/web_ui.py:361
+#: trac/wiki/web_ui.py:507 trac/wiki/web_ui.py:515
 #, python-format
 msgid "Version %(num)s"
 msgstr "Version %(num)s"
 
-#: trac/ticket/web_ui.py:716
+#: trac/ticket/web_ui.py:717
 msgid "initial"
 msgstr ""
 
-#: trac/ticket/web_ui.py:778 trac/versioncontrol/web_ui/changeset.py:342
-#: trac/wiki/web_ui.py:366
+#: trac/ticket/web_ui.py:779 trac/versioncontrol/web_ui/changeset.py:342
+#: trac/wiki/web_ui.py:374
 #, fuzzy
 msgid "Change"
 msgstr "Modifications"
 
-#: trac/ticket/web_ui.py:783
+#: trac/ticket/web_ui.py:784
 msgid "Ticket Diff"
 msgstr "Différence sur le Ticket"
 
-#: trac/ticket/web_ui.py:851
+#: trac/ticket/web_ui.py:852
 msgid "No permission to change ticket fields."
 msgstr "Pas le droit de changer les champs du ticket."
 
-#: trac/ticket/web_ui.py:859
+#: trac/ticket/web_ui.py:860
 msgid "No permissions to change ticket fields."
 msgstr "Pas les droits de changer les champs du ticket."
 
-#: trac/ticket/web_ui.py:868
+#: trac/ticket/web_ui.py:869
 msgid "No permissions to add a comment."
 msgstr "Pas le droit d'ajouter un commentaire."
 
-#: trac/ticket/web_ui.py:874
+#: trac/ticket/web_ui.py:875
 msgid ""
 "Sorry, can not save your changes. This ticket has been modified by "
 "someone else since you started"
@@ -2110,65 +2134,65 @@
 "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:881
+#: trac/ticket/web_ui.py:882
 msgid "Tickets must contain a summary."
 msgstr "Les Tickets doivent avoir un résumé"
 
-#: trac/ticket/web_ui.py:904
+#: trac/ticket/web_ui.py:905
 #, 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:919
+#: trac/ticket/web_ui.py:920
 msgid "Invalid comment threading identifier"
 msgstr "Identifiant du commentaire invalide"
 
-#: trac/ticket/web_ui.py:926
+#: trac/ticket/web_ui.py:927
 #, 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:1036
+#: trac/ticket/web_ui.py:1037
 msgid "Assign to"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1052
+#: trac/ticket/web_ui.py:1053
 #, fuzzy
 msgid "Open"
 msgstr "Ouvert"
 
-#: trac/ticket/web_ui.py:1053
+#: trac/ticket/web_ui.py:1054
 #, fuzzy
 msgid "Closed"
-msgstr "Termé"
+msgstr "Fermé"
 
-#: trac/ticket/web_ui.py:1068
+#: trac/ticket/web_ui.py:1069
 msgid "Add to Cc"
 msgstr "Ajouter en Copie"
 
-#: trac/ticket/web_ui.py:1069
+#: trac/ticket/web_ui.py:1070
 msgid "Remove from Cc"
 msgstr "Supprimer de Copie"
 
-#: trac/ticket/web_ui.py:1070
+#: trac/ticket/web_ui.py:1071
 msgid "Add/Remove from Cc"
 msgstr "Ajouter/Supprimer en Copie"
 
-#: trac/ticket/web_ui.py:1071
+#: trac/ticket/web_ui.py:1072
 msgid "<Author field>"
 msgstr "<Champ auteur>"
 
-#: trac/ticket/web_ui.py:1090 trac/ticket/templates/query.html:93
+#: trac/ticket/web_ui.py:1091 trac/ticket/templates/query.html:93
 msgid "yes"
 msgstr "oui"
 
-#: trac/ticket/web_ui.py:1090 trac/ticket/templates/query.html:96
+#: trac/ticket/web_ui.py:1091 trac/ticket/templates/query.html:96
 msgid "no"
 msgstr "non"
 
-#: trac/ticket/web_ui.py:1260 trac/versioncontrol/templates/changeset.html:130
+#: trac/ticket/web_ui.py:1261 trac/versioncontrol/templates/changeset.html:130
 msgid "modified"
 msgstr "modifié"
 
@@ -2782,9 +2806,9 @@
 "Diff mismatch: Base is a %(oldnode)s (%(oldpath)s in revision %(oldrev)s)"
 " and Target is a %(newnode)s (%(newpath)s in revision %(newrev)s)."
 msgstr ""
-"Discordance du diff : La Base est %(oldnode)s (%(oldpath)s dans la "
-"révision %(oldrev)s) et la Destination est %(newnode)s (%(newpath)s dans "
-"la révision %(newrev)s)."
+"Discordance de comparaison : La Base est %(oldnode)s (%(oldpath)s dans la"
+" révision %(oldrev)s) et la Destination est %(newnode)s (%(newpath)s dans"
+" la révision %(newrev)s)."
 
 #: trac/versioncontrol/svn_fs.py:803
 #, fuzzy, python-format
@@ -2802,20 +2826,21 @@
 #: trac/versioncontrol/templates/browser.html:63
 #, fuzzy
 msgid "Go!"
-msgstr "avant"
+msgstr "Changer"
 
 #: trac/versioncontrol/templates/browser.html:63
 msgid "Jump to the chosen preselected path"
-msgstr "Saut direct au chemin préselectionné"
+msgstr "Saut direct au chemin présélectionné"
 
 #: trac/versioncontrol/templates/browser.html:82
 #: trac/versioncontrol/templates/revisionlog.html:92
 #: trac/versioncontrol/web_ui/browser.py:622
 msgid "Rev"
-msgstr "Rév"
+msgstr "Rév."
 
 #: trac/versioncontrol/templates/browser.html:84
-#: trac/versioncontrol/web_ui/browser.py:373 trac/wiki/web_ui.py:533
+#: trac/versioncontrol/web_ui/browser.py:373 trac/wiki/web_ui.py:520
+#: trac/wiki/web_ui.py:544
 msgid "Last Change"
 msgstr "Dernière modification"
 
@@ -3257,71 +3282,75 @@
 msgid "Page not modified"
 msgstr "Page non modifiée"
 
-#: trac/wiki/web_ui.py:82 trac/wiki/web_ui.py:585
+#: trac/wiki/web_ui.py:85 trac/wiki/web_ui.py:596
 msgid "Wiki"
 msgstr "Wiki"
 
-#: trac/wiki/web_ui.py:84
+#: trac/wiki/web_ui.py:87
 msgid "Help/Guide"
 msgstr "Aide/Guide"
 
-#: trac/wiki/web_ui.py:119
+#: trac/wiki/web_ui.py:122
 #, python-format
 msgid "No version \"%(num)s\" for Wiki page \"%(name)s\""
 msgstr "Pas de version \"%(num)s\" pour la page Wiki \"%(name)s\""
 
-#: trac/wiki/web_ui.py:248
+#: trac/wiki/web_ui.py:181
 #, python-format
 msgid "The Wiki page field '%(field)s' is invalid: %(message)s"
 msgstr "Le champ '%(field)s' de la page Wiki est invalide: %(message)s"
 
-#: trac/wiki/web_ui.py:252
+#: trac/wiki/web_ui.py:185
 #, python-format
 msgid "Invalid Wiki page: %(message)s"
 msgstr "Page Wiki invalide: %(message)s"
 
-#: trac/wiki/web_ui.py:295
+#: trac/wiki/web_ui.py:271
+msgid "Page not modified, showing latest version."
+msgstr ""
+
+#: trac/wiki/web_ui.py:303
 #, fuzzy, python-format
 msgid "Version %(num)s of page \"%(name)s\" does not exist"
 msgstr "La version %(num)s de la page %(name)s n'existe pas"
 
-#: trac/wiki/web_ui.py:349
+#: trac/wiki/web_ui.py:357
 msgid "Page history"
 msgstr "Historique de la page"
 
-#: trac/wiki/web_ui.py:366
+#: trac/wiki/web_ui.py:374
 #, fuzzy
 msgid "Wiki History"
 msgstr "Historique des Tickets"
 
-#: trac/wiki/web_ui.py:431
+#: trac/wiki/web_ui.py:439
 #, python-format
 msgid "Page %(name)s does not exist"
 msgstr "La page %(name)s n'existe pas"
 
-#: trac/wiki/web_ui.py:468
+#: trac/wiki/web_ui.py:476
 #, python-format
 msgid "Page %(name)s not found"
 msgstr "La page %(name)s est introuvable"
 
-#: trac/wiki/web_ui.py:502 trac/wiki/web_ui.py:511
+#: trac/wiki/web_ui.py:510 trac/wiki/web_ui.py:519
 #, fuzzy
 msgid "View Latest Version"
 msgstr "Explorer cette version"
 
-#: trac/wiki/web_ui.py:528
+#: trac/wiki/web_ui.py:539
 msgid "Start Page"
 msgstr "Page d'accueil"
 
-#: trac/wiki/web_ui.py:529
+#: trac/wiki/web_ui.py:540
 msgid "Index"
 msgstr "Index"
 
-#: trac/wiki/web_ui.py:531
+#: trac/wiki/web_ui.py:542
 msgid "History"
 msgstr "Historique"
 
-#: trac/wiki/web_ui.py:541
+#: trac/wiki/web_ui.py:552
 msgid "Wiki changes"
 msgstr "Modification Wiki"
 
Index: trac/locale/messages.pot
===================================================================
--- trac/locale/messages.pot	(revision 7039)
+++ trac/locale/messages.pot	(working copy)
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: Trac 0.12\n"
 "Report-Msgid-Bugs-To: [EMAIL PROTECTED]"
-"POT-Creation-Date: 2008-05-05 15:14+0200\n"
+"POT-Creation-Date: 2008-05-09 19:15+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <[EMAIL PROTECTED]>\n"
 "Language-Team: LANGUAGE <[EMAIL PROTECTED]>\n"
@@ -96,7 +96,7 @@
 msgstr ""
 
 #: trac/attachment.py:664 trac/versioncontrol/web_ui/browser.py:511
-#: trac/wiki/web_ui.py:63
+#: trac/wiki/web_ui.py:66
 msgid "Plain Text"
 msgstr ""
 
@@ -675,35 +675,35 @@
 msgid "Released"
 msgstr ""
 
-#: trac/db/api.py:97
+#: trac/db/api.py:98
 #, python-format
 msgid "Unsupported database type \"%(scheme)s\""
 msgstr ""
 
-#: trac/db/api.py:120
+#: trac/db/api.py:121
 msgid "Database connection string must start with scheme:/"
 msgstr ""
 
-#: trac/db/mysql_backend.py:148
+#: trac/db/mysql_backend.py:149
 msgid "MySQL servers older than 4.1 are not supported!"
 msgstr ""
 
-#: trac/db/pool.py:107
+#: trac/db/pool.py:108
 #, python-format
 msgid "Unable to get database connection within %(time)d seconds"
 msgstr ""
 
-#: trac/db/sqlite_backend.py:131
+#: trac/db/sqlite_backend.py:132
 #, python-format
 msgid "Database already exists at %(path)s"
 msgstr ""
 
-#: trac/db/sqlite_backend.py:159
+#: trac/db/sqlite_backend.py:160
 #, python-format
 msgid "Database \"%(path)s\" not found."
 msgstr ""
 
-#: trac/db/sqlite_backend.py:168
+#: trac/db/sqlite_backend.py:169
 #, python-format
 msgid ""
 "The user %(user)s requires read _and_ write permission to the database "
@@ -1169,7 +1169,7 @@
 
 #: trac/templates/diff_view.html:19 trac/templates/diff_view.html:25
 #: trac/templates/history_view.html:26 trac/ticket/templates/ticket.html:100
-#: trac/wiki/web_ui.py:511 trac/wiki/templates/wiki_view.html:25
+#: trac/wiki/web_ui.py:519 trac/wiki/templates/wiki_view.html:25
 msgid "Version"
 msgstr ""
 
@@ -1178,7 +1178,7 @@
 msgid "and"
 msgstr ""
 
-#: trac/templates/diff_view.html:22 trac/ticket/web_ui.py:716
+#: trac/templates/diff_view.html:22 trac/ticket/web_ui.py:717
 #: trac/ticket/templates/ticket.html:97
 msgid "Initial Version"
 msgstr ""
@@ -1690,17 +1690,21 @@
 msgid "Next status will be '%(name)s'"
 msgstr ""
 
-#: trac/ticket/model.py:361
+#: trac/ticket/model.py:128
+msgid "Multi-values fields not supported yet"
+msgstr ""
+
+#: trac/ticket/model.py:363
 #, python-format
 msgid "%(type)s %(name)s does not exist."
 msgstr ""
 
-#: trac/ticket/model.py:505
+#: trac/ticket/model.py:507
 #, python-format
 msgid "Component %(name)s does not exist."
 msgstr ""
 
-#: trac/ticket/model.py:735
+#: trac/ticket/model.py:737
 #, python-format
 msgid "Version %(name)s does not exist."
 msgstr ""
@@ -1724,7 +1728,7 @@
 msgid "Created"
 msgstr ""
 
-#: trac/ticket/query.py:590 trac/ticket/web_ui.py:548
+#: trac/ticket/query.py:590 trac/ticket/web_ui.py:549
 msgid "Ticket"
 msgstr ""
 
@@ -1914,116 +1918,137 @@
 msgid "Ticket details"
 msgstr ""
 
-#: trac/ticket/web_ui.py:437
+#: trac/ticket/web_ui.py:211
+msgid "created"
+msgstr ""
+
+#: trac/ticket/web_ui.py:212
+msgid "reopened"
+msgstr ""
+
+#: trac/ticket/web_ui.py:213
+msgid "closed"
+msgstr ""
+
+#: trac/ticket/web_ui.py:214
+msgid "updated"
+msgstr ""
+
+#: trac/ticket/web_ui.py:310
 #, python-format
+msgid "Ticket %(ticketref)s (%(summary)s) %(verb)s"
+msgstr ""
+
+#: trac/ticket/web_ui.py:438
+#, python-format
 msgid "Invalid action \"%(name)s\""
 msgstr ""
 
-#: trac/ticket/web_ui.py:548
+#: trac/ticket/web_ui.py:549
 msgid "Back to Query"
 msgstr ""
 
-#: trac/ticket/web_ui.py:628 trac/ticket/web_ui.py:778
+#: trac/ticket/web_ui.py:629 trac/ticket/web_ui.py:779
 msgid "Ticket History"
 msgstr ""
 
-#: trac/ticket/web_ui.py:673
+#: trac/ticket/web_ui.py:674
 msgid "No differences to show"
 msgstr ""
 
-#: trac/ticket/web_ui.py:713 trac/ticket/web_ui.py:768
-#: trac/ticket/web_ui.py:776 trac/wiki/web_ui.py:347 trac/wiki/web_ui.py:353
-#: trac/wiki/web_ui.py:499 trac/wiki/web_ui.py:507
+#: trac/ticket/web_ui.py:714 trac/ticket/web_ui.py:769
+#: trac/ticket/web_ui.py:777 trac/wiki/web_ui.py:355 trac/wiki/web_ui.py:361
+#: trac/wiki/web_ui.py:507 trac/wiki/web_ui.py:515
 #, python-format
 msgid "Version %(num)s"
 msgstr ""
 
-#: trac/ticket/web_ui.py:716
+#: trac/ticket/web_ui.py:717
 msgid "initial"
 msgstr ""
 
-#: trac/ticket/web_ui.py:778 trac/versioncontrol/web_ui/changeset.py:342
-#: trac/wiki/web_ui.py:366
+#: trac/ticket/web_ui.py:779 trac/versioncontrol/web_ui/changeset.py:342
+#: trac/wiki/web_ui.py:374
 msgid "Change"
 msgstr ""
 
-#: trac/ticket/web_ui.py:783
+#: trac/ticket/web_ui.py:784
 msgid "Ticket Diff"
 msgstr ""
 
-#: trac/ticket/web_ui.py:851
+#: trac/ticket/web_ui.py:852
 msgid "No permission to change ticket fields."
 msgstr ""
 
-#: trac/ticket/web_ui.py:859
+#: trac/ticket/web_ui.py:860
 msgid "No permissions to change ticket fields."
 msgstr ""
 
-#: trac/ticket/web_ui.py:868
+#: trac/ticket/web_ui.py:869
 msgid "No permissions to add a comment."
 msgstr ""
 
-#: trac/ticket/web_ui.py:874
+#: trac/ticket/web_ui.py:875
 msgid ""
 "Sorry, can not save your changes. This ticket has been modified by "
 "someone else since you started"
 msgstr ""
 
-#: trac/ticket/web_ui.py:881
+#: trac/ticket/web_ui.py:882
 msgid "Tickets must contain a summary."
 msgstr ""
 
-#: trac/ticket/web_ui.py:904
+#: trac/ticket/web_ui.py:905
 #, python-format
 msgid "Ticket description is too long (must be less than %(num)s characters)"
 msgstr ""
 
-#: trac/ticket/web_ui.py:919
+#: trac/ticket/web_ui.py:920
 msgid "Invalid comment threading identifier"
 msgstr ""
 
-#: trac/ticket/web_ui.py:926
+#: trac/ticket/web_ui.py:927
 #, python-format
 msgid "The ticket field '%(field)s' is invalid: %(message)s"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1036
+#: trac/ticket/web_ui.py:1037
 msgid "Assign to"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1052
+#: trac/ticket/web_ui.py:1053
 msgid "Open"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1053
+#: trac/ticket/web_ui.py:1054
 msgid "Closed"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1068
+#: trac/ticket/web_ui.py:1069
 msgid "Add to Cc"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1069
+#: trac/ticket/web_ui.py:1070
 msgid "Remove from Cc"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1070
+#: trac/ticket/web_ui.py:1071
 msgid "Add/Remove from Cc"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1071
+#: trac/ticket/web_ui.py:1072
 msgid "<Author field>"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1090 trac/ticket/templates/query.html:93
+#: trac/ticket/web_ui.py:1091 trac/ticket/templates/query.html:93
 msgid "yes"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1090 trac/ticket/templates/query.html:96
+#: trac/ticket/web_ui.py:1091 trac/ticket/templates/query.html:96
 msgid "no"
 msgstr ""
 
-#: trac/ticket/web_ui.py:1260 trac/versioncontrol/templates/changeset.html:130
+#: trac/ticket/web_ui.py:1261 trac/versioncontrol/templates/changeset.html:130
 msgid "modified"
 msgstr ""
 
@@ -2627,7 +2652,8 @@
 msgstr ""
 
 #: trac/versioncontrol/templates/browser.html:84
-#: trac/versioncontrol/web_ui/browser.py:373 trac/wiki/web_ui.py:533
+#: trac/versioncontrol/web_ui/browser.py:373 trac/wiki/web_ui.py:520
+#: trac/wiki/web_ui.py:544
 msgid "Last Change"
 msgstr ""
 
@@ -3050,69 +3076,73 @@
 msgid "Page not modified"
 msgstr ""
 
-#: trac/wiki/web_ui.py:82 trac/wiki/web_ui.py:585
+#: trac/wiki/web_ui.py:85 trac/wiki/web_ui.py:596
 msgid "Wiki"
 msgstr ""
 
-#: trac/wiki/web_ui.py:84
+#: trac/wiki/web_ui.py:87
 msgid "Help/Guide"
 msgstr ""
 
-#: trac/wiki/web_ui.py:119
+#: trac/wiki/web_ui.py:122
 #, python-format
 msgid "No version \"%(num)s\" for Wiki page \"%(name)s\""
 msgstr ""
 
-#: trac/wiki/web_ui.py:248
+#: trac/wiki/web_ui.py:181
 #, python-format
 msgid "The Wiki page field '%(field)s' is invalid: %(message)s"
 msgstr ""
 
-#: trac/wiki/web_ui.py:252
+#: trac/wiki/web_ui.py:185
 #, python-format
 msgid "Invalid Wiki page: %(message)s"
 msgstr ""
 
-#: trac/wiki/web_ui.py:295
+#: trac/wiki/web_ui.py:271
+msgid "Page not modified, showing latest version."
+msgstr ""
+
+#: trac/wiki/web_ui.py:303
 #, python-format
 msgid "Version %(num)s of page \"%(name)s\" does not exist"
 msgstr ""
 
-#: trac/wiki/web_ui.py:349
+#: trac/wiki/web_ui.py:357
 msgid "Page history"
 msgstr ""
 
-#: trac/wiki/web_ui.py:366
+#: trac/wiki/web_ui.py:374
 msgid "Wiki History"
 msgstr ""
 
-#: trac/wiki/web_ui.py:431
+#: trac/wiki/web_ui.py:439
 #, python-format
 msgid "Page %(name)s does not exist"
 msgstr ""
 
-#: trac/wiki/web_ui.py:468
+#: trac/wiki/web_ui.py:476
 #, python-format
 msgid "Page %(name)s not found"
 msgstr ""
 
-#: trac/wiki/web_ui.py:502 trac/wiki/web_ui.py:511
+#: trac/wiki/web_ui.py:510 trac/wiki/web_ui.py:519
 msgid "View Latest Version"
 msgstr ""
 
-#: trac/wiki/web_ui.py:528
+#: trac/wiki/web_ui.py:539
 msgid "Start Page"
 msgstr ""
 
-#: trac/wiki/web_ui.py:529
+#: trac/wiki/web_ui.py:540
 msgid "Index"
 msgstr ""
 
-#: trac/wiki/web_ui.py:531
+#: trac/wiki/web_ui.py:542
 msgid "History"
 msgstr ""
 
-#: trac/wiki/web_ui.py:541
+#: trac/wiki/web_ui.py:552
 msgid "Wiki changes"
 msgstr ""
 
Index: trac/util/translation.py
===================================================================
--- trac/util/translation.py	(revision 7040)
+++ trac/util/translation.py	(working copy)
@@ -19,9 +19,14 @@
 except ImportError:
     import dummy_threading as threading
 
-__all__ = ['gettext', 'ngettext', 'gettext_noop', 'ngettext_noop']
+from genshi.builder import Element
+from genshi.core import Markup
 
 
+__all__ = ['gettext', 'ngettext', 'gettext_noop', 'ngettext_noop', 
+           'mgettext', 'mgettext_noop', 'mngettext', 'mngettext_noop']
+
+
 def gettext_noop(string, **kwargs):
     retval = string
     if kwargs:
@@ -38,7 +43,30 @@
         retval %= kwargs
     return retval
 
+def _markup_kwargs(string, kwargs):
+    for k, v in kwargs.items():
+        if isinstance(v, Element):
+            kwargs[k] = Markup(unicode(v))
+    return Markup(string) % kwargs
+    
 
+def mgettext_noop(string, **kwargs):
+    retval = string
+    if kwargs:
+        retval = _markup_kwargs(retval, kwargs)
+    return retval
+M_ = mgettext_noop
+
+def mngettext_noop(singular, plural, num, **kwargs):
+    if num == 1:
+        retval = singular
+    else:
+        retval = plural
+    if kwargs:
+        retval = _markup_kwargs(retval, kwargs)
+    return retval
+
+
 try:
     from babel.support import LazyProxy, Translations
     from gettext import NullTranslations
@@ -66,6 +94,27 @@
             return LazyProxy(_ngettext)
         return _ngettext()
 
+    def mgettext(string, **kwargs):
+        def _mgettext():
+            trans = get_translations().ugettext(string)
+            if kwargs:
+                trans = _markup_kwargs(trans, kwargs)
+            return trans
+        if not hasattr(_current, 'translations'):
+            return LazyProxy(_mgettext)
+        return _mgettext()
+    M_ = mgettext
+
+    def mngettext(singular, plural, num, **kwargs):
+        def _mngettext():
+            trans = get_translations().ungettext(singular, plural, num)
+            if kwargs:
+                trans = _markup_kwargs(trans, kwargs)
+            return trans
+        if not hasattr(_current, 'translations'):
+            return LazyProxy(_mngettext)
+        return _mngettext()
+
     def activate(locale):
         locale_dir = pkg_resources.resource_filename(__name__, '../locale')
         _current.translations = Translations.load(locale_dir, locale)
@@ -89,6 +138,8 @@
 except ImportError: # fall back on 0.11 behavior
     gettext = _ = gettext_noop
     ngettext = ngettext_noop
+    mgettext = M_ = mgettext_noop
+    mngettext = mngettext_noop
 
     def activate(locale):
         pass
Index: setup.cfg
===================================================================
--- setup.cfg	(revision 7039)
+++ setup.cfg	(working copy)
@@ -10,6 +10,7 @@
 copyright_holder = Edgewall Software
 msgid_bugs_address = [email protected]
 output_file = trac/locale/messages.pot
+keywords = M_ mgettext mngettext
 
 [init_catalog]
 input_file = trac/locale/messages.pot

Reply via email to