Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions data/team.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name,group,role,bio,image,email,github,twitter,linkedin
Dave Horsfall,Team,Project Co-lead,Leads the DIRECT framework and strategy,assets/img/team/dave-horsfall.webp,,https://github.com/davehorsfall,,
Aleks Nenadic,Team,Project Co-lead,Leads the DIRECT framework and strategy,assets/img/team/aleksandra-nenadic.webp,,https://github.com/anenadic,,
Phil Reed,Team,Engagement and Adoption Lead,Leads the engagement and adoption activities,assets/img/team/phil-reed.webp,,https://github.com/PhilReedData,,
Adrian D'Alessandro,Team,WebApp Lead,Oversees WebApp architecture and implementation,assets/img/team/adrian-dalessandro.webp,,https://github.com/AdrianDAlessandro,,
Ryan Smith,Contributor,,,,,,,
Andrew Gait,Contributor,,,,,,,
Bryn Ubald,Contributor,,,,,,,
Jason Klebes,Contributor,,,,,,,
Sam Bland,Contributor,WebApp Team,,,,,,
Barney Dobson,Contributor,,,,,,,
Saranjeet Kaur,Contributor,WebApp Team,,,,,,
Aman Goel,Contributor,Framework Team,,,,,,
Toby Hodges,Contributor,,,,,,,
GeoDaoyu,Contributor,,,,,,,
Christopher Cave-Ayland,Contributor,,,,,,,
Sahil Raja,Contributor,,,,,,,
Connor Aird,Contributor,,,,,,,
Emma Hogan,Contributor,Framework Team,,,,,,
Matt Craddock,Contributor,,,,,,,
Tamora James,Contributor,WebApp Team,,,,,,
Becky Osselton,Contributor,,,,,,,
Eli Chadwick,Contributor,,,,,,,
Gabriel Hanganu,Contributor,,,,,,,
Hannah Williams,Contributor,,,,,,,
Matthew Bluteau,Contributor,,,,,,,
Patricia Loto,Contributor,,,,,,,
Camille Santistevan,Contributor,,,,,,,
Ella Kaye,Contributor,,,,,,,
Jonathan Cooper,Contributor,Framework Team,,,,,,
Samantha Wittke,Contributor,,,,,,,
Sarah Gibson,Contributor,,,,,,,
Iain Barrass,Contributor,,,,,,,
Lieke de Boer,Contributor,,,,,,,
Martin O'Reilly,Contributor,,,,,,,
Nadine Spychala,Contributor,,,,,,,
Paul K Korir,Contributor,,,,,,,
Sean Marshallsay,Contributor,,,,,,,
Diego Alonso Alvarez,Contributor,,,,,,,
Comment thread
davehorsfall marked this conversation as resolved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added main/static/assets/img/team/dave-horsfall.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added main/static/assets/img/team/phil-reed.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 99 additions & 0 deletions main/templates/main/pages/our-team.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{% extends "main/base.page.html" %}
{% load static %}
{% block title %}
Our Team
{% endblock title %}
{% block breadcrumb_items %}
<li class="breadcrumb-item">About</li>
<li class="breadcrumb-item active" aria-current="page">Our Team</li>
{% endblock breadcrumb_items %}
{% block content %}
<section id="about">
<div class="row">
<h1 class="mb-5">Team Members</h1>
<div class="row mb-5">
{% for member in team_members %}
<div class="col-lg-3 col-md-6 mb-4">
<div class="text-center">
{% if member.image %}
<img src="{{ member.image }}"
alt="{{ member.name }}"
class="img-fluid rounded-circle mb-3"
style="width: 160px;
height: 160px;
object-fit: cover" />
{% else %}
<div class="bg-secondary rounded-circle d-inline-flex justify-content-center align-items-center mb-3"
style="width: 160px;
height: 160px"></div>
{% endif %}
<h5 class="fw-semibold mb-1">{{ member.name }}</h5>
<p class="text-muted mb-2">{{ member.role }}</p>
<p class="small">{{ member.bio }}</p>
<ul class="list-inline mt-3">
{% if member.email %}
<li class="list-inline-item">
<a href="mailto:{{ member.email }}"
class="text-decoration-none px-1"
aria-label="Email {{ member.name }}">
<i class="fa-solid fa-envelope"></i>
</a>
</li>
{% endif %}
{% if member.github %}
<li class="list-inline-item">
<a href="{{ member.github }}"
target="_blank"
rel="noopener noreferrer"
class="text-decoration-none px-1"
aria-label="View {{ member.name }} on GitHub">
<i class="fa-brands fa-github"></i>
</a>
Comment thread
davehorsfall marked this conversation as resolved.
</li>
{% endif %}
{% if member.twitter %}
<li class="list-inline-item">
<a href="{{ member.twitter }}"
target="_blank"
rel="noopener noreferrer"
class="text-decoration-none px-1"
aria-label="View {{ member.name }} on Twitter">
<i class="fa-brands fa-twitter"></i>
</a>
</li>
{% endif %}
{% if member.linkedin %}
<li class="list-inline-item">
<a href="{{ member.linkedin }}"
target="_blank"
rel="noopener noreferrer"
class="text-decoration-none px-1"
aria-label="View {{ member.name }} on LinkedIn">
<i class="fa-brands fa-linkedin"></i>
Comment thread
AdrianDAlessandro marked this conversation as resolved.
</a>
</li>
{% endif %}
</ul>
</div>
</div>
{% endfor %}
</div>
<h2 class="mb-3">Contributors</h2>
<ul class="list-inline mb-0">
{% for contributor in contributors %}
<li class="list-inline-item me-3 mb-1">
{% if contributor.github %}
<a href="{{ contributor.github }}"
target="_blank"
rel="noopener noreferrer">{{ contributor.name }}</a>
{% else %}
{{ contributor.name }}
{% endif %}
</li>
{% empty %}
<li class="list-inline-item">No contributors listed.</li>
{% endfor %}
</ul>
</div>
</section>
{% endblock content %}
3 changes: 2 additions & 1 deletion main/templates/main/snippets/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ <h6 class="text-muted text-uppercase fs-xs fw-semibold mb-3">About</h6>
href="{% url 'about' %}">Vision and roadmap</a>
</li>
<li class="nav-item mb-2">
<a class="nav-link p-0" href="">Our team</a>
<a class="nav-link p-0"
href="{% url 'our_team' %}">Our team</a>
</li>
<li class="nav-item mb-2">
<a class="nav-link p-0"
Expand Down
1 change: 1 addition & 0 deletions main/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
),
path("framework/", include(framework_patterns)),
path("policies/", include(policies_patterns)),
path("our-team/", views.TeamPageView.as_view(), name="our_team"),
path("get-involved/", views.GetInvolvedPageView.as_view(), name="get_involved"),
path("events/", views.EventsPageView.as_view(), name="events"),
path("framework-json/", views.FrameworkView.as_view(), name="framework_json"),
Expand Down
57 changes: 56 additions & 1 deletion main/views/page_views.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
"""Views for the page-related pages of the main app."""

