рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ: рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдПрдВрдЯреАрд▓реЛрдк рд░реЛрд╕реНрдЯ рд░реЗрд╕рд┐рдкреА



рд╕реАрдПрдордПрдл рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдореБрдЭреЗ i18n (рдмрд╣реБрднрд╛рд╖рд╛рд╡рд╛рдж) рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛, рдФрд░ рд╡рд┐рднрд┐рдиреНрди рд╡рд┐рдХрд▓реНрдкреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ ...



рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдкрд┐рдЫрд▓реЗ рдЕрдиреБрднрд╡ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдореИрдВ "рднрд╛рд╖рд╛ рд╕реНрдерд┐рд░рд╛рдВрдХ" рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдФрд░ рдЕрдВрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИрдХ рдХреЗ рд╕рд╛рде рдХреНрд▓реЗрд╢ред рд▓реЗрдХрд┐рди рдлрд┐рд░, рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдореИрдВрдиреЗ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдФрд░ рд▓реЛрдХрдкреНрд░рд┐рдп (рдпреВрдирд┐рдХреНрд╕-рдЖрдзрд╛рд░рд┐рдд) рдЯреВрд▓ рдореЗрдВ рдЬреАрдПрдирдпреВ рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ рдХреЛ рдЪреБрдирд╛ред рдЬрд▓реНрдж рд╣реА рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдпрд╣ рд╕рд░реНрд╡рд░ рдХреЛ рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХреЗ рдЕрдиреБрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдЕрдзрд┐рднрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЦреЛрдЬ рдЗрдВрдЬрди рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рдпрд╣ рдХрд┐ рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рдЙрдирдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдПрдХрд▓ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХреАрдХреГрдд рдкреНрд░рдгрд╛рд▓реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред

Googling gettext рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рдореИрдВрдиреЗ рдХрдИ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреЗрдЦреЗред



рдкрд╣рд▓рд╛ рдкрдХрдбрд╝рд╛ рдЧрдпрд╛ - code.google.com/p/gettext-js

рдкреНрд▓рд╕ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдореВрд▓ рдкреЛ-рдлрд╛рдЗрд▓ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд░реВрдкрд╛рдВрддрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдорд╛рдЗрдирд╕ - рдХреЛрдИ рдирдЧреЗрдЯ рдирд╣реАрдВ рд╣реИред



рддрдм рдореБрдЭреЗ plugins.jquery.com/project/gettext рдорд┐рд▓рд╛

рдореИрдВрдиреЗ рдЗрд╕рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкреНрд▓рдЧрдЗрди рдХреЛ рдПрдХ MO рдлрд╛рдЗрд▓ рд╕реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ JSON рдлрд╝рд╛рдЗрд▓ рдХреА рддреИрдпрд╛рд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред



рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП, рдкрд╛рдпрдерди рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

import simplejson as enc import gettext def gettext_json(domain, path, lang = [], indent = False): try: tr = gettext.translation(domain, path, lang) # for unknown reasons, instead of having plural entries like # key: [sg, pl1...] # tr._catalog has (key, n): pln, keys = tr._catalog.keys() keys.sort() ret = {} for k in keys: v = tr._catalog[k] if type(k) is tuple: if k[0] not in ret: ret[k[0]] = [] ret[k[0]].append(v) else: ret[k] = v return enc.dumps(ret, ensure_ascii = False, indent = indent) except IOError: return None
      
      







рдореБрдЭреЗ рдЦрд░реНрдЪ рдХрд░рдирд╛ рдерд╛ ... рдЧреБрдЧреНрдЧреБрд▓рдЬрд╝ рдкрд░ рдмреАрд╕ рдорд┐рдирдЯ рдФрд░ рдХреЛрдб рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдФрд░ рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбреЙрдХ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ред рдирддреАрдЬрддрди, рдореИрдВрдиреЗ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдпреВрдирд┐рдХреНрд╕ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдЬрдиреНрдо рджрд┐рдпрд╛ред



