You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by sa...@apache.org on 2014/02/15 22:25:26 UTC

svn commit: r1568681 [1/2] - in /bloodhound/trunk: bloodhound_dashboard/ bloodhound_dashboard/bhdashboard/ bloodhound_dashboard/bhdashboard/default-pages/ bloodhound_dashboard/bhdashboard/layouts/templates/ bloodhound_dashboard/bhdashboard/templates/ b...

Author: saintgermain
Date: Sat Feb 15 21:25:24 2014
New Revision: 1568681

URL: http://svn.apache.org/r1568681
Log:
Add internationalization to BH. Refs #694.

- Add translation scaffolding
- Generate extracted messages
- Add complete french translation
- Add partial spanish translation

Modified:
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/admin.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/default-pages/BloodhoundWidgets
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/macros.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bh_model_view.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/widget_macros.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/containers.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/report.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_grid.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_progress.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py
    bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py
    bloodhound/trunk/bloodhound_dashboard/setup.cfg
    bloodhound/trunk/bloodhound_dashboard/setup.py
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/product_admin.py
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/admin_products.html
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_delete.html
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_edit.html
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_list.html
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_view.html
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/repository_links.html
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/web_ui.py
    bloodhound/trunk/bloodhound_multiproduct/multiproduct/web_ui.py
    bloodhound/trunk/bloodhound_multiproduct/setup.cfg
    bloodhound/trunk/bloodhound_multiproduct/setup.py
    bloodhound/trunk/bloodhound_relations/bhrelations/api.py
    bloodhound/trunk/bloodhound_relations/bhrelations/templates/relations_manage.html
    bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py
    bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py
    bloodhound/trunk/bloodhound_relations/setup.cfg
    bloodhound/trunk/bloodhound_relations/setup.py
    bloodhound/trunk/bloodhound_search/bhsearch/api.py
    bloodhound/trunk/bloodhound_search/bhsearch/search_resources/base.py
    bloodhound/trunk/bloodhound_search/bhsearch/search_resources/changeset_search.py
    bloodhound/trunk/bloodhound_search/bhsearch/search_resources/milestone_search.py
    bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py
    bloodhound/trunk/bloodhound_search/bhsearch/search_resources/wiki_search.py
    bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html
    bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html
    bloodhound/trunk/bloodhound_search/bhsearch/web_ui.py
    bloodhound/trunk/bloodhound_search/bhsearch/whoosh_backend.py
    bloodhound/trunk/bloodhound_search/setup.cfg
    bloodhound/trunk/bloodhound_search/setup.py
    bloodhound/trunk/bloodhound_theme/bhtheme/htdocs/js/theme.js
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_about.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_basics.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_components.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_enums.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_logging.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_milestones.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_perms.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_plugins.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_products.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_versions.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_attach_file_form.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_attachment.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_batch_modify.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_browser.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_diff_options.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_diff_view.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_dirlist_thead.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_history_view.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_list_of_attachments.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_login.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_milestone_delete.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_milestone_edit.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_milestone_view.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_path_general.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_path_search.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_path_ticket.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_path_wikipage.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_advanced.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_datetime.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_general.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_keybindings.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_language.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_pygments.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_userinterface.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_preview_file.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_product_list.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_product_view.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_query.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_register.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_report_delete.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_report_edit.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_report_list.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_report_view.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_reset_password.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_revisionlog.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_search.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_ticket.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_ticket_actions.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_ticket_box.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_ticket_change.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_ticket_delete.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_ticket_preview.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_timeline.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_verify_email.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_wiki_delete.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_wiki_edit.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_wiki_edit_form.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_wiki_rename.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_wiki_view.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bloodhound_theme.html
    bloodhound/trunk/bloodhound_theme/bhtheme/theme.py
    bloodhound/trunk/bloodhound_theme/setup.cfg
    bloodhound/trunk/bloodhound_theme/setup.py
    bloodhound/trunk/installer/bloodhound_setup.py

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/admin.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/admin.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/admin.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/admin.py Sat Feb 15 21:25:24 2014
@@ -31,10 +31,10 @@ from trac.admin.api import IAdminCommand
 from trac.core import Component, implements
 from trac.db_default import schema as tracschema
 from trac.util.text import printout
-from trac.util.translation import _
 from trac.wiki.admin import WikiAdmin
 from trac.wiki.model import WikiPage
 from bhdashboard import wiki
+from bhdashboard.util.translation import _
 
 try:
     from multiproduct.model import Product, ProductResourceMap, ProductSetting

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py Sat Feb 15 21:25:24 2014
@@ -37,8 +37,8 @@ from trac.perm import IPermissionRequest
 from trac.resource import get_resource_url, Resource, resource_exists
 from trac.util.compat import set
 from trac.util.datefmt import parse_date
-from trac.util.translation import _
 from trac.web.chrome import add_stylesheet
+from bhdashboard.util.translation import _
 
 #--------------------------------------
 # Core classes and interfaces
