Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#33318 closed Bug (invalid)

Truncator class recognizes different length of ellipsis(...) depending on the LANGUAGE_CODE.

Reported by: YoungJoo Kim Owned by: nobody
Component: Internationalization Version: 3.2
Severity: Normal Keywords: truncatechars Truncator ellipsis LANGUAGE_CODE
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by YoungJoo Kim)

There is something strange about the truncatechars method of Django Template Language (DTL).
In the add_truncation_text method of the Truncator class, the length of the truncate variable depends on the value of LANGUAGE_CODE(ex. 'en-us', 'ko-kr' ...) in settings.py


The add_truncation_text method of the Truncator class is as follows.

# django/utils/text.py

def add_truncation_text(self, text, truncate=None):
    if truncate is None:
        truncate = pgettext(
            'String to return when truncating text',
            '%(truncated_text)s…')
    if '%(truncated_text)s' in truncate:
        return truncate % {'truncated_text': text}
    # The truncation text didn't contain the %(truncated_text)s string
    # replacement argument so just append it to the text.
    if text.endswith(truncate):
        # But don't append the truncation text if the current text already
        # ends in this.
        return text
    return '%s%s' % (text, truncate)

The truncate variable is assigned the string '%(truncated_text)s…' by the pgettext method.

In LANGUAGE_CODE 'en-us'(default), ellipsis is recognized as a string of length 1.
But in LANGUAGE_CODE 'ko-kr', ellipsis is recognized as three dots(...) and has length 3.

I think that the pgettext method is the cause.


So even though it is the same code, the output is different depending on the language.

In the chars method of the same Truncator class, the number of strings to print ellipsis from is calculated through the for statement.

The number of times this for loop is determined by the return value (== truncate variable) of the add_truncation_text method.

# django/utils/text.py

def chars(self, num, truncate=None, html=False):
    """
    Return the text truncated to be no longer than the specified number
    of characters.

    `truncate` specifies what should be used to notify that the string has
    been truncated, defaulting to a translatable string of an ellipsis.
    """
    self._setup()
    length = int(num)
    text = unicodedata.normalize('NFC', self._wrapped)

    # Calculate the length to truncate to (max length - end_text length)
    truncate_len = length
    for char in self.add_truncation_text('', truncate):
        if not unicodedata.combining(char):
            truncate_len -= 1
            if truncate_len == 0:
                break
    if html:
        return self._truncate_html(length, truncate, text, truncate_len, False)
    return self._text_chars(length, truncate, text, truncate_len)


In conclusion, output of the truncatechars method in HTML is as follows.
<p>{{ fruit|truncatechars:6 }}</p>

  1. LANGUAGE_CODE = 'en-us' (default)
    straw...
    pinea...
    
  2. LANGUAGE_CODE = 'ko-kr'
    str...
    pin...
    


Even if the language is different, the ellipsis should be recognized same as a string of length 1.

Users from other countries may misunderstand the functionality of the truncatechars method.

Thank you!

Change History (3)

comment:1 by Mariusz Felisiak, 2 years ago

Component: Template systemInternationalization
Resolution: invalid
Status: newclosed
Summary: Truncator class recognizes different length of ellipsis(...) depending on the LANGUAGE_CODE (ex. en-us, ko-kr...)Truncator class recognizes different length of ellipsis(...) depending on the LANGUAGE_CODE.

Thanks for the report, however it's an issue in translations that are handled at Transifex and not in this tracker.

I found "..." instead of ellipsis in ar, lt, fa, sr, ca, pt_BR, ml, tk, es, ko, lv, and ky translations.

comment:2 by Mariusz Felisiak, 2 years ago

I fixed this at Transifex.

comment:3 by YoungJoo Kim, 2 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top