Update events page#696
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the Events feature to support richer event metadata (location + external links) sourced from an expanded CSV schema, and adjusts navigation links accordingly.
Changes:
- Extend
data/events.csvschema and updateEventsPageViewto include location/event/blog fields and optional images. - Update the Events page template to render the new fields and handle missing images.
- Tweak navigation/footer links and add a new event image asset.
Reviewed changes
Copilot reviewed 5 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
main/views/page_views.py |
Reads new CSV columns into the Events context and sorts events by start date. |
main/templates/main/pages/events.html |
Renders new event fields (location/event/blog) and adds a “no image” placeholder. |
data/events.csv |
Replaces the old CSV layout with a new header + enriched event records. |
main/templates/main/snippets/navbar.html |
Updates the Framework dropdown label for the roles page. |
main/templates/main/snippets/footer.html |
Adds a Framework “Overview” link in the footer. |
main/static/assets/img/events/DisCouRSE -team-culture.jpg |
Adds a new event image asset. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| RSECon25,2025-09-09,2025-09-11,"Oculus, University of Warwick",Workshop for user experience testing the web app visualisations and profiles,https://rsecon25.society-rse.org/,,"Dave Horsfall, Adrian D’Alessandro, Aman Goel, Aleksandra Nenadic, Phil Reed, Emma Hogan, Muhammad Salihu, Gabriel Hanganu", | ||
| "Satellite Training Community Day, RSECon25",2025-09-12,2025-09-12,"Oculus, University of Warwick",Workshop for capturing and mapping training and learning opportunities,https://rsecon25.society-rse.org/training-community-day/,,"Dave Horsfall, Toby Hodges, Weronika Filinger, Phil Reed, Samantha Ahern, Jonathan Cooper, Aman Goel", | ||
| Careers and Skills for Data-driven Research (CaSDaR) Hybrid Event Launch,2025-09-18,2025-09-18,"Library of Birmingham, England",Lightning talk at the launch of Careers and Skills for Data-driven Research (CaSDaR),https://www.eventbrite.com/e/careers-and-skills-for-data-driven-research-casdar-hybrid-event-launch-tickets-1496323607189,https://www.software.ac.uk/blog/casdar-professionalisation-data-stewardship-roles-uk,Phil Reed,assets/img/events/CaSDaR-launch.png | ||
| DisCouRSE Focus Group: Team Culture and Leadership in dRTP contexts,2026-01-19,2026-01-19,King's College London,,https://discourse-network.github.io/events/202601-focus-group-culture/,,Dave Horsfall,assets/img/events/DisCouRSE -team-culture.jpg |
There was a problem hiding this comment.
This image filename contains a space (DisCouRSE -team-culture.jpg), which is inconsistent with the other event image filenames in main/static/assets/img/events and can lead to awkward/invalid URLs in static() output. Consider renaming the file to a URL-safe name (e.g., use hyphens/underscores only) and update this CSV path accordingly.
| DisCouRSE Focus Group: Team Culture and Leadership in dRTP contexts,2026-01-19,2026-01-19,King's College London,,https://discourse-network.github.io/events/202601-focus-group-culture/,,Dave Horsfall,assets/img/events/DisCouRSE -team-culture.jpg | |
| DisCouRSE Focus Group: Team Culture and Leadership in dRTP contexts,2026-01-19,2026-01-19,King's College London,,https://discourse-network.github.io/events/202601-focus-group-culture/,,Dave Horsfall,assets/img/events/DisCouRSE-team-culture.jpg |
| </li> | ||
| <li> | ||
| <a class="dropdown-item" href="{% url 'roles' %}">Roles and job profiles</a> | ||
| <a class="dropdown-item" href="{% url 'roles' %}">Roles & career pathways</a> |
There was a problem hiding this comment.
The navbar label change to “Roles & career pathways” will break the existing navbar test assertion that looks for the “Roles and job profiles” link text (see tests/main/test_main_views.py:84-86). Either update the test expectation (and any other references) or keep the previous label to avoid CI failures.
| <a class="dropdown-item" href="{% url 'roles' %}">Roles & career pathways</a> | |
| <a class="dropdown-item" href="{% url 'roles' %}">Roles and job profiles</a> |
There was a problem hiding this comment.
Happy to change this title to "career pathways", but there has been an effort to remove & from things in the framework for accessibility reasons. So this should be an "and"
| <a class="dropdown-item" href="{% url 'roles' %}">Roles & career pathways</a> | |
| <a class="dropdown-item" href="{% url 'roles' %}">Roles and career pathways</a> |
(also, like copilot suggests, the test should be updated accordingly).
| <a href="{{ event.blog }}" target="_blank">{{ event.title }}</a> | ||
| {% else %} | ||
| {{ event.title }} | ||
| {% endif %} | ||
| </h4> | ||
| <p class="mb-2">{{ event.description }}</p> | ||
| <p class="text-muted mb-1 small"> | ||
| <strong>Date:</strong> {{ event.start_date }} | ||
| {% if event.end_date and event.end_date != event.start_date %}– {{ event.end_date }}{% endif %} | ||
| {% if event.location %}| {{ event.location }}{% endif %} | ||
| {% if event.event_link %}| <a href="{{ event.event_link }}" target="_blank">Event</a>{% endif %} | ||
| {% if event.blog %}| <a href="{{ event.blog }}" target="_blank">Blog</a>{% endif %} |
There was a problem hiding this comment.
Links opened with target="_blank" should include rel="noopener noreferrer" to prevent tabnabbing. This project already follows that pattern elsewhere (e.g., main/templates/main/pages/skill.html). Add the rel attribute to the event title link and the “Event”/“Blog” links here.
| </h4> | ||
| <p class="mb-2">{{ event.description }}</p> | ||
| <p class="text-muted mb-1 small"> | ||
| <strong>Date:</strong> {{ event.start_date }} |
There was a problem hiding this comment.
The template no longer displays an end date for multi-day events, even though the view still provides end_date and the CSV includes multi-day ranges (e.g., 2023-09-05 to 2023-09-08). Consider restoring the previous conditional end-date display so date ranges remain accurate.
| <strong>Date:</strong> {{ event.start_date }} | |
| <strong>Date:</strong> {{ event.start_date }} | |
| {% if event.end_date %} | |
| {% if event.end_date != event.start_date %}- {{ event.end_date }}{% endif %} | |
| {% endif %} |
| image_path = row.get("Image") | ||
| events.append( | ||
| { | ||
| "title": row.get("Title", ""), | ||
| "start_date": row.get("Start Date", ""), | ||
| "end_date": row.get("End Date", ""), | ||
| "location": row.get("Location", ""), | ||
| "event_link": row.get("Event Link", ""), | ||
| "blog": row.get("Blog", ""), | ||
| "description": row.get("Description", ""), | ||
| "contributors": row.get("Contributors", ""), | ||
| "image": static( | ||
| row.get("Image", "assets/img/blog/single/image.jpg") | ||
| ), | ||
| "image": static(image_path) if image_path else None, | ||
| } | ||
| ) | ||
|
|
||
| events.sort(key=lambda e: e["start_date"], reverse=True) | ||
| events.sort(key=lambda e: cast(str, e["start_date"]), reverse=True) | ||
|
|
There was a problem hiding this comment.
cast(str, e["start_date"]) only affects typing; it won’t prevent runtime failures if a row ever produces a non-string (e.g., None from csv.DictReader). It’d be safer to normalize CSV values to str when building each event dict (e.g., use row.get(...) or "" for start/end dates) so the sort key is guaranteed to be a string and the cast can be removed.
| @@ -125,20 +125,22 @@ def get_context_data(self, **kwargs: Mapping[str, Any]) -> dict[str, Any]: | |||
| with open(csv_path, newline="", encoding="utf-8") as csvfile: | |||
| reader = csv.DictReader(csvfile) | |||
| for row in reader: | |||
| image_path = row.get("Image") | |||
| events.append( | |||
| { | |||
| "title": row.get("Title", ""), | |||
| "start_date": row.get("Start Date", ""), | |||
| "end_date": row.get("End Date", ""), | |||
| "location": row.get("Location", ""), | |||
| "event_link": row.get("Event Link", ""), | |||
| "blog": row.get("Blog", ""), | |||
| "description": row.get("Description", ""), | |||
| "contributors": row.get("Contributors", ""), | |||
| "image": static( | |||
| row.get("Image", "assets/img/blog/single/image.jpg") | |||
| ), | |||
| "image": static(image_path) if image_path else None, | |||
| } | |||
| ) | |||
|
|
|||
| events.sort(key=lambda e: e["start_date"], reverse=True) | |||
| events.sort(key=lambda e: cast(str, e["start_date"]), reverse=True) | |||
|
|
|||
| context["events"] = events | |||
| return context | |||
There was a problem hiding this comment.
The current EventsPageView tests only assert that an events list exists, but they don’t validate the new fields (location, event_link, blog) or the missing-image behavior introduced here. Adding assertions for at least one row (including that empty image values don’t crash rendering) would help prevent regressions when the CSV schema evolves again.
anenadic
left a comment
There was a problem hiding this comment.
This is looking good to me, would nice to add slides we used at events and maybe other docs but this can also be added progressively.
AdrianDAlessandro
left a comment
There was a problem hiding this comment.
Overall, this is good. I still think that longer term this should be moved to the database, or pulled from a separate location, like how the governance and licensing pages have been done.
Again, some changes required to make tests pass, and some good suggestions from copilot to address
There was a problem hiding this comment.
Probably best to remove the space from this filename
| UK-Ireland Digital Humanities Association Event 2025,2025-06-17,2025-06-18,University of Glasgow,"Workshop for capturing a digital humanities voice in the framework, part of SSI Fellowship for Phil Reed",https://digitalhumanities-uk-ie.org/2025-annual-event/,https://www.software.ac.uk/blog/giving-digital-humanities-voice-skills-and-competencies-digital-research-professionals-dha,"Phil Reed, Dave Horsfall, Aleksandra Nenadic, Lucia Michielin, Anna-Maria Sichani", | ||
| "N8 CIR RSE Annual Meeting, July 2025",2025-07-10,2025-07-10,"The Bar Convent, York",Lightning talk,https://n8cir.org.uk/training-and-events/event-resources/rse-am-2025/,,Aman Goel, | ||
| SSI internal ideas meeting,2025-09-02,2025-09-02,Online,Presentation + activity to explore the framework,,,Aleksandra Nenadic, | ||
| RSECon25,2025-09-09,2025-09-11,"Oculus, University of Warwick",Workshop for user experience testing the web app visualisations and profiles,https://rsecon25.society-rse.org/,,"Dave Horsfall, Adrian D’Alessandro, Aman Goel, Aleksandra Nenadic, Phil Reed, Emma Hogan, Muhammad Salihu, Gabriel Hanganu", |
There was a problem hiding this comment.
Do we not have a photo from RSECon25?
| <div class="bg-dark rounded-2 d-flex justify-content-center align-items-center" | ||
| style="width: 150px; | ||
| height: 100px"> | ||
| <span class="text-muted text-light small">No image</span> |
There was a problem hiding this comment.
Should we defer to the image used before for these missing images? assets/img/blog/single/image.jpg
| {% if event.blog %} | ||
| <a href="{{ event.blog }}" target="_blank">{{ event.title }}</a> | ||
| {% else %} | ||
| {{ event.title }} | ||
| {% endif %} |
There was a problem hiding this comment.
Do we need a link to the blog on the title when there is already a blog link included below?
| {% if event.end_date and event.end_date != event.start_date %}– {{ event.end_date }}{% endif %} | ||
| {% if event.location %}| {{ event.location }}{% endif %} | ||
| {% if event.event_link %}| <a href="{{ event.event_link }}" target="_blank">Event</a>{% endif %} | ||
| {% if event.blog %}| <a href="{{ event.blog }}" target="_blank">Blog</a>{% endif %} |
There was a problem hiding this comment.
I agree with copilot's suggestion here.
| {% if event.blog %}| <a href="{{ event.blog }}" target="_blank">Blog</a>{% endif %} | |
| {% if event.event_link %}| <a href="{{ event.event_link }}" target="_blank rel="noopener noreferrer"">Event</a>{% endif %} | |
| {% if event.blog %}| <a href="{{ event.blog }}" target="_blank rel="noopener noreferrer"">Blog</a>{% endif %} |
| </li> | ||
| <li> | ||
| <a class="dropdown-item" href="{% url 'roles' %}">Roles and job profiles</a> | ||
| <a class="dropdown-item" href="{% url 'roles' %}">Roles & career pathways</a> |
There was a problem hiding this comment.
Happy to change this title to "career pathways", but there has been an effort to remove & from things in the framework for accessibility reasons. So this should be an "and"
| <a class="dropdown-item" href="{% url 'roles' %}">Roles & career pathways</a> | |
| <a class="dropdown-item" href="{% url 'roles' %}">Roles and career pathways</a> |
(also, like copilot suggests, the test should be updated accordingly).
| "image": static(image_path) if image_path else None, | ||
| } | ||
| ) | ||
|
|
||
| events.sort(key=lambda e: e["start_date"], reverse=True) | ||
| events.sort(key=lambda e: cast(str, e["start_date"]), reverse=True) |
There was a problem hiding this comment.
I think a cleaner way to fix the mypy error is, instead of casting it as a str, just ensure the types in the dictionary are consistent. This works for me:
| "image": static(image_path) if image_path else None, | |
| } | |
| ) | |
| events.sort(key=lambda e: e["start_date"], reverse=True) | |
| events.sort(key=lambda e: cast(str, e["start_date"]), reverse=True) | |
| "image": static(image_path) if image_path else "", | |
| } | |
| ) | |
| events.sort(key=lambda e: e["start_date"], reverse=True) |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Description
This PR updates the existing events page, populating each event with more details.
Fixes # (issue)
Type of change
Key checklist
python -m pytest)mkdocs serve)pre-commit run --all-files)Further checks