@@ -319,7 +319,7 @@ class InvalidWidgetArgument(WidgetExcept
     title = 'Invalid Argument'
 
     def __init__(self, argname, message, title=None, show_traceback=False):
-        message = _("Invalid argument `") + argname + "`. " + message
+        message = _("Invalid argument") + " `" + argname + "`. " + message
         TracError.__init__(self, message, title, show_traceback)
         self.argname = argname
 

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/default-pages/BloodhoundWidgets
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/default-pages/BloodhoundWidgets?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/default-pages/BloodhoundWidgets (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/default-pages/BloodhoundWidgets Sat Feb 15 21:25:24 2014
@@ -184,7 +184,7 @@ To test the following code, it should be
 from datetime import datetime
 # Note: since Trac 0.11, datetime objects are used internally
 
-from bhdashboard.util import WidgetBase
+from bhdashboard.util.widgets import WidgetBase
 
 class TimeStampWidget(WidgetBase):
     """Inserts the current time (in seconds)"""
@@ -241,7 +241,7 @@ To test the following code, you should s
 
 from genshi.builder import tag
 
-from bhdashboard.util import WidgetBase
+from bhdashboard.util.widgets import WidgetBase
 
 class HelloWorldWidget(WikiWidgetBase):
     """Simple HelloWorld widget.

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html Sat Feb 15 21:25:24 2014
@@ -22,7 +22,9 @@
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
-      xmlns:xi="http://www.w3.org/2001/XInclude">
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhdashboard">
   <xi:include href="layout.html" />
   <head>
     <title>$title</title>
@@ -31,7 +33,7 @@
   <body>
     <xi:include href="bs_btnbar.html" />
     <div id="ft" class="row">
-      <div id="help" class="span8">
+      <div id="help" class="span8" i18n:msg="">
         <span class="label label-info">Note:</span> See
         <a href="${href.wiki('BloodhoundDashboard')}">BloodhoundDashboard</a>
         for help on using the dashboard.

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html Sat Feb 15 21:25:24 2014
@@ -23,6 +23,8 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:xi="http://www.w3.org/2001/XInclude"
+      xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhdashboard"
       py:with="is_global = req.perm.env.product is None">
   <xi:include href="layout.html" />
   <head>
@@ -30,10 +32,10 @@
   </head>
 
   <body>
-    <h2 py:if="not is_global">Dashboard for product <i>${req.perm.env.product.name}</i></h2>
+    <h2 py:if="not is_global" i18n:msg="name">Dashboard for product <i>${req.perm.env.product.name}</i></h2>
     <xi:include href="bs_grid.html" />
     <div id="ft" class="row">
-      <div id="help" class="span8">
+      <div id="help" class="span8" i18n:msg="">
         <span class="label label-info">Note:</span> See
         <a href="${href.wiki('BloodhoundDashboard')}">BloodhoundDashboard</a>
         for help on using the dashboard.

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/macros.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/macros.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/macros.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/macros.py Sat Feb 15 21:25:24 2014
@@ -21,11 +21,12 @@
 r"""Bloodhound Macros"""
 
 from genshi.builder import tag
-from trac.util.translation import _, cleandoc_
+from trac.util.translation import cleandoc_
 from trac.wiki.api import WikiSystem
 from trac.wiki.macros import WikiMacroBase
 
 from bhdashboard.wiki import GUIDE_NAME
+from bhdashboard.util.translation import _
 
 class UserGuideTocMacro(WikiMacroBase):
     _description = cleandoc_("""Display a Guide table of contents

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bh_model_view.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bh_model_view.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bh_model_view.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bh_model_view.html Sat Feb 15 21:25:24 2014
@@ -23,6 +23,7 @@
 <div xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhdashboard"
       xmlns:bh="http://issues.apache.org/bloodhound/wiki/Ui/Dashboard"
       xmlns:xi="http://www.w3.org/2001/XInclude"
       py:strip=""
@@ -56,7 +57,7 @@
         </py:choose>
       </div>
       <div class="$cols_activity hidden-phone">
-        <h2>${_('Activity')}</h2>
+        <h2>${dgettext('bhdashboard', 'Activity')}</h2>
       </div>
     </div>
   </div>

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/widget_macros.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/widget_macros.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/widget_macros.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/widget_macros.html Sat Feb 15 21:25:24 2014
@@ -20,6 +20,8 @@
 <html 
     xmlns="http://www.w3.org/1999/xhtml"
     xmlns:py="http://genshi.edgewall.org/"
+    xmlns:i18n="http://genshi.edgewall.org/i18n"
+    i18n:domain="bhdashboard"
     xmlns:xi="http://www.w3.org/2001/XInclude"
     xmlns:bh="http://issues.apache.org/bloodhound/wiki/Ui/Dashboard"
     py:strip="" >
@@ -54,7 +56,7 @@
 
   <!--! Widget markup (py:match) -->
 
-  <div py:def="bhnotfound()" class="alert alert-error">
+  <div py:def="bhnotfound()" class="alert alert-error" i18n:msg="Error">
     <span class="label label-important">Error</span>
     Dashboard data is missing . 
     Is <code>bhdashboard.web_ui.DashboardModule</code> component disabled?

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py Sat Feb 15 21:25:24 2014
@@ -36,17 +36,16 @@ from genshi.core import Stream
 from trac.core import Component, implements
 from trac.config import Option, IntOption
 from trac.mimeview.api import Context
-from trac.util.translation import _
 from trac.ticket.query import QueryModule
 from trac.ticket.report import ReportModule
 from trac.util.compat import groupby
-from trac.util.translation import _
 from trac.web.api import IRequestHandler, IRequestFilter
 from trac.web.chrome import add_ctxtnav, add_stylesheet, Chrome, \
                             INavigationContributor, ITemplateProvider
 
 from bhdashboard.api import DashboardSystem, InvalidIdentifier
 from bhdashboard import _json
+from bhdashboard.util.translation import _, add_domain
 from multiproduct.env import ProductEnvironment
 
 
@@ -57,9 +56,16 @@ class DashboardModule(Component):
                ITemplateProvider)
 
     mainnav_label = Option('mainnav', 'tickets.label', 'Tickets',
-                           """Dashboard label in mainnav""")
+                           """Dashboard label in mainnav""",
+                           doc_domain='bhdashboard')
     default_widget_height = IntOption('widgets', 'default_height', 320,
-                                      """Default widget height in pixels""")
+                                      """Default widget height in pixels""", 
+                                      doc_domain='bhdashboard')
+
+    def __init__(self, *args, **kwargs):
+        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
+        add_domain(self.env.path, locale_dir)
+        super(DashboardModule, self).__init__(*args, **kwargs)
 
     # IRequestFilter methods
 
@@ -146,7 +152,7 @@ class DashboardModule(Component):
                 resource_filename('bhdashboard.widgets', 'templates')]
 
     # Temp vars
-    DASHBOARD_SCHEMA = {
+    DASHBOARD_GLOBAL_SCHEMA = DASHBOARD_SCHEMA = {
             'div': [
                     {
                         '_class': 'row',
@@ -202,7 +208,7 @@ class DashboardModule(Component):
                                         '&col=id&col=summary&col=owner'
                                         '&col=status&col=priority&'
                                         'order=priority',
-                                    'title': 'Active Tickets'}}],
+                                    'title': _('Active Tickets')}}],
                             'altlinks': False
                         },
                     'my tickets': {
@@ -216,7 +222,7 @@ class DashboardModule(Component):
                                           '&col=status&col=priority&'
                                           'order=priority&'
                                           'owner=$USER',
-                                    'title': 'My Tickets'}
+                                    'title': _('My Tickets')}
                                 }],
                             'altlinks': False
                         },
@@ -231,7 +237,6 @@ class DashboardModule(Component):
         }
 
     # global dashboard queries: add milestone column, group by product
