Skip to content

Commit 7ce73f2

Browse files
authored
Merge branch 'main' into django-5.2
2 parents fa78a8a + ed5906c commit 7ce73f2

7 files changed

Lines changed: 59 additions & 7 deletions

File tree

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# Notify @EWDurbin for all opened Issues and Pull Requests
2-
* @EWDurbin @JacobCoffee
2+
* @JacobCoffee

downloads/templatetags/download_tags.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from django import template
66
from django.core.cache import cache
77
from django.utils.html import format_html
8+
from django.utils.safestring import mark_safe
89

910
from downloads.models import Release
1011

@@ -90,6 +91,31 @@ def has_sha256(files):
9091
return any(f.sha256_sum for f in files)
9192

9293

94+
@register.filter
95+
def wbr_wrap(value: str | None) -> str:
96+
"""
97+
Insert <wbr> tags for optional line breaking, prioritising halfway break.
98+
99+
Uses inline-block spans for halves so the browser prefers breaking
100+
at the midpoint first, then within each half if still too wide.
101+
"""
102+
if not value:
103+
return value or ""
104+
105+
interval = 16
106+
chunks = [value[i : i + interval] for i in range(0, len(value), interval)]
107+
108+
# Split into two halves, each half has internal <wbr> breaks
109+
midpoint = len(chunks) // 2
110+
first_half = "<wbr>".join(chunks[:midpoint])
111+
second_half = "<wbr>".join(chunks[midpoint:])
112+
113+
return mark_safe(
114+
f'<span class="checksum-half">{first_half}</span><wbr>'
115+
f'<span class="checksum-half">{second_half}</span>'
116+
)
117+
118+
93119
@register.filter
94120
def sort_windows(files):
95121
if not files:

pydotorg/context_processors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def url_name(request):
1010
try:
1111
match = resolve(request.path)
1212
except Resolver404:
13-
return {}
13+
return {'URL_NAMESPACE': None, 'URL_NAME': None}
1414
else:
1515
namespace, url_name_ = match.namespace, match.url_name
1616
if namespace:

pydotorg/tests/test_context_processors.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ def test_url_name(self):
1919
self.assertEqual({'URL_NAMESPACE': 'events', 'URL_NAME': 'events:calendar_list'}, context_processors.url_name(request))
2020

2121
request = self.factory.get('/getit-404/releases/3.3.3/not-an-actual-thing/')
22-
self.assertEqual({}, context_processors.url_name(request))
22+
self.assertEqual({'URL_NAMESPACE': None, 'URL_NAME': None}, context_processors.url_name(request))
2323

2424
request = self.factory.get('/getit-404/releases/3.3.3/\r\n/')
25-
self.assertEqual({}, context_processors.url_name(request))
25+
self.assertEqual({'URL_NAMESPACE': None, 'URL_NAME': None}, context_processors.url_name(request))
2626

2727
request = self.factory.get('/nothing/here/')
28-
self.assertEqual({}, context_processors.url_name(request))
28+
self.assertEqual({'URL_NAMESPACE': None, 'URL_NAME': None}, context_processors.url_name(request))
2929

3030
def test_blog_url(self):
3131
request = self.factory.get('/about/')
@@ -114,3 +114,18 @@ def test_user_nav_bar_links_for_anonymous_user(self):
114114
request.user = AnonymousUser()
115115

116116
self.assertEqual({"USER_NAV_BAR": {}}, context_processors.user_nav_bar_links(request))
117+
118+
def test_url_name_always_returns_keys(self):
119+
# Ensure URL_NAME and URL_NAMESPACE are always present in context, even for 404s,
120+
# otherwise it makes sentry unhappy: https://python-software-foundation.sentry.io/issues/6931306293/
121+
# test with a 404 path
122+
request = self.factory.get('/this-does-not-exist/')
123+
result = context_processors.url_name(request)
124+
125+
# keys should always be present
126+
self.assertIn('URL_NAME', result)
127+
self.assertIn('URL_NAMESPACE', result)
128+
129+
# values should be None for unresolved URLs
130+
self.assertIsNone(result['URL_NAME'])
131+
self.assertIsNone(result['URL_NAMESPACE'])

static/sass/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,10 @@ table th, table td {
18991899
border-left: none; }
19001900
table tfoot {
19011901
border-top: 1px solid #dddddd; }
1902+
table .checksum {
1903+
font-size: 0.85em; }
1904+
table .checksum .checksum-half {
1905+
display: inline-block; }
19021906

19031907
.row-title {
19041908
border-top: 5px solid #d4dbe1;

static/sass/style.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,12 @@ table {
10121012
}
10131013

10141014
tfoot { border-top: 1px solid $grey-lighterer; }
1015+
1016+
.checksum {
1017+
font-size: 0.85em;
1018+
1019+
.checksum-half { display: inline-block; }
1020+
}
10151021
}
10161022

10171023
.documentation-help { }

templates/downloads/release_detail.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
{% load has_sha256 from download_tags %}
99
{% load sort_windows from download_tags %}
1010
{% load get_eol_info from download_tags %}
11+
{% load wbr_wrap from download_tags %}
1112

1213
{% block body_attributes %}class="python downloads"{% endblock %}
1314

@@ -126,9 +127,9 @@ <h3>{{ f.os.name }}</h3>
126127
<td>{% if f.gpg_signature_file %}<a href="{{ f.gpg_signature_file }}">SIG</a>{% endif %}</td>
127128
{% endif %}
128129
{% if release_files|has_sha256 %}
129-
<td>{{ f.sha256_sum }}</td>
130+
<td><code class="checksum">{{ f.sha256_sum|wbr_wrap }}</code></td>
130131
{% elif release_files|has_md5 %}
131-
<td>{{ f.md5_sum }}</td>
132+
<td><code class="checksum">{{ f.md5_sum|wbr_wrap }}</code></td>
132133
{% endif %}
133134
</tr>
134135
{% endfor %}

0 commit comments

Comments
 (0)