Skip to content

Commit 08b136a

Browse files
Truncate author lists using model method (#2552)
## Summary Replaces CSS-based author truncation with a model method approach for more reliable and consistent behavior. - Adds `display_authors(max_authors=3)` method to project metadata mixin - Shows first 3 authors followed by "et al." when there are more - Simplifies templates to use `{{ published_project.display_authors }}` - Includes unit tests for the new method ## Why The previous CSS approach (`line-clamp`, `flex-grow`) had layout issues where `flex-grow: 1` from parent rules caused overflow. A model-based approach gives predictable output regardless of CSS context. ## Test plan - [x] Unit tests pass (`python manage.py test project.test_views.TestDisplayAuthors`) - [x] Verified locally on homepage and search results
2 parents 0eca1ad + 7f49e41 commit 08b136a

File tree

5 files changed

+48
-15
lines changed

5 files changed

+48
-15
lines changed

physionet-django/project/modelcomponents/metadata.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,15 @@ def author_list(self):
115115
"""
116116
return self.authors.all().order_by('display_order')
117117

118+
def display_authors(self, max_authors=3):
119+
"""
120+
Get a truncated display string of author names.
121+
Shows up to max_authors names, with 'et al.' if there are more.
122+
"""
123+
authors = list(self.authors.all().order_by('display_order'))
124+
names = ', '.join(a.get_full_name() for a in authors[:max_authors])
125+
return f'{names}, et al.' if len(authors) > max_authors else names
126+
118127
def get_author_info(self, separate_submitting=False, include_emails=False):
119128
"""
120129
Get the project's authors, setting information needed to display

physionet-django/project/test_views.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,3 +1576,38 @@ def tearDown(self):
15761576
self.credentialed_project.save()
15771577
self.open_project.georestricted = False
15781578
self.open_project.save()
1579+
1580+
1581+
class TestDisplayAuthors(TestMixin):
1582+
"""Test the display_authors method on projects."""
1583+
1584+
def test_display_authors_few(self):
1585+
"""Projects with 3 or fewer authors show all names."""
1586+
project = PublishedProject.objects.get(title='Demo ECG Signal Toolbox')
1587+
result = project.display_authors()
1588+
self.assertNotIn('et al.', result)
1589+
# Should contain all author names
1590+
for author in project.authors.all():
1591+
self.assertIn(author.get_full_name(), result)
1592+
1593+
def test_display_authors_many(self):
1594+
"""Projects with more than 3 authors show truncated list."""
1595+
project = PublishedProject.objects.get(title='Demo eICU Collaborative Research Database')
1596+
# This project should have many authors from the fixture
1597+
if project.authors.count() > 3:
1598+
result = project.display_authors()
1599+
self.assertIn('et al.', result)
1600+
# Should only contain first 3 author names
1601+
authors = list(project.authors.all().order_by('display_order'))
1602+
for author in authors[:3]:
1603+
self.assertIn(author.get_full_name(), result)
1604+
1605+
def test_display_authors_custom_max(self):
1606+
"""Test custom max_authors parameter."""
1607+
project = PublishedProject.objects.get(title='Demo eICU Collaborative Research Database')
1608+
if project.authors.count() > 1:
1609+
result = project.display_authors(max_authors=1)
1610+
authors = list(project.authors.all().order_by('display_order'))
1611+
self.assertIn(authors[0].get_full_name(), result)
1612+
if project.authors.count() > 1:
1613+
self.assertIn('et al.', result)

physionet-django/search/templates/search/content_list.html

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77
</p>
88
<{% firstof content_list_header 'h2' %}><a href="{% url 'published_project' published_project.slug published_project.version %}">{{ published_project.title }}</a></{% firstof content_list_header 'h2' %}>
99
{% if not published_project.is_legacy %}
10-
<p class="text-muted card-authors">
11-
{% for author in published_project.author_list %}
12-
{{ author.get_full_name }}{% if not forloop.last %}, {% endif %}
13-
{% endfor %}
14-
</p>
10+
<p class="text-muted card-authors">{{ published_project.display_authors }}</p>
1511
{% endif %}
1612
<div style="margin-bottom: 1rem;">
1713
{% if not published_project.short_description %}

physionet-django/search/templates/search/homepage_content_list.html

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,7 @@ <h3 class="card-title">
1212
</a>
1313
</h3>
1414
{% if not published_project.is_legacy %}
15-
<p class="card-authors">
16-
{% for author in published_project.author_list %}
17-
{{ author.get_full_name }}{% if not forloop.last %}, {% endif %}
18-
{% endfor %}
19-
</p>
15+
<p class="card-authors">{{ published_project.display_authors }}</p>
2016
{% endif %}
2117

2218
{% if not published_project.short_description %}

physionet-django/static/custom/css/style.css

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,9 @@ body .main {
241241
color: var(--gray-color);
242242
}
243243
.card-authors {
244-
display: -webkit-box;
245-
-webkit-line-clamp: 1;
246-
-webkit-box-orient: vertical;
247244
overflow: hidden;
248-
flex-grow: 0;
249-
flex-shrink: 0;
245+
text-overflow: ellipsis;
246+
white-space: nowrap;
250247
}
251248
.modern-ui .card-authors {
252249
font-size: 0.875rem;

0 commit comments

Comments
 (0)