-    DASHBOARD_GLOBAL_SCHEMA = copy.deepcopy(DASHBOARD_SCHEMA)
     DASHBOARD_GLOBAL_SCHEMA['widgets']['active tickets']['args'][2]['args']['query'] = (
         'status=!closed&group=product&col=id&col=summary&col=owner&col=status&'
         'col=priority&order=priority&col=milestone'
@@ -261,7 +266,7 @@ class DashboardModule(Component):
         """Render widget without failing.
         """
         if wp is None:
-            data = {'msglabel': 'Warning',
+            data = {'msglabel': _('Warning'),
                     'msgbody': _('Unknown widget %(name)s', name=name)}
             return 'widget_alert.html', {'title': '', 'data': data}, ctx
 

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/containers.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/containers.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/containers.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/containers.py Sat Feb 15 21:25:24 2014
@@ -28,9 +28,9 @@ from genshi.builder import tag
 from trac.core import implements, TracError
 
 from bhdashboard.api import DashboardSystem, InvalidWidgetArgument, JsonField
-from bhdashboard.util import WidgetBase, check_widget_name, \
-                              dummy_request, merge_links, minmax, \
+from bhdashboard.util import dummy_request, merge_links, minmax, \
                               pretty_wrapper, trac_version, trac_tags
+from bhdashboard.util.widgets import WidgetBase, check_widget_name
 from bhdashboard.web_ui import DashboardModule
 
 class ContainerWidget(WidgetBase):

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py Sat Feb 15 21:25:24 2014
@@ -29,11 +29,12 @@ import itertools
 from genshi.builder import tag
 
 from trac.resource import Neighborhood
-from trac.util.translation import _
 from trac.ticket.model import Milestone, Component, Version
 from trac.ticket.query import Query
 
-from bhdashboard.util import WidgetBase, check_widget_name, pretty_wrapper
+from bhdashboard.util import pretty_wrapper
+from bhdashboard.util.widgets import WidgetBase, check_widget_name
+from bhdashboard.util.translation import _
 
 from multiproduct.env import Product, ProductEnvironment
 

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py Sat Feb 15 21:25:24 2014
@@ -33,13 +33,14 @@ from trac.core import implements, TracEr
 from trac.mimeview.api import Context
 from trac.resource import Resource, ResourceNotFound
 from trac.ticket.query import Query, QueryModule
-from trac.util.translation import _
 from trac.web.api import RequestDone
 
-from bhdashboard.util import WidgetBase, InvalidIdentifier, \
-                              check_widget_name, dummy_request, \
-                              merge_links, pretty_wrapper, trac_version, \
+from bhdashboard.util import dummy_request, merge_links, \
+                              pretty_wrapper, trac_version, \
                               trac_tags
+from bhdashboard.util.widgets import WidgetBase, InvalidIdentifier, \
+                                      check_widget_name
+from bhdashboard.util.translation import _
 
 from multiproduct.env import ProductEnvironment
 

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/report.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/report.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/report.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/report.py Sat Feb 15 21:25:24 2014
@@ -32,13 +32,14 @@ from trac.core import implements, TracEr
 from trac.mimeview.api import Context
 from trac.resource import ResourceNotFound
 from trac.ticket.report import ReportModule
-from trac.util.translation import _
 from trac.web.api import RequestDone
 
-from bhdashboard.util import WidgetBase, InvalidIdentifier, \
-                              check_widget_name, dummy_request, \
-                              merge_links, pretty_wrapper, trac_version, \
+from bhdashboard.util import dummy_request, merge_links, \
+                              pretty_wrapper, trac_version, \
                               trac_tags
+from bhdashboard.util.widgets import WidgetBase, InvalidIdentifier, \
+                               check_widget_name
+from bhdashboard.util.translation import _
 
 class TicketReportWidget(WidgetBase):
     """Display tickets in saved report using a grid

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html Sat Feb 15 21:25:24 2014
@@ -21,6 +21,8 @@
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:py="http://genshi.edgewall.org/"
   xmlns:xi="http://www.w3.org/2001/XInclude"
+  xmlns:i18n="http://genshi.edgewall.org/i18n"
+  i18n:domain="bhdashboard"
   py:with="_view = view if view in ('list', 'cloud', 'compact', 'table') else 'list'">
 
   <py:def function="display_value(value)">

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_grid.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_grid.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_grid.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_grid.html Sat Feb 15 21:25:24 2014
@@ -20,19 +20,21 @@
 <div class="report"
       xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
-      xmlns:xi="http://www.w3.org/2001/XInclude">
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhdashboard">
   <!--! TODO: Add description icon plus tooltip -->
   <!--! div py:if="description" id="description" xml:space="preserve">
     ${wiki_to_html(context, description)}
   </div -->
   <py:choose test="">
     <div py:when="paginator.has_more_pages">
-      <div class="report-result" style="float: left; margin-right: 1.6em;">
+      <div class="report-result" style="float: left; margin-right: 1.6em;" i18n:msg="displayed_items">
         Results <span class="numresults">(${paginator.displayed_items()})</span>
       </div>
       <xi:include href="page_index.html" />
     </div>
-    <div py:when="numrows" class="numrows">($numrows total rows)</div>
+    <div py:when="numrows" class="numrows" i18n:msg="numrows">($numrows total rows)</div>
   </py:choose>
 
   <py:choose test="">

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html Sat Feb 15 21:25:24 2014
@@ -20,17 +20,20 @@
 <div id="content" class="product"
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:py="http://genshi.edgewall.org/"
-  xmlns:xi="http://www.w3.org/2001/XInclude">
+  xmlns:xi="http://www.w3.org/2001/XInclude"
+  xmlns:i18n="http://genshi.edgewall.org/i18n"
+  i18n:domain="bhdashboard">
   <div py:if="product_list" class="row" id="products">
     <py:for each="i, p in zip(colseq, product_list)">
       <div class="span4">
         <div class="well product-well">
-          <h4>
+          <h4 i18n:msg="name,prefix,owner">
             &#9734; <a href="${p.href}">$p.name ($p.prefix)</a>
             <py:if test="p.owner_link">
               <br />
               <small>owned by
-                <a href="$p.owner_link">${authorinfo(p._data['owner']) if p._data['owner'] else _('(nobody)')}</a>
+                <a href="$p.owner_link" py:if="p._data['owner']">${authorinfo(p._data['owner'])}</a>
+                <a href="$p.owner_link" py:if="not p._data['owner']">(nobody)</a>
               </small>
             </py:if>
           </h4>

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_progress.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_progress.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_progress.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_progress.html Sat Feb 15 21:25:24 2014
@@ -21,6 +21,7 @@
     xmlns="http://www.w3.org/1999/xhtml"
     xmlns:py="http://genshi.edgewall.org/"
     xmlns:i18n="http://genshi.edgewall.org/i18n"
+    i18n:domain="bhdashboard"
     xmlns:xi="http://www.w3.org/2001/XInclude"
     py:with="view = view or 'standard'">
 
@@ -92,8 +93,7 @@
             ${interval.title}
           </p>
           <p style="font-size: 150%">
-            <a href="${interval_hrefs[idx] if interval_hrefs else '#'}"
-                i18n:msg="count" >
+            <a href="${interval_hrefs[idx] if interval_hrefs else '#'}">
               ${interval.count}
             </a> &nbsp;
           </p>

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html Sat Feb 15 21:25:24 2014
@@ -20,7 +20,9 @@
 <div
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:py="http://genshi.edgewall.org/"
-  xmlns:xi="http://www.w3.org/2001/XInclude">
+  xmlns:xi="http://www.w3.org/2001/XInclude"
+  xmlns:i18n="http://genshi.edgewall.org/i18n"
+  i18n:domain="bhdashboard">
 
   <py:choose test="">
     <py:when test="relations">

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html Sat Feb 15 21:25:24 2014
@@ -21,6 +21,8 @@
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:py="http://genshi.edgewall.org/"
   xmlns:xi="http://www.w3.org/2001/XInclude"
+  xmlns:i18n="http://genshi.edgewall.org/i18n"
+  i18n:domain="bhdashboard"
   py:with="now = datetime.now(req.tz);
            today = format_date(now);
            yesterday = format_date(now - timedelta(days=1))"
@@ -32,7 +34,7 @@
     <thead>
       <tr>
         <th>
-          ${day}: ${day == today and 'Today' or day == yesterday and 'Yesterday' or None}
+          ${day}: ${day == today and _('Today') or day == yesterday and _('Yesterday') or None}
         </th>
       </tr>
     </thead>
@@ -40,7 +42,7 @@
       <tr py:for="event in events"
         py:with="highlight = precision and precisedate and timedelta(0) &lt;= (event.date - precisedate) &lt; precision">
         <td class="${classes(event.kind, highlight=highlight)}">
-          <dt>
+          <dt i18n:msg="time,event,author">
             <span class="time">${format_time(event.date, str('%H:%M'))}</span>: <a href="${event.render('url', context)}">${event.render('title', context)}</a>
               <py:if test="event.author">by <span class="author">${format_author(event.author)}</span></py:if>
           </dt>

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py Sat Feb 15 21:25:24 2014
@@ -35,16 +35,16 @@ from trac.ticket.query import Query
 from trac.ticket.roadmap import apply_ticket_permissions, get_ticket_stats, \
                             ITicketGroupStatsProvider, RoadmapModule
 from trac.util.text import unicode_urlencode
-from trac.util.translation import _
 from trac.web.chrome import add_stylesheet
 
 from bhdashboard.api import DateField, EnumField, InvalidWidgetArgument, \
                             ListField
 from bhdashboard.widgets.query import exec_query
-from bhdashboard.util import WidgetBase, check_widget_name, \
-                            dummy_request, merge_links, minmax, \
+from bhdashboard.util import dummy_request, merge_links, minmax, \
                             pretty_wrapper, resolve_ep_class, \
                             trac_version, trac_tags
+from bhdashboard.util.widgets import WidgetBase, check_widget_name
+from bhdashboard.util.translation import _
 
 from multiproduct.env import Product, ProductEnvironment
 
@@ -106,28 +106,28 @@ class TicketFieldValuesWidget(WidgetBase
                 self.bind_params(name, options, *params)
 
         field_maps = {'type': {'admin_url': 'type',
-                               'title': 'Types',
+                               'title': _('Types'),
                                },
                       'status': {'admin_url': None,
-                                 'title': 'Statuses',
+                                 'title': _('Statuses'),
                                  },
                       'priority': {'admin_url': 'priority',
-                                   'title': 'Priorities',
+                                   'title': _('Priorities'),
                                    },
                       'milestone': {'admin_url': 'milestones',
-                                    'title': 'Milestones',
+                                    'title': _('Milestones'),
                                     },
                       'component': {'admin_url': 'components',
-                                    'title': 'Components',
+                                    'title': _('Components'),
                                     },
                       'version': {'admin_url': 'versions',
-                                  'title': 'Versions',
+                                  'title': _('Versions'),
                                   },
                       'severity': {'admin_url': 'severity',
-                                   'title': 'Severities',
+                                   'title': _('Severities'),
                                    },
                       'resolution': {'admin_url': 'resolution',
-                                     'title': 'Resolutions',
+                                     'title': _('Resolutions'),
                                      },
                       }
         _field = []
@@ -152,8 +152,7 @@ class TicketFieldValuesWidget(WidgetBase
                         hint = _('Contact your administrator for further details')
                     return 'widget_alert.html', \
                             {
-                                'title' : Markup(_('%(field)s',
-                                            field=field_maps[fieldnm]['title'])),
+                                'title' : Markup(field_maps[fieldnm]['title']),
                                 'data' : dict(msgtype='info',
                                     msglabel="Note",
                                     msgbody=Markup(_('''No values are

Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py Sat Feb 15 21:25:24 2014
@@ -39,14 +39,14 @@ from trac.ticket.api import TicketSystem
 from trac.ticket.model import Ticket
 from trac.ticket.web_ui import TicketModule
 from trac.util.datefmt import utc
-from trac.util.translation import _, tag_
 from trac.web.chrome import add_stylesheet
 
 from bhdashboard.api import DateField, EnumField, ListField
-from bhdashboard.util import WidgetBase, InvalidIdentifier, \
-                              check_widget_name, dummy_request, \
-                              merge_links, pretty_wrapper, trac_version, \
-                              trac_tags
+from bhdashboard.util import dummy_request, merge_links, pretty_wrapper, \
+                             trac_version, trac_tags
+from bhdashboard.util.widgets import WidgetBase, InvalidIdentifier, \
+                              check_widget_name
+from bhdashboard.util.translation import _, tag_
 
 __metaclass__ = type
 
@@ -77,7 +77,8 @@ class TimelineWidget(WidgetBase):
     """Display activity feed.
     """
     default_count = IntOption('widget_activity', 'limit', 25,
-        """Maximum number of items displayed by default""")
+        """Maximum number of items displayed by default""",
+                              doc_domain='bhdashboard')
 
     event_filters = ExtensionPoint(ITimelineEventsFilter)
 
@@ -149,7 +150,7 @@ class TimelineWidget(WidgetBase):
                 return 'widget_alert.html', {
                     'title':  _("Activity"),
                     'data': {
-                        'msglabel': "Warning",
+                        'msglabel': _("Warning"),
                         'msgbody':
                             tag_("The TimelineWidget is disabled because the "
                                  "Timeline component is not available. "
@@ -210,7 +211,7 @@ class TimelineWidget(WidgetBase):
             data = module.process_request(fakereq)[1]
         except TracError, exc:
             if data is not None:
-                exc.title = data.get('title', 'Activity')
+                exc.title = data.get('title', _('Activity'))
             raise
         else:
             merge_links(srcreq=fakereq, dstreq=req,

Modified: bloodhound/trunk/bloodhound_dashboard/setup.cfg
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/setup.cfg?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/setup.cfg (original)
+++ bloodhound/trunk/bloodhound_dashboard/setup.cfg Sat Feb 15 21:25:24 2014
@@ -22,3 +22,24 @@ tag_svn_revision = true
 
 [sdist]
 formats = gztar,bztar,ztar,tar,zip
+
+[extract_messages]
+add_comments = TRANSLATOR:
+msgid_bugs_address =
+output_file = bhdashboard/locale/messages.pot
+keywords = _ ngettext:1,2 N_ tag_ tagn_:1,2 Option:4 BoolOption:4 IntOption:4 ListOption:6 ExtensionOption:5 PathOption:4
+no-wrap = true
+
+[init_catalog]
+input_file = bhdashboard/locale/messages.pot
+output_dir = bhdashboard/locale
+domain = bhdashboard
+
+[compile_catalog]
+directory = bhdashboard/locale
+domain = bhdashboard
+
+[update_catalog]
+input_file = bhdashboard/locale/messages.pot
+output_dir = bhdashboard/locale
+domain = bhdashboard

Modified: bloodhound/trunk/bloodhound_dashboard/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/setup.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/setup.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/setup.py Sat Feb 15 21:25:24 2014
@@ -94,7 +94,8 @@ PKG_INFO = {'bhdashboard' : ('bhdashboar
                               '../NOTICE', '../README', '../TESTING_README',
                               'htdocs/*.*', 'htdocs/css/*.css',
                               'htdocs/img/*.*', 'htdocs/js/*.js',
-                              'templates/*', 'default-pages/*'],
+                              'templates/*', 'default-pages/*',
+                              'locale/*/LC_MESSAGES/*.mo'],
                           ),
             'bhdashboard.widgets' : ('bhdashboard/widgets',     # Package dir
                             # Package data
@@ -107,6 +108,10 @@ PKG_INFO = {'bhdashboard' : ('bhdashboar
             'bhdashboard.tests' : ('bhdashboard/tests',     # Package dir
                             # Package data
                             ['data/**'],
+                         ),
+            'bhdashboard.util' : ('bhdashboard/util',     # Package dir
+                            # Package data
+                            [],
                           ),
             }
 
@@ -124,6 +129,24 @@ ENTRY_POINTS = r"""
                bhdashboard.widgets.timeline = bhdashboard.widgets.timeline
                bhdashboard.wiki = bhdashboard.wiki
                """
+extra = {}
+try:
+    from trac.util.dist import get_l10n_js_cmdclass
+    cmdclass = get_l10n_js_cmdclass()
+    if cmdclass:
+        extra['cmdclass'] = cmdclass
+        extractors = [
+            ('**.py',                'trac.dist:extract_python', None),
+            ('**/templates/**.html', 'genshi', None),
+            ('**/templates/**.txt',  'genshi', {
+                'template_class': 'genshi.template:TextTemplate'
+            }),
+        ]
+        extra['message_extractors'] = {
+            'bhdashboard': extractors,
+        }
+except ImportError:
+    pass
 
 setup(
     name=DIST_NM,
@@ -147,5 +170,6 @@ setup(
                   for p in PKG_INFO.keys()],
     entry_points = ENTRY_POINTS,
     classifiers = cats,
-    long_description= DESC
+    long_description= DESC,
+    **extra
     )

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py Sat Feb 15 21:25:24 2014
@@ -36,7 +36,6 @@ from trac.resource import IExternalResou
                           IResourceManager, ResourceNotFound
 from trac.ticket.api import ITicketFieldProvider, ITicketManipulator
 from trac.util.text import to_unicode, unquote_label, unicode_unquote
-from trac.util.translation import _, N_
 from trac.web.chrome import ITemplateProvider, add_warning
 from trac.web.main import FakePerm, FakeSession
 from trac.wiki.admin import WikiAdmin
@@ -47,6 +46,7 @@ from multiproduct.dbcursor import GLOBAL
 from multiproduct.model import Product, ProductResourceMap, ProductSetting
 from multiproduct.util import EmbeddedLinkFormatter, IDENTIFIER, \
                               using_mysql_backend, using_sqlite_backend
+from multiproduct.util.translation import _, N_, add_domain
 
 __all__ = ['MultiProductSystem', 'PRODUCT_SYNTAX_DELIMITER']
 
@@ -83,7 +83,7 @@ class MultiProductSystem(Component):
         'default_product_prefix',
         default='@',
         doc="""Prefix used for default product when migrating single-product
-        installations to multi-product.""")
+        installations to multi-product.""", doc_domain='multiproduct')
 
     default_product = Option('ticket', 'default_product', '',
         """Default product for newly created tickets.""")
@@ -99,13 +99,14 @@ class MultiProductSystem(Component):
         following will be used `products/$(prefix)s`
 
         Note the usage of `$(...)s` instead of `%(...)s` as the later form
-        would be interpreted by the ConfigParser itself. """)
+        would be interpreted by the ConfigParser itself. """,
+                              doc_domain='multiproduct')
 
     product_config_parent = PathOption('inherit', 'multiproduct', '',
         """The path to the configuration file containing the settings shared
         by sibling product environments. By default will inherit
         global environment configuration.
-        """)
+        """, doc_domain='multiproduct')
 
     SCHEMA = [mcls._get_schema()
               for mcls in (Product, ProductResourceMap)]
@@ -122,6 +123,12 @@ class MultiProductSystem(Component):
 
     PRODUCT_POPULATE_TABLES = list(set(MIGRATE_TABLES) - set(['wiki']))
 
+    def __init__(self, *args, **kwargs):
+        import pkg_resources
+        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
+        add_domain(self.env.path, locale_dir)
+        super(MultiProductSystem, self).__init__(*args, **kwargs)
+
     def get_version(self):
         """Finds the current version of the bloodhound database schema"""
         rows = self.env.db_direct_query("""
