Skip to content

Commit 5f26989

Browse files
authored
Merge pull request #547 from davep/aria-dates
Add aria-label to date-based archive links
2 parents caf064c + 75232dd commit 5f26989

5 files changed

Lines changed: 33 additions & 13 deletions

File tree

ChangeLog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
- Added an alternative relatedness graph view to the graph page when the
1111
related posts feature (`with_related`) is enabled.
1212
([#546](https://github.com/davep/blogmore/pull/546))
13+
- Added `aria-label` attributes to year, month, and day archive links in the
14+
archive list pages and calendar templates to improve accessibility for
15+
screen reader users by preventing identical link text (e.g. "05" or "May")
16+
with different destinations.
17+
([#547](https://github.com/davep/blogmore/pull/547))
1318

1419
## v2.30.0
1520

src/blogmore/renderer.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ def __init__(
8080
def _format_date(date: dt.datetime | None) -> Markup:
8181
"""Format a datetime object as HTML with archive links.
8282
83-
The date portion is rendered as
84-
`<a href="/{year}/">{year}</a>-<a href="/{year}/{mm}/">{mm}</a>-<a href="/{year}/{mm}/{dd}/">{dd}</a>`
85-
so each component links to the corresponding archive page.
83+
The date portion is rendered as separate links for the year, month, and day
84+
(separated by dashes), with each link containing an appropriate aria-label
85+
pointing to the corresponding archive page.
8686
8787
Args:
8888
date: The datetime to format.
@@ -97,9 +97,18 @@ def _format_date(date: dt.datetime | None) -> Markup:
9797
month = date.month
9898
day = date.day
9999

100-
year_link = Markup(f'<a href="/{year}/">{year}</a>')
101-
month_link = Markup(f'<a href="/{year}/{month:02d}/">{month:02d}</a>')
102-
day_link = Markup(f'<a href="/{year}/{month:02d}/{day:02d}/">{day:02d}</a>')
100+
year_label = f"Archive for {year}"
101+
month_name = date.strftime("%B")
102+
month_label = f"Archive for {month_name} {year}"
103+
day_label = f"Archive for {month_name} {day}, {year}"
104+
105+
year_link = Markup(f'<a href="/{year}/" aria-label="{year_label}">{year}</a>')
106+
month_link = Markup(
107+
f'<a href="/{year}/{month:02d}/" aria-label="{month_label}">{month:02d}</a>'
108+
)
109+
day_link = Markup(
110+
f'<a href="/{year}/{month:02d}/{day:02d}/" aria-label="{day_label}">{day:02d}</a>'
111+
)
103112

104113
time_str = date.strftime("%H:%M:%S")
105114
formatted = Markup(f"{year_link}-{month_link}-{day_link} {time_str}")

src/blogmore/templates/archive.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ <h1>Archive <span class="archive-post-count">({{ total_post_count }} {{ 'post' i
5454

5555
{% for year in ns.years.keys()|sort(reverse=True) %}
5656
<section class="archive-year" id="archive-{{ year }}">
57-
<h2><a href="/{{ year }}/{{ pagination_page1_suffix }}">{{ year }}</a> <span class="archive-post-count">({{ year_counts[year] }} {{ 'post' if year_counts[year] == 1 else 'posts' }})</span></h2>
57+
<h2><a href="/{{ year }}/{{ pagination_page1_suffix }}" aria-label="Archive for {{ year }}">{{ year }}</a> <span class="archive-post-count">({{ year_counts[year] }} {{ 'post' if year_counts[year] == 1 else 'posts' }})</span></h2>
5858

5959
{% for month_key in ns.years[year].keys()|sort(reverse=True) %}
6060
{% set month_count = ns.years[year][month_key]['posts']|length %}
6161
<section class="archive-month" id="archive-{{ year }}-{{ month_key }}">
62-
<h3><a href="/{{ year }}/{{ month_key }}/{{ pagination_page1_suffix }}">{{ ns.years[year][month_key]['name'] }}</a> <span class="archive-post-count">({{ month_count }} {{ 'post' if month_count == 1 else 'posts' }})</span></h3>
62+
<h3><a href="/{{ year }}/{{ month_key }}/{{ pagination_page1_suffix }}" aria-label="Archive for {{ ns.years[year][month_key]['name'] }} {{ year }}">{{ ns.years[year][month_key]['name'] }}</a> <span class="archive-post-count">({{ month_count }} {{ 'post' if month_count == 1 else 'posts' }})</span></h3>
6363

6464
<ul class="archive-post-list">
6565
{% for post in ns.years[year][month_key]['posts'] %}

src/blogmore/templates/calendar.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ <h1>Calendar</h1>
2222
<section class="calendar-year-section">
2323
<h2 class="calendar-year-label">
2424
{% if year_group.year_url %}
25-
<a href="{{ year_group.year_url }}">{{ year_group.year }}</a>
25+
<a href="{{ year_group.year_url }}" aria-label="Archive for {{ year_group.year }}">{{ year_group.year }}</a>
2626
{% else %}
2727
{{ year_group.year }}
2828
{% endif %}
@@ -33,7 +33,7 @@ <h2 class="calendar-year-label">
3333
<div class="calendar-month">
3434
<h3 class="calendar-month-label">
3535
{% if cal_month.month_url %}
36-
<a href="{{ cal_month.month_url }}">{{ cal_month.month_name }}</a>
36+
<a href="{{ cal_month.month_url }}" aria-label="Archive for {{ cal_month.month_name }} {{ year_group.year }}">{{ cal_month.month_name }}</a>
3737
{% else %}
3838
{{ cal_month.month_name }}
3939
{% endif %}

tests/test_renderer.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,15 @@ def test_format_date_links(self) -> None:
5959
"""Test that format_date produces archive links for year, month and day."""
6060
date = dt.datetime(2026, 2, 20, 15, 46, 0, tzinfo=dt.UTC)
6161
formatted = TemplateRenderer._format_date(date)
62-
assert '<a href="/2026/">2026</a>' in formatted
63-
assert '<a href="/2026/02/">02</a>' in formatted
64-
assert '<a href="/2026/02/20/">20</a>' in formatted
62+
assert '<a href="/2026/" aria-label="Archive for 2026">2026</a>' in formatted
63+
assert (
64+
'<a href="/2026/02/" aria-label="Archive for February 2026">02</a>'
65+
in formatted
66+
)
67+
assert (
68+
'<a href="/2026/02/20/" aria-label="Archive for February 20, 2026">20</a>'
69+
in formatted
70+
)
6571
assert "15:46:00" in formatted
6672
assert "UTC" in formatted
6773

0 commit comments

Comments
 (0)