Skip to content

Commit 9adc205

Browse files
JulienPalardnessita
andcommitted
Refs #28877 -- Added special ordinal context when humanizing value 1.
Some languages use a different ordinal suffix for the number 1 than for other values ending in 1 (e.g. 21, 31). Added a dedicated pgettext context "ordinal is 1" to allow translators to handle this distinction. For example, in French, 1 is written as "1er" while 21, 31, etc. use "21e", "31e", etc. Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
1 parent 23931eb commit 9adc205

4 files changed

Lines changed: 86 additions & 3 deletions

File tree

django/contrib/humanize/templatetags/humanize.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ def ordinal(value):
3232
return value
3333
if value < 0:
3434
return str(value)
35-
if value % 100 in (11, 12, 13):
35+
if value == 1:
36+
# Translators: Ordinal format when value is 1 (1st).
37+
value = pgettext("ordinal is 1", "{}st").format(value)
38+
elif value % 100 in (11, 12, 13):
3639
# Translators: Ordinal format for 11 (11th), 12 (12th), and 13 (13th).
3740
value = pgettext("ordinal 11, 12, 13", "{}th").format(value)
3841
else:
806 Bytes
Binary file not shown.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Test-only French translations for humanize ordinal filter.
2+
msgid ""
3+
msgstr ""
4+
"Content-Type: text/plain; charset=UTF-8\n"
5+
"Content-Transfer-Encoding: 8bit\n"
6+
"Language: fr\n"
7+
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
8+
9+
msgid "Humanize"
10+
msgstr "Humanisation"
11+
12+
#. Translators: Ordinal format when value is 1 (1st).
13+
#: contrib/humanize/templatetags/humanize.py:37
14+
#, fuzzy
15+
#| msgctxt "ordinal 1"
16+
#| msgid "{}st"
17+
msgctxt "ordinal is 1"
18+
msgid "{}st"
19+
msgstr "{}<sup>er</sup>"
20+
21+
#. Translators: Ordinal format for 11 (11th), 12 (12th), and 13 (13th).
22+
msgctxt "ordinal 11, 12, 13"
23+
msgid "{}th"
24+
msgstr "{}<sup>e</sup>"
25+
26+
#. Translators: Ordinal format when value ends with 0, e.g. 80th.
27+
msgctxt "ordinal 0"
28+
msgid "{}th"
29+
msgstr "{}<sup>e</sup>"
30+
31+
#. Translators: Ordinal format when value ends with 1, e.g. 81st, except 11.
32+
msgctxt "ordinal 1"
33+
msgid "{}st"
34+
msgstr "{}<sup>e</sup>"
35+
36+
#. Translators: Ordinal format when value ends with 2, e.g. 82nd, except 12.
37+
msgctxt "ordinal 2"
38+
msgid "{}nd"
39+
msgstr "{}<sup>e</sup>"
40+
41+
#. Translators: Ordinal format when value ends with 3, e.g. 83rd, except 13.
42+
msgctxt "ordinal 3"
43+
msgid "{}rd"
44+
msgstr "{}<sup>e</sup>"
45+
46+
#. Translators: Ordinal format when value ends with 4, e.g. 84th.
47+
msgctxt "ordinal 4"
48+
msgid "{}th"
49+
msgstr "{}<sup>e</sup>"
50+
51+
#. Translators: Ordinal format when value ends with 5, e.g. 85th.
52+
msgctxt "ordinal 5"
53+
msgid "{}th"
54+
msgstr "{}<sup>e</sup>"
55+
56+
#. Translators: Ordinal format when value ends with 6, e.g. 86th.
57+
msgctxt "ordinal 6"
58+
msgid "{}th"
59+
msgstr "{}<sup>e</sup>"
60+
61+
#. Translators: Ordinal format when value ends with 7, e.g. 87th.
62+
msgctxt "ordinal 7"
63+
msgid "{}th"
64+
msgstr "{}<sup>e</sup>"
65+
66+
#. Translators: Ordinal format when value ends with 8, e.g. 88th.
67+
msgctxt "ordinal 8"
68+
msgid "{}th"
69+
msgstr "{}<sup>e</sup>"
70+
71+
#. Translators: Ordinal format when value ends with 9, e.g. 89th.
72+
msgctxt "ordinal 9"
73+
msgid "{}th"
74+
msgstr "{}<sup>e</sup>"

tests/humanize_tests/tests.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import datetime
2+
import os
23
from decimal import Decimal
34

45
from django.contrib.humanize.templatetags import humanize
@@ -9,10 +10,10 @@
910
from django.utils.timezone import get_fixed_timezone
1011
from django.utils.translation import gettext as _
1112

13+
here = os.path.dirname(os.path.abspath(__file__))
1214
# Mock out datetime in some tests so they don't fail occasionally when they
1315
# run too slow. Use a fixed datetime for datetime.now(). DST change in
1416
# America/Chicago (the default time zone) happened on March 11th in 2012.
15-
1617
now = datetime.datetime(2012, 3, 9, 22, 30)
1718

1819

@@ -83,6 +84,7 @@ def test_ordinal(self):
8384
with translation.override("en"):
8485
self.humanize_tester(test_list, result_list, "ordinal")
8586

87+
@override_settings(LOCALE_PATHS=[os.path.join(here, "locale")])
8688
def test_i18n_html_ordinal(self):
8789
"""Allow html in output on i18n strings"""
8890
test_list = (
@@ -93,6 +95,8 @@ def test_i18n_html_ordinal(self):
9395
"11",
9496
"12",
9597
"13",
98+
"21",
99+
"31",
96100
"101",
97101
"102",
98102
"103",
@@ -108,7 +112,9 @@ def test_i18n_html_ordinal(self):
108112
"11<sup>e</sup>",
109113
"12<sup>e</sup>",
110114
"13<sup>e</sup>",
111-
"101<sup>er</sup>",
115+
"21<sup>e</sup>",
116+
"31<sup>e</sup>",
117+
"101<sup>e</sup>",
112118
"102<sup>e</sup>",
113119
"103<sup>e</sup>",
114120
"111<sup>e</sup>",

0 commit comments

Comments
 (0)