Code

Ticket #18731: makemessages.patch

File makemessages.patch, 10.8 KB (added by diabeteman, 16 months ago)

Adds --extra-keyword to the makemessages command. (with docs and tests)

  • django/core/management/commands/makemessages.py

    diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
    index 606cbe0..55b9ee1 100644
    a b def write_pot_file(potfile, msgs, file, work_file, is_templatized): 
    126126        fp.write(msgs) 
    127127 
    128128def process_file(file, dirpath, potfile, domain, verbosity, 
    129                  extensions, wrap, location, stdout=sys.stdout): 
     129                 extensions, wrap, location, stdout=sys.stdout, 
     130                 extra_keywords=None): 
    130131    """ 
    131132    Extract translatable literals from :param file: for :param domain: 
    132133    creating or updating the :param potfile: POT file. 
    def process_file(file, dirpath, potfile, domain, verbosity, 
    149150        work_file = os.path.join(dirpath, thefile) 
    150151        with open(work_file, "w") as fp: 
    151152            fp.write(src_data) 
    152         cmd = ( 
    153             'xgettext -d %s -L C %s %s --keyword=gettext_noop ' 
    154             '--keyword=gettext_lazy --keyword=ngettext_lazy:1,2 ' 
    155             '--keyword=pgettext:1c,2 --keyword=npgettext:1c,2,3 ' 
    156             '--from-code UTF-8 --add-comments=Translators -o - "%s"' % 
    157             (domain, wrap, location, work_file)) 
     153 
     154        keywords = ['gettext_noop', 
     155                    'gettext_lazy', 
     156                    'ngettext_lazy:1,2', 
     157                    'pgettext:1c,2', 
     158                    'npgettext:1c,2,3', 
     159                    ] 
     160        if extra_keywords: 
     161            keywords.extend(extra_keywords) 
     162 
     163        cmd = 'xgettext -d %s -L C %s %s' 
     164        for kw in keywords: 
     165            cmd += ' --keyword=%s' % kw 
     166        cmd += ' --from-code UTF-8 --add-comments=Translators -o - "%s"' 
     167        cmd %= (domain, wrap, location, work_file) 
     168 
    158169    elif domain == 'django' and (file_ext == '.py' or file_ext in extensions): 
    159170        thefile = file 
    160171        orig_file = os.path.join(dirpath, file) 
    def process_file(file, dirpath, potfile, domain, verbosity, 
    167178            with open(os.path.join(dirpath, thefile), "w") as fp: 
    168179                fp.write(content) 
    169180        work_file = os.path.join(dirpath, thefile) 
    170         cmd = ( 
    171             'xgettext -d %s -L Python %s %s --keyword=gettext_noop ' 
    172             '--keyword=gettext_lazy --keyword=ngettext_lazy:1,2 ' 
    173             '--keyword=ugettext_noop --keyword=ugettext_lazy ' 
    174             '--keyword=ungettext_lazy:1,2 --keyword=pgettext:1c,2 ' 
    175             '--keyword=npgettext:1c,2,3 --keyword=pgettext_lazy:1c,2 ' 
    176             '--keyword=npgettext_lazy:1c,2,3 --from-code UTF-8 ' 
    177             '--add-comments=Translators -o - "%s"' % 
    178             (domain, wrap, location, work_file)) 
     181 
     182        keywords = ['gettext_lazy', 
     183                    'ngettext_lazy:1,2', 
     184                    'ugettext_noop', 
     185                    'ugettext_lazy', 
     186                    'ungettext_lazy:1,2', 
     187                    'pgettext:1c,2', 
     188                    'npgettext:1c,2,3', 
     189                    'pgettext_lazy:1c,2', 
     190                    'npgettext_lazy:1c,2,3', 
     191                    ] 
     192        if extra_keywords: 
     193            keywords.extend(extra_keywords) 
     194 
     195        cmd = 'xgettext -d %s -L Python %s %s' 
     196        for kw in keywords: 
     197            cmd += ' --keyword=%s' % kw 
     198        cmd += ' --from-code UTF-8 --add-comments=Translators -o - "%s"' 
     199        cmd %= (domain, wrap, location, work_file) 
    179200    else: 
    180201        return 
    181202    msgs, errors, status = _popen(cmd) 
    def write_po_file(pofile, potfile, domain, locale, verbosity, stdout, 
    246267 
    247268def make_messages(locale=None, domain='django', verbosity=1, all=False, 
    248269        extensions=None, symlinks=False, ignore_patterns=None, no_wrap=False, 
    249         no_location=False, no_obsolete=False, stdout=sys.stdout): 
     270        no_location=False, no_obsolete=False, stdout=sys.stdout, 
     271        extra_keywords=None): 
    250272    """ 
    251273    Uses the ``locale/`` directory from the Django Git tree or an 
    252274    application/project to process all files with translatable literals for 
    def make_messages(locale=None, domain='django', verbosity=1, all=False, 
    325347        for dirpath, file in find_files(".", ignore_patterns, verbosity, 
    326348                stdout, symlinks=symlinks): 
    327349            process_file(file, dirpath, potfile, domain, verbosity, extensions, 
    328                     wrap, location, stdout) 
     350                    wrap, location, stdout, extra_keywords) 
    329351 
    330352        if os.path.exists(potfile): 
    331353            write_po_file(pofile, potfile, domain, locale, verbosity, stdout, 
    class Command(NoArgsCommand): 
    355377            default=False, help="Don't write '#: filename:line' lines"), 
    356378        make_option('--no-obsolete', action='store_true', dest='no_obsolete', 
    357379            default=False, help="Remove obsolete message strings"), 
     380        make_option('--extra-keyword', dest='extra_keywords', 
     381                    help='If you use import aliases for ugettext and its variations, ' 
     382                    'you can specify it here to make sure that xgettext will find ' 
     383                    'your translatable strings.', 
     384                    action='append') 
    358385    ) 
    359386    help = ("Runs over the entire source tree of the current directory and " 
    360387"pulls out all strings marked for translation. It creates (or updates) a message " 
    class Command(NoArgsCommand): 
    379406        no_wrap = options.get('no_wrap') 
    380407        no_location = options.get('no_location') 
    381408        no_obsolete = options.get('no_obsolete') 
     409        extra_keywords = options.get('extra_keywords') 
    382410        if domain == 'djangojs': 
    383411            exts = extensions if extensions else ['js'] 
    384412        else: 
    class Command(NoArgsCommand): 
    390418                             % get_text_list(list(extensions), 'and')) 
    391419 
    392420        make_messages(locale, domain, verbosity, process_all, extensions, 
    393             symlinks, ignore_patterns, no_wrap, no_location, no_obsolete, self.stdout) 
     421            symlinks, ignore_patterns, no_wrap, no_location, no_obsolete, 
     422            self.stdout, extra_keywords) 
  • docs/man/django-admin.1

    diff --git a/docs/man/django-admin.1 b/docs/man/django-admin.1
    index 4d937b4..7e9200c 100644
    a b Executes 
    6060.B sqlall 
    6161for the given app(s) in the current database. 
    6262.TP 
    63 .BI "makemessages [" "\-\-locale=LOCALE" "] [" "\-\-domain=DOMAIN" "] [" "\-\-extension=EXTENSION" "] [" "\-\-all" "] [" "\-\-symlinks" "] [" "\-\-ignore=PATTERN" "] [" "\-\-no\-default\-ignore" "] [" "\-\-no\-wrap" "] [" "\-\-no\-location" "]" 
     63.BI "makemessages [" "\-\-locale=LOCALE" "] [" "\-\-domain=DOMAIN" "] [" "\-\-extension=EXTENSION" "] [" "\-\-all" "] [" "\-\-symlinks" "] [" "\-\-ignore=PATTERN" "] [" "\-\-no\-default\-ignore" "] [" "\-\-no\-wrap" "] [" "\-\-no\-location" "] [" "\-\-extra-keyword=KEYWORD" "]" 
    6464Runs over the entire source tree of the current directory and pulls out all 
    6565strings marked for translation. It creates (or updates) a message file in the 
    6666conf/locale (in the django tree) or locale (for project and application) directory. 
  • docs/ref/django-admin.txt

    diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
    index d471b59..70a748d 100644
    a b Use the ``--no-location`` option to not write '``#: filename:line``' 
    474474comment lines in language files. Note that using this option makes it harder 
    475475for technically skilled translators to understand each message's context. 
    476476 
     477.. django-admin-option:: --extra-keyword 
     478 
     479.. versionadded:: 1.6 
     480 
     481When you import the ``ugettext`` and ``ugettext_lazy`` functions as aliases, 
     482``makemessages`` may not find translatable strings in your python source code. 
     483With the ``--extra-keyword`` option, you can force it to look for other aliases 
     484you may choose. 
     485 
     486Example usage: 
     487 
     488If you want ``makemessages`` to find translatable strings in the following 
     489python code. 
     490 
     491.. code-block:: python 
     492 
     493   from django.utils.translation import ugettext as tr, ugettext_lazy as tr_lazy 
     494 
     495   tr('some translatable string') 
     496   tr_lazy('some lazy translatable string') 
     497 
     498You will need to add the option ``--extra-keyword`` twice:: 
     499 
     500    django-admin.py makemessages --locale=fr_FR --extra-keyword=tr --extra-keyword=tr_lazy 
     501 
     502.. note:: The default alias ``'_'`` will allways be detected by ``makemessages``  
     503   whether you use the ``--extra-keyword`` option or not. 
     504 
     505 
    477506runfcgi [options] 
    478507----------------- 
    479508 
  • tests/regressiontests/i18n/commands/extraction.py

    diff --git a/setup.py b/setup.py
    old mode 100644
    new mode 100755
    diff --git a/tests/regressiontests/i18n/commands/extraction.py b/tests/regressiontests/i18n/commands/extraction.py
    index aa5efe1..61720f5 100644
    a b class NoLocationExtractorTests(ExtractorTests): 
    293293        with open(self.PO_FILE, 'r') as fp: 
    294294            po_contents = force_text(fp.read()) 
    295295            self.assertTrue('#: templates/test.html:55' in po_contents) 
     296 
     297 
     298class UgettextAliasesTests(ExtractorTests): 
     299 
     300    def test_missing_keyword(self): 
     301        os.chdir(self.test_dir) 
     302        shutil.copyfile('./ugettext-aliases.sample', './ugettext_aliases.py') 
     303        management.call_command('makemessages', locale=LOCALE, verbosity=0) 
     304        self.assertTrue(os.path.exists(self.PO_FILE)) 
     305        with open(self.PO_FILE, 'r') as fp: 
     306            po_contents = force_text(fp.read()) 
     307            self.assertNotMsgId('Should be found only with the --extra-keyword option', po_contents) 
     308            self.assertNotMsgId('Lazy, should be found only with the --extra-keyword option', po_contents) 
     309        os.remove('./ugettext_aliases.py') 
     310 
     311    def test_added_keywords(self): 
     312        os.chdir(self.test_dir) 
     313        shutil.copyfile('./ugettext-aliases.sample', './ugettext_aliases.py') 
     314        management.call_command('makemessages', locale=LOCALE, verbosity=0, extra_keywords=['tr', 'tr_lazy']) 
     315        self.assertTrue(os.path.exists(self.PO_FILE)) 
     316        with open(self.PO_FILE, 'r') as fp: 
     317            po_contents = force_text(fp.read()) 
     318            self.assertMsgId('Should be found only with the --extra-keyword option', po_contents) 
     319            self.assertMsgId('Lazy, should be found only with the --extra-keyword option', po_contents) 
     320        os.remove('./ugettext_aliases.py') 
     321 
  • tests/regressiontests/i18n/tests.py

    diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
    index d8af6f1..28dd4e7 100644
    a b if can_run_extraction_tests: 
    3232    from .commands.extraction import (ExtractorTests, BasicExtractorTests, 
    3333        JavascriptExtractorTests, IgnoredExtractorTests, SymlinkExtractorTests, 
    3434        CopyPluralFormsExtractorTests, NoWrapExtractorTests, 
    35         NoLocationExtractorTests) 
     35        NoLocationExtractorTests, UgettextAliasesTests) 
    3636if can_run_compilation_tests: 
    3737    from .commands.compilation import (PoFileTests, PoFileContentsTests, 
    3838        PercentRenderingTests)