@@ -624,7 +631,7 @@ class MultiProductSystem(Component):
     # ITicketFieldProvider methods
     def get_select_fields(self):
         """Product select fields"""
-        return [(35, {'name': 'product', 'label': N_('Product'),
+        return [(35, {'name': 'product', 'label': _('Product'),
                       'cls': Product, 'pk': 'prefix', 'optional': False,
                       'value': self.default_product})]
 
@@ -737,8 +744,8 @@ class MultiProductSystem(Component):
                 # Note: add_warning() is used intead of returning a list of
                 # error tuples, since the latter results in trac rendering
                 # errors (ticket's change.date is not populated)
-                add_warning(req, _('The user "%s" does not exist.' %
-                    ticket['owner']))
+                add_warning(req, _('The user "%s" does not exist.') %
+                    ticket['owner'])
         return []
 
 

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py Sat Feb 15 21:25:24 2014
@@ -423,7 +423,7 @@ class ProductEnvironment(Component, Comp
         This is the base URL that will be used when producing
         documents that will be used outside of the web browsing
         context, like for example when inserting URLs pointing to Trac
-        resources in notification e-mails.""")
+        resources in notification e-mails.""", doc_domain='multiproduct')
 
     @property
     def base_url(self):
@@ -442,7 +442,8 @@ class ProductEnvironment(Component, Comp
         force Trac to use the `base_url` setting also for
         redirects. This introduces the obvious limitation that this
         environment will only be usable when accessible from that URL,
-        as redirects are frequently used. ''(since 0.10.5)''""")
+        as redirects are frequently used. ''(since 0.10.5)''""",
+                                        doc_domain='multiproduct')
 
     @property
     def project_name(self):
@@ -466,7 +467,8 @@ class ProductEnvironment(Component, Comp
         return self.parent.project_url
 
     project_admin = Option('project', 'admin', '',
-        """E-Mail address of the product's leader / administrator.""")
+        """E-Mail address of the product's leader / administrator.""",
+                           doc_domain='multiproduct')
 
     @property
     def project_footer(self):
@@ -476,23 +478,24 @@ class ProductEnvironment(Component, Comp
         return self.parent.project_footer
 
     project_icon = Option('project', 'icon', 'common/trac.ico',
-        """URL of the icon of the product.""")
+        """URL of the icon of the product.""", doc_domain='multiproduct')
 
     log_type = Option('logging', 'log_type', 'inherit',
         """Logging facility to use.
 
         Should be one of (`inherit`, `none`, `file`, `stderr`,
-        `syslog`, `winlog`).""")
+        `syslog`, `winlog`).""", doc_domain='multiproduct')
 
     log_file = Option('logging', 'log_file', 'trac.log',
         """If `log_type` is `file`, this should be a path to the
         log-file.  Relative paths are resolved relative to the `log`
-        directory of the environment.""")
+        directory of the environment.""", doc_domain='multiproduct')
 
     log_level = Option('logging', 'log_level', 'DEBUG',
         """Level of verbosity in log.
 
-        Should be one of (`CRITICAL`, `ERROR`, `WARN`, `INFO`, `DEBUG`).""")
+        Should be one of (`CRITICAL`, `ERROR`, `WARN`, `INFO`, `DEBUG`).""",
+                       doc_domain='multiproduct')
 
     log_format = Option('logging', 'log_format', None,
         """Custom logging format.
@@ -515,7 +518,7 @@ class ProductEnvironment(Component, Comp
         Example:
         `($(thread)d) Trac[$(basename)s:$(module)s] $(levelname)s: $(message)s`
 
-        ''(since 0.10.5)''""")
+        ''(since 0.10.5)''""", doc_domain='multiproduct')
 
     def __init__(self, env, product, create=False):
         """Initialize the product environment.

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/product_admin.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/product_admin.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/product_admin.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/product_admin.py Sat Feb 15 21:25:24 2014
@@ -28,7 +28,6 @@ from trac.resource import ResourceNotFou
 from trac.ticket.admin import TicketAdminPanel, _save_config
 from trac.util import getuser, lazy
 from trac.util.text import print_table, to_unicode, printerr, printout
-from trac.util.translation import _, N_, gettext, ngettext
 from trac.web.api import HTTPNotFound, IRequestFilter, IRequestHandler
 from trac.web.chrome import Chrome, add_notice, add_warning
 
@@ -36,6 +35,7 @@ from multiproduct.env import ProductEnvi
 from multiproduct.model import Product
 from multiproduct.perm import sudo
 from multiproduct.util import ReplacementComponent
+from multiproduct.util.translation import _, N_, gettext, ngettext
 
 import multiproduct.versioncontrol
 import trac.versioncontrol.admin

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/admin_products.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/admin_products.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/admin_products.html (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/admin_products.html Sat Feb 15 21:25:24 2014
@@ -23,7 +23,8 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:py="http://genshi.edgewall.org/"
-      xmlns:i18n="http://genshi.edgewall.org/i18n">
+      xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="multiproduct">
   <xi:include href="admin.html" />
   <head>
     <title>Products</title>

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_delete.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_delete.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_delete.html (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_delete.html Sat Feb 15 21:25:24 2014
@@ -23,6 +23,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="multiproduct"
       xmlns:xi="http://www.w3.org/2001/XInclude">
   <xi:include href="layout.html" />
   <head>

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_edit.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_edit.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_edit.html (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_edit.html Sat Feb 15 21:25:24 2014
@@ -23,6 +23,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="multiproduct"
       xmlns:xi="http://www.w3.org/2001/XInclude">
   <xi:include href="layout.html" />
   <head>

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_list.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_list.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_list.html (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_list.html Sat Feb 15 21:25:24 2014
@@ -23,6 +23,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="multiproduct"
       xmlns:xi="http://www.w3.org/2001/XInclude">
   <xi:include href="layout.html" />
   <head>

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_view.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_view.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_view.html (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/product_view.html Sat Feb 15 21:25:24 2014
@@ -23,6 +23,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="multiproduct"
       xmlns:xi="http://www.w3.org/2001/XInclude">
   <xi:include href="layout.html" />
   <head>

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/repository_links.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/repository_links.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/repository_links.html (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/templates/repository_links.html Sat Feb 15 21:25:24 2014
@@ -23,7 +23,8 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:py="http://genshi.edgewall.org/"
-      xmlns:i18n="http://genshi.edgewall.org/i18n">
+      xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="multiproduct">
   <xi:include href="admin.html" />
   <head>
     <title>Repository Links</title>

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py Sat Feb 15 21:25:24 2014
@@ -18,9 +18,9 @@
 #  under the License.
 
 from trac.ticket.batch import BatchModifyModule
-from trac.util.translation import _
 from trac.web.chrome import add_script_data
 from multiproduct.env import ProductEnvironment
+from multiproduct.util.translation import _
 
 
 class ProductBatchModifyModule(BatchModifyModule):

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py Sat Feb 15 21:25:24 2014
@@ -34,7 +34,6 @@ from trac.ticket.api import TicketSystem
 from trac.ticket.query import Query, QueryModule, TicketQueryMacro, QueryValueError
 from trac.util.datefmt import from_utimestamp, utc, to_timestamp
 from trac.util.text import shorten_line
-from trac.util.translation import _, tag_
 from trac.web import parse_arg_list, arg_list_to_args
 from trac.web.chrome import Chrome, add_stylesheet, add_link, web_context, \
     add_script_data, add_script, add_ctxtnav, add_warning
@@ -43,6 +42,7 @@ from trac.resource import Resource
 from multiproduct.dbcursor import GLOBAL_PRODUCT
 from multiproduct.env import lookup_product_env, resolve_product_href, \
                              ProductEnvironment
+from multiproduct.util.translation import _, tag_
 
 
 class ProductQuery(Query):

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/web_ui.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/web_ui.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/web_ui.py Sat Feb 15 21:25:24 2014
@@ -30,12 +30,12 @@ from trac.ticket.api import TicketSystem
 from trac.resource import Resource, get_resource_shortname, ResourceNotFound
 from trac.search import search_to_sql, shorten_result
 from trac.util.datefmt import from_utimestamp
-from trac.util.translation import _, tag_
 
 from multiproduct.api import MultiProductSystem, PRODUCT_SYNTAX_DELIMITER_RE
 from multiproduct.env import ProductEnvironment
 from multiproduct.model import Product
 from multiproduct.util import IDENTIFIER
+from multiproduct.util.translation import _, tag_
 from multiproduct.web_ui import ProductModule
 
 

Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/web_ui.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/web_ui.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/web_ui.py Sat Feb 15 21:25:24 2014
@@ -21,7 +21,6 @@ import re
 
 from trac.core import Component, TracError, implements
 from trac.resource import Neighborhood, Resource, ResourceNotFound
-from trac.util.translation import _
 from trac.web.api import HTTPNotFound, IRequestHandler, IRequestFilter
 from trac.web.chrome import (
     Chrome, INavigationContributor, add_link, add_notice, add_warning,
@@ -32,7 +31,7 @@ from multiproduct.env import resolve_pro
 from multiproduct.hooks import PRODUCT_RE
 from multiproduct.model import Product
 from multiproduct.env import ProductEnvironment
-
+from multiproduct.util.translation import _
 
 # requests to the following URLs will be skipped in the global scope
 # (no more redirection to default product)

Modified: bloodhound/trunk/bloodhound_multiproduct/setup.cfg
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/setup.cfg?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/setup.cfg (original)
+++ bloodhound/trunk/bloodhound_multiproduct/setup.cfg Sat Feb 15 21:25:24 2014
@@ -23,3 +23,23 @@ tag_svn_revision = true
 [sdist]
 formats = gztar,bztar,ztar,tar,zip
 
+[extract_messages]
+add_comments = TRANSLATOR:
+msgid_bugs_address =
+output_file = multiproduct/locale/messages.pot
+keywords = _ ngettext:1,2 N_ tag_ tagn_:1,2 Option:4 BoolOption:4 IntOption:4 ListOption:6 ExtensionOption:5 PathOption:4
+no-wrap = true
+
+[init_catalog]
+input_file = multiproduct/locale/messages.pot
+output_dir = multiproduct/locale
+domain = multiproduct
+
+[compile_catalog]
+directory = multiproduct/locale
+domain = multiproduct
+
+[update_catalog]
+input_file = multiproduct/locale/messages.pot
+output_dir = multiproduct/locale
+domain = multiproduct

Modified: bloodhound/trunk/bloodhound_multiproduct/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/setup.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/setup.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/setup.py Sat Feb 15 21:25:24 2014
@@ -34,6 +34,25 @@ if __name__ == '__main__':
             del sys.argv[ac]
             break
 
+extra = {}
+try:
+    from trac.util.dist import get_l10n_js_cmdclass
+    cmdclass = get_l10n_js_cmdclass()
+    if cmdclass:
+        extra['cmdclass'] = cmdclass
+        extractors = [
+            ('**.py',                'trac.dist:extract_python', None),
+            ('**/templates/**.html', 'genshi', None),
+            ('**/templates/**.txt',  'genshi', {
+                'template_class': 'genshi.template:TextTemplate'
+            }),
+        ]
+        extra['message_extractors'] = {
+            'multiproduct': extractors,
+        }
+except ImportError:
+    pass
+
 setup(
     name = 'BloodhoundMultiProduct',
     version = '0.8.0',
@@ -41,8 +60,9 @@ setup(
     author = "Apache Bloodhound",
     license = "Apache License v2",
     url = "https://bloodhound.apache.org/",
-    packages = ['multiproduct', 'multiproduct.ticket', 'tests',],
-    package_data = {'multiproduct' : ['templates/*.html',]},
+    packages = ['multiproduct', 'multiproduct.ticket', 'multiproduct.util',
+                'tests',],
+    package_data = {'multiproduct' : ['templates/*.html','locale/*/LC_MESSAGES/*.mo']},
     install_requires = ['sqlparse'],
     entry_points = {'trac.plugins': [
             'multiproduct.model = multiproduct.model',
@@ -54,5 +74,6 @@ setup(
             'multiproduct.web_ui = multiproduct.web_ui',
         ],},
     test_suite='tests.test_suite',
-    tests_require=['unittest2' if parse_version(sys.version) < parse_version('2.7') else '']
+    tests_require=['unittest2' if parse_version(sys.version) < parse_version('2.7') else ''],
+    **extra
 )

Modified: bloodhound/trunk/bloodhound_relations/bhrelations/api.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/bhrelations/api.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/bhrelations/api.py (original)
+++ bloodhound/trunk/bloodhound_relations/bhrelations/api.py Sat Feb 15 21:25:24 2014
@@ -25,6 +25,7 @@ from pkg_resources import resource_filen
 from bhrelations import db_default
 from bhrelations.model import Relation
 from bhrelations.utils import unique
+from bhrelations.utils.translation import _, add_domain
 from multiproduct.api import ISupportMultiProductEnvironment
 from multiproduct.model import Product
 from multiproduct.env import ProductEnvironment
@@ -200,16 +201,21 @@ class RelationsSystem(Component):
         'NoSelfReferenceValidator, ExclusiveValidator, BlockerValidator',
         include_missing=False,
         doc="""Validators used to validate all relations,
-        regardless of their type."""
+        regardless of their type.""",
+        doc_domain='bhrelations'
     )
 
     duplicate_relation_type = Option(
         'bhrelations',
         'duplicate_relation',
         'duplicateof',
-        "Relation type to be used with the resolve as duplicate workflow.")
+        "Relation type to be used with the resolve as duplicate workflow.",
+        doc_domain='bhrelations')
 
     def __init__(self):