gettext2json

 #!/usr/bin/python import sys import simplejson as enc import gettext def gettext_json(domain, path, lang = [], indent = False): try: tr = gettext.translation(domain, path, lang) # for unknown reasons, instead of having plural entries like # key: [sg, pl1...] # tr._catalog has (key, n): pln, keys = tr._catalog.keys() keys.sort() ret = {} for k in keys: v = tr._catalog[k] if type(k) is tuple: if k[0] not in ret: ret[k[0]] = [] ret[k[0]].append(v) else: ret[k] = v return enc.dumps(ret, ensure_ascii = True, indent = indent) except IOError as (errno, strerror): print "I/O error({0}): {1}".format(errno, strerror) print gettext_json(sys.argv[1],sys.argv[2],[sys.argv[3]], True)
      
      







рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВрдиреЗ рдЯреЗрдХреНрд╕реНрдЯ PO рдлрд╛рдЗрд▓реЛрдВ рд╕реЗ рдмрд╛рдЗрдирд░реА рдПрдордУ рдлрд╛рдЗрд▓реЗрдВ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рд╣реИ:



BuildLocales:

 #!/usr/bin/php -q <?php chdir(__DIR__); $lcPath = './locale'; $jsPath = './static/locale'; foreach (glob($lcPath.'/*/LC_MESSAGES/*.po') as $poFile) { $locale = pathinfo(dirname(dirname($poFile)), PATHINFO_FILENAME); $domain = pathinfo($poFile, PATHINFO_FILENAME); $moFile = dirname($poFile).'/'.$domain.'.mo'; $jsFile = $jsPath.'/'.$locale.'/'.$domain.'.json'; shell_exec('mkdir -p '.escapeshellarg($jsPath.'/'.$locale)); shell_exec('msgfmt -o '.escapeshellarg($moFile).' '.escapeshellarg($poFile)); $cmd = 'gettext2json '.escapeshellarg($domain).' '.escapeshellarg($lcPath ).' '.escapeshellarg($locale).' > '.escapeshellarg($jsFile); shell_exec($cmd); }
      
      





рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рднреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдмрд╕ рд╕реНрдерд╛рдиреАрдп рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЯреЗрдХреНрд╕реНрдЯ .po рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдмрдирд╛рдиреЗ / рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдмрд┐рд▓реНрдбрдкреНрд▓реЗрд▓реЗрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред



рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ html рдЯреИрдЧ рдХреА рд▓реИрдВрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╕рд┐рд░ рдореЗрдВ json рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдкрде рдХреЗ рд╕рд╛рде рдПрдХ рд▓рд┐рдВрдХ рддрддреНрд╡ рдЬреЛрдбрд╝реЗрдВ рдФрд░ jquery.gettext.js рд▓реЛрдб рдХрд░реЗрдВред



рдкреГрд╖реНрда рдХреЗ HTML рдХреЛрдб рдХреА рд╢реБрд░реБрдЖрдд рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧреА:



 <!DOCTYPE html> <html lang="ru"> ... <link href="/locale/ru/mydomain.json" lang="ru" rel="gettext"/> <script type="text/javascript" src="/js/jquery.gettext.js" /> ...
      
      







рдлрд┐рд░ рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ _ ("рдирдорд╕реНрддреЗ рджреБрдирд┐рдпрд╛!") рдФрд░ рдЖрдирдВрдж рд▓реЗрдВред рдКрдкреНрд╕! рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ!



рд╣рдореЗрдВ jquery.gettext.js рдореЗрдВ рдХреБрдЫ рдареАрдХ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдкреИрдЪ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:



 63,66c63,70 < try { < var messages = eval('(' + data + ')'); < } catch(e) { < return; --- > if (typeof(data) == 'object') { > var messages = data; > } else { > try { > var messages = eval('(' + data + ')'); > } catch(e) { > return; > }
      
      





рдЬреЛ рд▓реЛрдЧ рдкреИрдЪ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд▓рд╕реА рд╣реЛрддреЗ рд╣реИрдВ рд╡реЗ jquery.gettext.js рд▓реЗрддреЗ рд╣реИрдВред



рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдкрдиреЗ рднреБрдирд╛ рдХрд╛ рдЖрдирдВрдж рд▓рд┐рдпрд╛, рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред



All Articles