Ticket #14844: 14844-1-wip.diff

File 14844-1-wip.diff, 7.0 KB (added by ramiro, 3 years ago)

work-in-progress patch implementing the proposed syntax

  • django/templatetags/i18n.py

    diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py
    a b  
    9696
    9797class BlockTranslateNode(Node):
    9898    def __init__(self, extra_context, singular, plural=None, countervar=None,
    99             counter=None, message_context=None):
     99            counter=None, message_context=None, plural_vname_var=None, plural_vname=None):
    100100        self.extra_context = extra_context
    101101        self.singular = singular
    102102        self.plural = plural
    103103        self.countervar = countervar
    104104        self.counter = counter
    105105        self.message_context = message_context
     106        self.plural_vname_var = plural_vname_var
     107        self.plural_vname = plural_vname
    106108
    107109    def render_token_list(self, tokens):
    108110        result = []
     
    129131        singular, vars = self.render_token_list(self.singular)
    130132        # Escape all isolated '%'
    131133        singular = re.sub(u'%(?!\()', u'%%', singular)
     134        count, plural_vname = None, None
    132135        if self.plural and self.countervar and self.counter:
    133136            count = self.counter.resolve(context)
    134137            context[self.countervar] = count
     138            if self.plural_vname_var is not None and self.plural_vname is not None:
     139                plural_vname = self.plural_vname.resolve(context)
    135140            plural, plural_vars = self.render_token_list(self.plural)
    136141            plural = re.sub(u'%(?!\()', u'%%', plural)
    137142            if message_context:
     
    145150                result = translation.pgettext(message_context, singular)
    146151            else:
    147152                result = translation.ugettext(singular)
     153        if count not in (1, None) and plural_vname is not None: # TODO: Hardcoding 1 isn't right
     154            #print 'setting context["%s"] = "%s" to render "%s"' % (self.plural_vname_var, plural_vname, result)
     155            context[self.plural_vname_var] = plural_vname
    148156        data = dict([(v, _render_value_in_context(context.get(v, ''), context)) for v in vars])
    149157        context.pop()
    150158        try:
     
    432440    else:
    433441        message_context = None
    434442    extra_context = options.get('with', {})
     443    plural_vname_var, plural_vname = None, None
    435444
    436445    singular = []
    437446    plural = []
     
    442451        else:
    443452            break
    444453    if countervar and counter:
    445         if token.contents.strip() != 'plural':
    446             raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags inside it")
     454        if not token.contents.lstrip().startswith('plural'):
     455            raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags inside it (%s)" % token.contents.strip())
     456        else:
     457            poptions = {}
     458            bits = token.split_contents()
     459            remaining_bits = bits[1:]
     460            while remaining_bits:
     461                option = remaining_bits.pop(0)
     462                if option in poptions:
     463                    raise TemplateSyntaxError('The %r option was specified more '
     464                                            'than once.' % option)
     465                if option == 'with':
     466                    pvalue = token_kwargs(remaining_bits, parser, support_legacy=False)
     467                    if len(pvalue) != 1:
     468                        raise TemplateSyntaxError('"with" in %r section of blocktrans tag accepts only '
     469                                                'one keyword argument.' % bits[0])
     470                    if pvalue.keys()[0] not in options['with']:
     471                        raise TemplateSyntaxError(
     472                            'blocktrans: Pluralized verbose name variable '
     473                            'specified in plural section should have the same '
     474                            'name as the one in the singular section')
     475                else:
     476                    raise TemplateSyntaxError('Unknown argument for %r tag: %r.' %
     477                                            (bits[0], option))
     478                poptions[option] = pvalue
     479            plural_vname = poptions.get('with')
     480            if 'with' in poptions:
     481                plural_vname_var, plural_vname = poptions['with'].items()[0]
    447482        while parser.tokens:
    448483            token = parser.next_token()
    449484            if token.token_type in (TOKEN_VAR, TOKEN_TEXT):
     
    454489        raise TemplateSyntaxError("'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents)
    455490
    456491    return BlockTranslateNode(extra_context, singular, plural, countervar,
    457             counter, message_context)
     492            counter, message_context, plural_vname_var, plural_vname)
    458493
    459494@register.tag
    460495def language(parser, token):
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    a b  
    13051305            'i18n36': ('{% load i18n %}{% trans "Page not found" as page_not_found noop %}{{ page_not_found }}', {'LANGUAGE_CODE': 'de'}, "Page not found"),
    13061306            'i18n37': ('{% load i18n %}{% trans "Page not found" as page_not_found %}{% blocktrans %}Error: {{ page_not_found }}{% endblocktrans %}', {'LANGUAGE_CODE': 'de'}, "Error: Seite nicht gefunden"),
    13071307
     1308            # New in 1.4: When the plural form functionality is used with a
     1309            # count variable, the plural inner tag can specify one var binding
     1310            # that overrides a similarly named one declared in the main tag body
     1311            'i18n38': ('{% load i18n %}{% blocktrans with name=singular_name count counter=number %}singular: {{ counter }} {{ name }}{% plural with name=plural_name %}plural: {{ counter }} {{ name }}{% endblocktrans %}', {'number': 1, 'singular_name': 'pony', 'plural_name': 'ponies'}, u"singular: 1 pony"),
     1312            'i18n39': ('{% load i18n %}{% blocktrans with name=singular_name count counter=number %}singular: {{ counter }} {{ name }}{% plural with name=plural_name %}plural: {{ counter }} {{ name }}{% endblocktrans %}', {'number': 2, 'singular_name': 'pony', 'plural_name': 'ponies'}, u"plural: 2 ponies"),
     1313            'i18n40': ('{% load i18n %}{% blocktrans with name=singular_name count counter=number %}singular: {{ counter }} {{ name }}{% plural with name=plural_name foo="bar" %}plural: {{ counter }} {{ name }}{% endblocktrans %}', {'number': 2, 'singular_name': 'pony', 'plural_name': 'ponies'}, template.TemplateSyntaxError),
     1314            'i18n41': ('{% load i18n %}{% blocktrans with name=singular_name %}singular: {{ counter }} {{ name }}{% plural with name=plural_name %}plural: {{ counter }} {{ name }}{% endblocktrans %}', {'number': 2, 'singular_name': 'pony', 'plural_name': 'ponies'}, template.TemplateSyntaxError),
     1315            'i18n42': ('{% load i18n %}{% blocktrans with name=singular_name count counter=number %}singular: {{ counter }} {{ name}}{% plural foo %}plural: {{ counter }} {{ name }}{% endblocktrans %}', {'number': 2, 'singular_name': 'pony'}, template.TemplateSyntaxError),
     1316
    13081317            ### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
    13091318
    13101319            'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),
Back to Top