+        import pkg_resources
+        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
+        add_domain(self.env.path, locale_dir)
         links, labels, validators, blockers, copy_fields, exclusive = \
             self._parse_config()
         self._links = links

Modified: bloodhound/trunk/bloodhound_relations/bhrelations/templates/relations_manage.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/bhrelations/templates/relations_manage.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/bhrelations/templates/relations_manage.html (original)
+++ bloodhound/trunk/bloodhound_relations/bhrelations/templates/relations_manage.html Sat Feb 15 21:25:24 2014
@@ -24,21 +24,22 @@
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhrelations"
       xmlns:bh="http://issues.apache.org/bloodhound/wiki/Ui/Dashboard">
   <xi:include href="layout.html" />
   <xi:include href="widget_macros.html" />
 
   <head>
-    <title py:choose="">Ticket relations for #${ticket.id}</title>
+    <title py:choose="" i18n:msg="ticket_id">Ticket relations for #${ticket.id}</title>
   </head>
 
   <body>
-    <h1>Manage relations for ticket <a href="${href.ticket(ticket.id)}">#$ticket.id</a></h1>
+    <h1 i18n:msg="ticket_id">Manage relations for ticket <a href="${href.ticket(ticket.id)}">#$ticket.id</a></h1>
 
     <div class="row">
       <div class="span8">
         <py:if test='error'>
