Hi everyone I post a reply in the web3py thread in this mailing list
asking for a site where make a wishlist, but thinking about what I would
want in web3py, I realized that I needed in web2py already so I have
make a patch for the actual translation system in the gluon/languages.py
file.

One of the lacks that I see in the translation system is that is a
little difficult to maintain the language file in large applications
like the one I am developing at this moment. Think about modules that
you can plug or unplug of your application, and each have their own
strings, or something more common, the pluggin system.

Actually if you want to install a plugin like plugin_wiki you have to do
your own translation because you cannot insert translation files (if
actually web2py supports this... do it I don't know how to make it xD).
It would be great to have a community where you can make plugins and add
the language files inside.

This is what makes the patch:

Allows to use a "namespace" parameter in the T() like this

T("Hello World", namespace="plugin_wiki")

So in the languages/ folder will appear this:

- languages/
    - en_en.py
    - plugin_wiki/
        - en_en.py

so if you use T("Hello World", namespace="plugin_wiki") it will go to
find the string into languates/plugin_wiki/*your_lang*.py and if you use
the common way T("Hello World") it will go as always to
languages/*your_lang*.py

I haven't tested it enough but it works for me at now, and I haven't
written the part for the admin interface where you can push the button
for refreshing the lang files (I don't get on wiht the RegExp at all)

My 2 cents
I hope that I can send the patch to the list

-- 



--- languages.py_orig_bkp	2012-11-29 12:41:39.377540956 +0100
+++ languages.py	2012-11-29 12:48:52.881536524 +0100
@@ -49,7 +49,7 @@
         logging.error('Syntax error in %s' % filename)
         return {}
 
-def read_dict(filename):    
+def read_dict(filename):
     return getcfs('language:%s'%filename,filename,
                   lambda filename=filename:read_dict_aux(filename))
 
@@ -110,28 +110,30 @@
     m = None
     s = None
     T = None
-
+    n = None
     def __init__(
         self,
         message,
         symbols = {},
         T = None,
+        namespace="app_base"
         ):
         self.m = message
         self.s = symbols
         self.T = T
+        self.n = namespace
 
     def __repr__(self):
         return "<lazyT %s>" % (repr(str(self.m)), )
 
     def __str__(self):
-        return self.T.translate(self.m, self.s)
+        return self.T.translate(self.m, self.s, self.n)
 
     def __eq__(self, other):
-        return self.T.translate(self.m, self.s) == other
+        return self.T.translate(self.m, self.s, self.n) == other
 
     def __ne__(self, other):
-        return self.T.translate(self.m, self.s) != other
+        return self.T.translate(self.m, self.s, self.n) != other
 
     def __add__(self, other):
         return '%s%s' % (self, other)
@@ -173,7 +175,7 @@
         return str(self)
 
     def __mod__(self, symbols):
-        return self.T.translate(self.m, symbols)
+        return self.T.translate(self.m, symbols, self.n)
 
 
 class translator(object):
@@ -194,16 +196,21 @@
 
     notice 2: en and en-en are considered different languages!
     """
-
+    t={}
+    
     def __init__(self, request):
         self.request = request
         self.folder = request.folder
         self.current_languages = ['en']
         self.accepted_language = None
-        self.language_file = None
+        self.language_file = {}
+        self.language_file['app_base'] = None
+        self.t = {}
+        self.t['app_base'] = {}
         self.http_accept_language = request.env.http_accept_language
         self.requested_languages = self.force(self.http_accept_language)
         self.lazy = True
+        self.namespace = 'app_base'        
         self.otherTs = {}
 
     def get_possible_languages(self):
@@ -221,6 +228,7 @@
         self.force(self.http_accept_language)
 
     def force(self, *languages):
+        ret_langs = False
         if not languages or languages[0] is None:
             languages = []
         if len(languages) == 1 and isinstance(languages[0], (str, unicode)):
@@ -238,23 +246,45 @@
                     self.accepted_language = language
                     break
                 filename = os.path.join(self.folder, 'languages/', language + '.py')
-                if os.path.exists(filename):
+                if os.path.exists(filename):                    
                     self.accepted_language = language
-                    self.language_file = filename
-                    self.t = read_dict(filename)
+                    self.language_file['app_base'] = filename
+                    self.t['app_base'] = read_dict(filename)
+                    ret_langs = True
+                    #return languages
+                
+                root_dir = os.path.join(self.folder, 'languages/')
+                #for root, dirs, files in os.walk(root_dir):
+                for namespace in os.listdir(root_dir):                    
+                    if namespace.startswith("."):
+                        continue                    
+                    if os.path.isdir(root_dir+namespace):
+                        filename = os.path.join(self.folder, 'languages/',  namespace + os.sep, language + '.py')
+                        if os.path.exists(filename):                            
+                            self.language_file[namespace] = filename
+                            self.t[namespace] = read_dict(filename)
+                if ret_langs == True:
                     return languages
-        self.language_file = None
-        self.t = {}  # ## no language by default
+        for key, value in self.language_file.items():
+            self.language_file[key] = None
+        for key, value in self.t.items():
+            self.t[key] = {}  # ## no language by default
         return languages
 
-    def __call__(self, message, symbols={}, language=None, lazy=None):
+    def __call__(self, message, symbols={}, language=None, lazy=None, namespace=None):        
+        if namespace is None:
+            namespace = 'app_base'
+        if namespace != 'app_base':
+            namespace_folder =os.path.join(self.folder, 'languages/', namespace) 
+            if not os.path.exists(namespace_folder):
+                os.makedirs(namespace_folder)        
         if lazy is None:
             lazy = self.lazy
         if not language:
             if lazy:
-                return lazyT(message, symbols, self)
+                return lazyT(message, symbols, self, namespace)
             else:
-                return self.translate(message, symbols)
+                return self.translate(message, symbols, namespace)
         else:
             try:
                 otherT = self.otherTs[language]
@@ -263,7 +293,7 @@
                 otherT.force(language)
             return otherT(message, symbols, lazy=lazy)
 
-    def translate(self, message, symbols):
+    def translate(self, message, symbols, namespace='app_base'):
         """
         user ## to add a comment into a translation string
         the comment can be useful do discriminate different possible
@@ -278,6 +308,11 @@
         """
         #for some reason languages.py gets executed before gaehandler.py
         # is able to set web2py_runtime_gae, so re-check here
+        if namespace not in self.t.keys():
+            self.t[namespace] = {}
+        if namespace not in self.language_file.keys():
+            self.language_file[namespace] = os.path.join(self.folder, 'languages/', namespace + os.sep , self.accepted_language + '.py') 
+            #self.language_file[namespace] = None 
         is_gae = settings.global_settings.web2py_runtime_gae
         if not message.startswith('#') and not '\n' in message:
             tokens = message.rsplit('##', 1)
@@ -287,11 +322,11 @@
         if len(tokens) == 2:
             tokens[0] = tokens[0].strip()
             message = tokens[0] + '##' + tokens[1].strip()
-        mt = self.t.get(message, None)
+        mt = self.t[namespace].get(message, None)
         if mt is None:
-            self.t[message] = mt = tokens[0]
-            if self.language_file and not is_gae:
-                write_dict(self.language_file, self.t)
+            self.t[namespace][message] = mt = tokens[0]
+            if self.language_file[namespace] and not is_gae:
+                write_dict(self.language_file[namespace], self.t[namespace])
         if symbols or symbols == 0:
             return mt % symbols
         return mt

Reply via email to