Django DIY рднрд╛рдЧ 2: рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг

рднрд╛рдЧ 1

рдкрд░рд┐рдЪрдпред


рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдореИрдВ рд▓реЗрдЦ рдорд╛рд░реНрдЧреЛрдВ рдореЗрдВ рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдЦрд┐рд▓рд╛рдл рд▓рдбрд╝рд╛рдИ рдореЗрдВ рдЕрдзрд┐рдХ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг рдХрд╛ рд╡рд┐рд╖рдп рдХрд╛рдлреА рд╡реНрдпрд╛рдкрдХ рдерд╛, рдЗрд╕рд▓рд┐рдП рдЙрдирдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдПрдХ рдкрдж рд╕рдорд░реНрдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ред рд╣рдо рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░ рдЖрдо рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

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

рдкрд╛рдпрдерди рдлрд╛рдЗрд▓реЛрдВ рд╕реЗ рдЕрдиреБрд╡рд╛рдж рд╡рд╛рдХреНрдпрд╛рдВрд╢


рдЕрдиреБрд╡рд╛рдж рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдиреБрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдо рдЗрд╕реЗ рдЙрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдирд╛рдо рд╕реЗ рдЧреБрдЬрд╛рд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЕрдиреБрд╡рд╛рдж рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣реА рд╣реИред рдЕрдЧрд▓рд╛, рд╣рдо рдмрд╕ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ _ () рдХрд╣рддреЗ рд╣реИрдВ рдФрд░ рдЕрдиреБрд╡рд╛рджрд┐рдд рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдХреЛ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
import core.union; _ = core.union.get_trans('module') _('text') 


рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕реЗ рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХрд╛ рдЕрдиреБрд╡рд╛рдж


рд░реЗрдВрдбрд░_рдЯреИрдореНрдкрд▓ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдкреЗрд╕реНрдЯ рдХрд░реЗрдВ, рдЬреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ, рдЕрдиреБрд╡рд╛рдж рдлрдВрдХреНрд╢рди рдХреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдЕрдВрд╢:
 p['gettext'] = get_trans(module) p['_'] = get_trans(module) 

рдирддреАрдЬрддрди, рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:
 def render_templ(template, **kwarg): template = jinja.get_template(template) module = split_templ_name( template)[0] kwarg['gettext'] = get_trans(module) kwarg['_'] = get_trans(module) kwarg['context'] = context() return template.render(**kwarg) 


рдЖрдк рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рднреА рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЗрд╕реЗ рдкрд╛рд░рд┐рдд рди рдХрд░реЗрдВред
рдЗрд╕рдХреЗ рдмрд╛рдж рдЕрдиреБрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдп рдЖрддреЗ рд╣реИрдВред
 langs = {} def load_lng(path, module_name, lang): """     """ if not module_name in langs[lang]: langs[lang][module_name] = [] path = os.path.join( path, module_name, 'locale') if module_name else os.path.join (path, 'locale') if os.path.isdir(path): t = gettext.translation('_', path, [cur_lang()], codeset='UTF-8') langs[lang][module_name].append(t) def get_lng(module): """     . """ lang = cur_lang() if not lang in langs: langs[lang] = {} if not module in langs[lang]: langs[lang][module] = [] load_lng(os.path.join (settings.lib_path,'app'), module, lang) load_lng(os.path.join (os.getcwd(),'app'), module, lang) if not module: load_lng(os.path.join (os.getcwd()), '', lang) return langs[lang][module] def trans(module, s): """     ,      """ if type(s) == str: s = s.decode('UTF-8') translated = s lng = get_lng(module) if lng: for i in reversed(lng): translated = i.gettext(s).decode('UTF-8') #     translated        . if s != translated: break return translated def get_trans(module): #       return lambda s: trans(module, s) 


рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ


рдЕрдм рд╣рдореЗрдВ {{_ ('рдЯреЗрдХреНрд╕реНрдЯ')}} рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж рдЕрдиреБрд╡рд╛рдж рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдореЗрдВ / app / рдореЙрдбреНрдпреВрд▓ / ru / LS_MESSAGES рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдореЗрдВ _.mo, _.po рдлрд╛рдЗрд▓реЗрдВ рдорд┐рд▓рдиреА рдЪрд╛рд╣рд┐рдПред
_.mo - рд╕рдВрдХрд▓рд┐рдд рдлрд╝рд╛рдЗрд▓ рдЬрд╣рд╛рдБ рд╕реЗ gettext рддрдм рдЕрдиреБрд╡рд╛рдж рдкрдврд╝рддрд╛ рд╣реИред
_.po - рдЗрд╕ рдореЙрдбрд▓ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрдиреБрд╡рд╛рджрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб рд╡рд╛рд▓реА рдлрд╝рд╛рдЗрд▓:
 #: /path/modul/templ/base.tpl:25 msgid "text" msgstr "" #      . 

рдпреЗ рдлрд╝рд╛рдЗрд▓реЗрдВ рдХрдВрд╕реЛрд▓ рд╕реЗ рдорд╛рдирдХ рдХрдорд╛рдВрдб рджреНрд╡рд╛рд░рд╛ рдкреНрд░рдмрдВрдзрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ:
xgettext - рдЕрдиреБрд╡рд╛рдж рдХреЗ рд▓рд┐рдП рдлрд╛рдЗрд▓реЛрдВ рд╕реЗ рд▓рд╛рдЗрдиреЗрдВ рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИред
msginit - рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрд╡рд╛рдж рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рддрд╛ рд╣реИ _.poред
msgfmt - _.mo рдмрд╛рдЗрдирд░реА рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред
msgmerge - рдЕрдиреБрд╡рд╛рдж рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВред
рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рд╕рдм рдХреБрдЫ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдФрд░ рд╣рд░ рдмрд╛рд░ рдХрдИ рдХрдорд╛рдВрдб рдирд╣реАрдВ рд▓рд┐рдЦреВрдВрдЧрд╛, рдФрд░ рджреВрд╕рд░реА рдмрд╛рдд, xgettext рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ * .py рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде, рдХрдо рд╕реЗ рдХрдо рдЙрд╕реЗ рдРрд╕рд╛ рдЕрд╡рд╕рд░ рдирд╣реАрдВ рдорд┐рд▓рд╛ред
рдЗрд╕рд▓рд┐рдП, рд╣рдо рдПрдХ рдЫреЛрдЯреА рд╕реА рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд▓рд┐рдЦреЗрдВрдЧреЗ рдХрд┐ рдПрдХ рдХрдорд╛рдВрдб рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЗрди рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░реЗрдЧрд╛ред

 #     . list_lang = ['ru_RU', 'en_US']     . s = str(sys.argv) s = s[1:-1]; app = [] for word in s.split(", "): app.append(word) #      lib_path = '/path' #      app_path = app[1][1:-1] def iter_trans(dir, is_app=True): """             .""" if is_app: #    for res in os.listdir(dir): path_ = os.path.join(dir, res, 'locale') if os.path.isdir(path_): for res in os.listdir(path_): path = os.path.join(path_, res, 'LC_MESSAGES') if os.path.isdir(path): po_f = os.path.join(path, '_.po') mo_f = os.path.join(path, '_.mo') os.popen("msgfmt -o %s %s" % (mo_f, po_f )).read() else: #      . path_ = os.path.join(dir, 'locale') if os.path.isdir(path_): for res in os.listdir(path_): path = os.path.join(path_, res, 'LC_MESSAGES') if os.path.isdir(path): po_f = os.path.join(path, '_.po') mo_f = os.path.join(path, '_.mo') os.popen("msgfmt -o %s %s" % (mo_f, po_f )).read() def iter_mo(dir, is_app=True): """    """ if is_app: for res in os.listdir(dir): path = os.path.join(dir, res, 'templ') if os.path.isdir(path): iter_templ(path) else: path = os.path.join(dir, 'templ') if os.path.isdir(path): iter_templ(path) pot_header = """# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\\n" "Report-Msgid-Bugs-To: \\n" "POT-Creation-Date: %s\\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" "Language-Team: LANGUAGE <LL@li.org>\\n" "MIME-Version: 1.0\\n" "Content-Type: text/plain; charset=UTF-8\\n" "Content-Transfer-Encoding: 8bit\\n" """ % (time.strftime("%Y-%m-%d %H:%M%z")) def iter_templ(dir): """           pot .        _.po      . """ out_f = os.path.join(dir, '..', 'locale', '_.pot') file_o = open(out_f, 'w') #    . file_o.write(pot_header) for name in os.listdir(dir): if name.endswith('.tpl'): load_translation(os.path.join(dir, name), file_o) file_o.close() for res in list_lang: lang = res[:2] po_path = os.path.join(dir, '..', 'locale', lang) if not os.path.isdir(po_path): os.makedirs(po_path, 0755) po_path = os.path.join(po_path, 'LC_MESSAGES') if not os.path.isdir(po_path): os.makedirs(po_path, 0755) po_f = os.path.join(po_path, '_.po') if not os.path.isfile(po_f): os.popen("msginit --no-translator -i %s -o %s -l %s" % ( out_f, po_f, res+'.UTF-8')).read() else: os.popen("msgmerge %s %s -o %s" % (po_f, out_f, po_f)).read() def load_translation(in_f, file): """         . """ with open(in_f, 'r') as f: l = f.read().split('\n') n = 0; r = {} for rs in l: n += 1 #     aa = re.findall(r'_\([^)]+\)', rs) for res in aa: #         res = res[3:-2] #       if not res in r: r[res] = [] #    r[res].append(n) for res, nums in r.iteritems(): file.write('#: '+in_f+':'+','.join([str(x) for x in nums])+'\n') file.write('msgid "'+res+'"\n') file.write('msgstr ""\n\n') #       'cpl',  ,  ,    . itr = iter_trans if len(app) > 2 and app[2][1:-1] == 'cpl' else iter_mo for res in [lib_path + '/', False, lib_path +'/app/', app_path +'/app/', app_path + '/', False]: itr(res) 