-          <div class="alert alert-error">
+          <div class="alert alert-error" i18n:msg="error">
             <span class="label label-important">Oops !</span>
             Could not create relation.
             $error

Modified: bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py (original)
+++ bloodhound/trunk/bloodhound_relations/bhrelations/web_ui.py Sat Feb 15 21:25:24 2014
@@ -30,7 +30,6 @@ from trac.core import Component, impleme
 from trac.resource import get_resource_url, Resource
 from trac.ticket.model import Ticket
 from trac.util import exception_to_unicode, to_unicode
-from trac.util.translation import _
 from trac.web import IRequestHandler, IRequestFilter
 from trac.web.chrome import ITemplateProvider, add_warning
 
@@ -38,6 +37,7 @@ from bhrelations.api import RelationsSys
     TicketRelationsSpecifics, UnknownRelationType, NoSuchTicketError
 from bhrelations.model import Relation
 from bhrelations.validation import ValidationError
+from bhrelations.utils.translation import _
 
 
 class RelationManagementModule(Component):

Modified: bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py (original)
+++ bloodhound/trunk/bloodhound_relations/bhrelations/widgets/relations.py Sat Feb 15 21:25:24 2014
@@ -24,11 +24,12 @@ r"""Project dashboard for Apache(TM) Blo
 Widgets displaying ticket relations.
 """
 