import csv
import json
import logging
from collections.abc import Mapping
from json import dumps
from pathlib import Path
from typing import Any, ClassVar
from typing import Any, ClassVar, cast

import markdown
import nh3
import requests
from django.db.models import Q, QuerySet
from django.shortcuts import get_object_or_404
from django.templatetags.static import static
from django.utils.decorators import method_decorator
from django.utils.safestring import mark_safe
from django.views.decorators.cache import cache_page
Expand Down Expand Up @@ -233,6 +235,59 @@ def get_context_data(self, **kwargs: Mapping[str, object]) -> dict[str, object]:
return context


class TeamPageView(TemplateView):
"""View that renders the team page from CSV."""

template_name = "main/pages/our-team.html"

def get_context_data(self, **kwargs: Mapping[str, Any]) -> dict[str, Any]:
"""Add grouped team and contributor data to the template context."""
context = super().get_context_data(**kwargs)
Comment thread
AdrianDAlessandro marked this conversation as resolved.

csv_path = Path("data/team.csv")
team_members: list[dict[str, Any]] = []
contributors: list[dict[str, Any]] = []

if not csv_path.exists():
context["team_members"] = team_members
context["contributors"] = contributors
return context

with open(csv_path, newline="", encoding="utf-8") as csvfile:
reader = csv.DictReader(csvfile)

for row in reader:
if not row:
continue

name = (row.get("name") or "").strip()
image_path = (row.get("image") or "").strip()
member = {
"name": name,
"role": (row.get("role") or "").strip(),
"bio": (row.get("bio") or "").strip(),
"image": static(image_path) if image_path else None,
"email": (row.get("email") or "").strip(),
"github": (row.get("github") or "").strip(),
"twitter": (row.get("twitter") or "").strip(),
"linkedin": (row.get("linkedin") or "").strip(),
}

group = (row.get("group") or "").strip().lower()
if group == "contributor":
if name:
contributors.append(member)
else:
team_members.append(member)

contributors.sort(key=lambda m: cast(str, m["name"]).casefold())

context["team_members"] = team_members
context["contributors"] = contributors

return context


class RolesPageView(TemplateView):
"""View that renders the role profiles page."""

Expand Down
18 changes: 18 additions & 0 deletions tests/main/test_main_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,24 @@ def test_provides_required_context(self, client):
assert isinstance(response.context["events"], QuerySet)


class TestTeamPageView(TemplateOkMixin):
"""Test suite for the EventsPageView."""

_template_name = "main/pages/our-team.html"

def _get_url(self):
return reverse("our_team")

def test_provides_required_context(self, client):
"""Test that the our team view provides the teams context."""
response = client.get(self._get_url())
assert response.status_code == HTTPStatus.OK
assert "team_members" in response.context
assert isinstance(response.context["team_members"], list)
assert "contributors" in response.context
assert isinstance(response.context["contributors"], list)


class TestAccountOverviewView(LoginRequiredMixin):
"""Test suite for the account_overview view."""

Expand Down
Loading