рд╕рд╛рд░рд╛рдВрд╢


рдЕрдм рд░реВрдкрд░реЗрдЦрд╛ рдореЗрдВ рдПрдХ рдореЙрдбреНрдпреВрд▓рд░ рд╕рдВрд░рдЪрдирд╛, рдорд╛рдирдХреАрдХрд░рдг рдФрд░ рдЖрдВрддрд░рд┐рдХрдХрд░рдг рд╣реИред рдПрдХ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдкрд░реЗрдЦрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдмрд╕ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдорд╛рд░реНрдЧреЛрдВ рдФрд░ рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реИред рдЙрд╕рдХреЗ рдмрд╛рдж, рдореБрдЦреНрдп рдШрдЯрдХ рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛: рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдкреИрдирд▓, рдбреЗрдЯрд╛ рдкреНрд░рд╕реНрддреБрддрд┐, рдЖрджрд┐ред
рдЕрднреА рдХреЗ рд▓рд┐рдП рдмрд╕ рдЗрддрдирд╛ рд╣реАред

рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛


рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ рдХреА рдкреНрд░рдХреГрддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдЕрдЬрдЧрд░ рдореЗрдВ рдЧреЗрдЯреЗрдХреНрд╕реНрдЯ рдХрд╛ рдкрд░рд┐рдЪрдп
gettext рдФрд░ jinja2
рдкрд╛рдпрдерди рдФрд░ рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ рдкреНрд░рд▓реЗрдЦрди

рд╡рд┐рд╕реНрддрд╛рд░

Source: https://habr.com/ru/post/In146798/


All Articles