-from trac.util.translation import _
 from trac.ticket.model import Ticket
 
-from bhdashboard.util import WidgetBase, check_widget_name, pretty_wrapper
+from bhdashboard.util import pretty_wrapper
+from bhdashboard.util.widgets import WidgetBase, check_widget_name
 from bhrelations.web_ui import RelationManagementModule
+from bhrelations.utils.translation import _
 
 __metaclass__ = type
 

Modified: bloodhound/trunk/bloodhound_relations/setup.cfg
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/setup.cfg?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/setup.cfg (original)
+++ bloodhound/trunk/bloodhound_relations/setup.cfg Sat Feb 15 21:25:24 2014
@@ -23,3 +23,23 @@ tag_svn_revision = true
 [sdist]
 formats = gztar,bztar,ztar,tar,zip
 
+[extract_messages]
+add_comments = TRANSLATOR:
+msgid_bugs_address =
+output_file = bhrelations/locale/messages.pot
+keywords = _ ngettext:1,2 N_ tag_ tagn_:1,2 Option:4 BoolOption:4 IntOption:4 ListOption:6 OrderedExtensionsOption:6 PathOption:4
+no-wrap = true
+
+[init_catalog]
+input_file = bhrelations/locale/messages.pot
+output_dir = bhrelations/locale
+domain = bhrelations
+
+[compile_catalog]
+directory = bhrelations/locale
+domain = bhrelations
+
+[update_catalog]
+input_file = bhrelations/locale/messages.pot
+output_dir = bhrelations/locale
+domain = bhrelations

Modified: bloodhound/trunk/bloodhound_relations/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_relations/setup.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_relations/setup.py (original)
+++ bloodhound/trunk/bloodhound_relations/setup.py Sat Feb 15 21:25:24 2014
@@ -91,12 +91,15 @@ PKG_INFO = {'bhrelations': ('bhrelations
                               '../NOTICE', '../README', '../TESTING_README',
                               'htdocs/*.*', 'htdocs/css/*.css',
                               'htdocs/img/*.*', 'htdocs/js/*.js',
-                              'templates/*', 'default-pages/*'],
+                              'templates/*', 'default-pages/*',
+                              'locale/*/LC_MESSAGES/*.mo'],
                           ),
             'bhrelations.widgets': (
                 'bhrelations/widgets', ['templates/*.html']),
             'bhrelations.tests': (
                 'bhrelations/tests', ['data/*.*']),
+            'bhrelations.utils': (
+                'bhrelations/utils', []),
             }
 
 ENTRY_POINTS = {
@@ -108,6 +111,26 @@ ENTRY_POINTS = {
         'bhrelations.widgets.ticketrelations = bhrelations.widgets.relations',
     ],
 }
+
+extra = {}
+try:
+    from trac.util.dist import get_l10n_js_cmdclass
+    cmdclass = get_l10n_js_cmdclass()
+    if cmdclass:
+        extra['cmdclass'] = cmdclass
+        extractors = [
+            ('**.py',                'trac.dist:extract_python', None),
+            ('**/templates/**.html', 'genshi', None),
+            ('**/templates/**.txt',  'genshi', {
+                'template_class': 'genshi.template:TextTemplate'
+            }),
+        ]
+        extra['message_extractors'] = {
+            'bhrelations': extractors,
+        }
+except ImportError:
+    pass
+
 setup(
     name=DIST_NM,
     version=latest,
@@ -131,5 +154,6 @@ setup(
     classifiers = cats,
     long_description= DESC,
     test_suite='bhrelations.tests.test_suite',
-    tests_require=['unittest2' if parse_version(sys.version) < parse_version('2.7') else '']
+    tests_require=['unittest2' if parse_version(sys.version) < parse_version('2.7') else ''],
+    **extra
     )

Modified: bloodhound/trunk/bloodhound_search/bhsearch/api.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_search/bhsearch/api.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_search/bhsearch/api.py (original)
+++ bloodhound/trunk/bloodhound_search/bhsearch/api.py Sat Feb 15 21:25:24 2014
@@ -25,6 +25,7 @@ from trac.core import (Interface, Compon
 from trac.env import IEnvironmentSetupParticipant
 from multiproduct.api import ISupportMultiProductEnvironment
 from multiproduct.core import MultiProductExtensionPoint
+from bhsearch.utils.translation import _, add_domain
 
 ASC = "asc"
 DESC = "desc"
@@ -238,19 +239,25 @@ class BloodhoundSearchApi(Component):
     """
     implements(IEnvironmentSetupParticipant, ISupportMultiProductEnvironment)
 
+    def __init__(self, *args, **kwargs):
+        import pkg_resources
+        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
+        add_domain(self.env.path, locale_dir)
+        super(BloodhoundSearchApi, self).__init__(*args, **kwargs)
+
     backend = ExtensionOption('bhsearch', 'search_backend',
         ISearchBackend, 'WhooshBackend',
         'Name of the component implementing Bloodhound Search backend \
-        interface: ISearchBackend.')
+        interface: ISearchBackend.', doc_domain='bhsearch')
 
     parser = ExtensionOption('bhsearch', 'query_parser',
         IQueryParser, 'DefaultQueryParser',
         'Name of the component implementing Bloodhound Search query \
-        parser.')
+        parser.', doc_domain='bhsearch')
 
     index_pre_processors = OrderedExtensionsOption(
         'bhsearch', 'index_preprocessors', IDocIndexPreprocessor,
-        ['SecurityPreprocessor'],
+        ['SecurityPreprocessor'], include_missing=True,
     )
     result_post_processors = ExtensionPoint(IResultPostprocessor)
     query_processors = ExtensionPoint(IQueryPreprocessor)

Modified: bloodhound/trunk/bloodhound_search/bhsearch/search_resources/base.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/base.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_search/bhsearch/search_resources/base.py (original)
+++ bloodhound/trunk/bloodhound_search/bhsearch/search_resources/base.py Sat Feb 15 21:25:24 2014
@@ -30,12 +30,13 @@ class BaseIndexer(Component):
     This is base class for Bloodhound Search indexers of specific resource
     """
     silence_on_error = BoolOption('bhsearch', 'silence_on_error', "True",
-        """If true, do not throw an exception during indexing a resource""")
+        """If true, do not throw an exception during indexing a resource""",
+                                  doc_domain='bhsearch')
 
     wiki_formatter = ExtensionOption('bhsearch', 'wiki_syntax_formatter',
         ISearchWikiSyntaxFormatter, 'SimpleSearchWikiSyntaxFormatter',
         'Name of the component implementing wiki syntax to text formatter \
-        interface: ISearchWikiSyntaxFormatter.')
+        interface: ISearchWikiSyntaxFormatter.', doc_domain='bhsearch')
 
 
 class BaseSearchParticipant(Component):

Modified: bloodhound/trunk/bloodhound_search/bhsearch/search_resources/changeset_search.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/changeset_search.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_search/bhsearch/search_resources/changeset_search.py (original)
+++ bloodhound/trunk/bloodhound_search/bhsearch/search_resources/changeset_search.py Sat Feb 15 21:25:24 2014
@@ -114,19 +114,21 @@ class ChangesetSearchParticipant(BaseSea
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join(default_facets),
-        doc="""Default facets applied to search view of specific resource""")
+        doc="""Default facets applied to search view of specific resource""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc = """If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     default_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default=",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     #ISearchParticipant members
     def get_title(self):

Modified: bloodhound/trunk/bloodhound_search/bhsearch/search_resources/milestone_search.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/milestone_search.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_search/bhsearch/search_resources/milestone_search.py (original)
+++ bloodhound/trunk/bloodhound_search/bhsearch/search_resources/milestone_search.py Sat Feb 15 21:25:24 2014
@@ -148,19 +148,21 @@ class MilestoneSearchParticipant(BaseSea
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join(default_facets),
-        doc="""Default facets applied to search view of specific resource""")
+        doc="""Default facets applied to search view of specific resource""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc = """If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     default_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default=",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     #ISearchParticipant members
     def get_title(self):

Modified: bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py (original)
+++ bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py Sat Feb 15 21:25:24 2014
@@ -214,19 +214,21 @@ class TicketSearchParticipant(BaseSearch
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join(default_facets),
-        doc="""Default facets applied to search view of specific resource""")
+        doc="""Default facets applied to search view of specific resource""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc = """If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     default_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default = ",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     #ISearchParticipant members
     def get_title(self):

Modified: bloodhound/trunk/bloodhound_search/bhsearch/search_resources/wiki_search.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/wiki_search.py?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_search/bhsearch/search_resources/wiki_search.py (original)
+++ bloodhound/trunk/bloodhound_search/bhsearch/search_resources/wiki_search.py Sat Feb 15 21:25:24 2014
@@ -140,19 +140,21 @@ class WikiSearchParticipant(BaseSearchPa
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join(default_facets),
-        doc="""Default facets applied to search view of specific resource""")
+        doc="""Default facets applied to search view of specific resource""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc = """If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     default_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default = ",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     #ISearchParticipant members
     def get_title(self):

Modified: bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html (original)
+++ bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html Sat Feb 15 21:25:24 2014
@@ -24,6 +24,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhsearch"
       xmlns:xi="http://www.w3.org/2001/XInclude">
   <xi:include href="layout.html" />
 
@@ -199,4 +200,4 @@
 
     </div>
   </body>
-</html>
\ No newline at end of file
+</html>

Modified: bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html?rev=1568681&r1=1568680&r2=1568681&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html (original)
+++ bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html Sat Feb 15 21:25:24 2014
@@ -23,6 +23,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhsearch"
       xmlns:xi="http://www.w3.org/2001/XInclude">
 <a py:if="active_product or active_filter_queries or query" href="${href.bhsearch()}">Search</a>
 <py:if test='active_product'>