From ea31bca342ea52aac38e73b93db30bac3f2fe82f Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Fri, 17 Apr 2026 16:42:07 +0100 Subject: [PATCH 1/2] Add the Tools, languages and methodologies page --- main/tables.py | 80 +++++++++++++------ .../pages/tools-languages-methodologies.html | 22 +++++ main/templates/main/snippets/navbar.html | 6 +- main/urls.py | 5 ++ main/views/page_views.py | 12 ++- tests/main/test_tables.py | 10 +-- 6 files changed, 104 insertions(+), 31 deletions(-) create mode 100644 main/templates/main/pages/tools-languages-methodologies.html diff --git a/main/tables.py b/main/tables.py index 940d5662..6fbec153 100644 --- a/main/tables.py +++ b/main/tables.py @@ -3,17 +3,38 @@ from typing import TYPE_CHECKING import django_tables2 as tables +from django.db.models.query import QuerySet from django.urls import reverse from django.utils.html import format_html from django.utils.safestring import SafeString, mark_safe -from .models import LearningResource, Skill +from .models import LearningResource, Skill, ToolLanguageMethodology if TYPE_CHECKING: # pragma: no cover from django.db.models.fields.related_descriptors import ManyRelatedManager +external_link_html = ( + '{}' +) +badge_html = '{}' -class LearningResourcesTable(tables.Table): + +def _render_skills(qs: QuerySet[Skill]) -> SafeString: + """Helper function for rendering skills links as buttons in tables.""" + return mark_safe( + " ".join( + format_html( + external_link_html, + reverse("skill_detail", args=(skill.slug,)), + "btn btn-outline-primary rounded-pill btn-sm", + skill.name, + ) + for skill in qs + ) + ) + + +class LearningResourceTable(tables.Table): """Table class for the LearningResources model.""" skill_set = tables.ManyToManyColumn(verbose_name="Skills") @@ -27,10 +48,12 @@ class Meta: def render_name(self, value: str, record: LearningResource) -> SafeString: """Include the URL in the name.""" - return format_html( - '{}', - record.url, - value, + return format_html(external_link_html, record.url, "fs-lg", value) + + def render_language(self, value: str) -> SafeString: + """Render the language field as a badge.""" + return mark_safe( + " ".join(format_html(badge_html, val) for val in value.split(",")) ) def render_provider(self, value: str, record: LearningResource) -> SafeString: @@ -38,22 +61,33 @@ def render_provider(self, value: str, record: LearningResource) -> SafeString: if record.provider is None or not record.provider.url: return mark_safe(value) - return format_html( - '{}', - record.provider.url, - value, - ) + return format_html(external_link_html, record.provider.url, "", value) def render_skill_set(self, value: "ManyRelatedManager[Skill]") -> SafeString: - """Include the relevant skills as badges.""" - return mark_safe( - "".join( - format_html( - '{}', - reverse("skill_detail", args=(skill.slug,)), - skill.name, - ) - for skill in value.all() - ) - ) + """Include the relevant skills as button links.""" + return _render_skills(value.all()) + + +class ToolLanguageMethodologyTable(tables.Table): + """Table class for the LearningResources model.""" + + skill_set = tables.ManyToManyColumn(verbose_name="Skills") + + class Meta: + """Meta options for the LearningResourcesTable.""" + + model = ToolLanguageMethodology + fields = ("name", "kind") + order_by = "name" + + def render_name(self, value: str, record: LearningResource) -> SafeString: + """Include the URL in the name.""" + return format_html(external_link_html, record.url, "fs-lg", value) + + def render_kind(self, value: str) -> SafeString: + """Render the kind field as a badge.""" + return format_html(badge_html, value) + + def render_skill_set(self, value: "ManyRelatedManager[Skill]") -> SafeString: + """Include the relevant skills as button links.""" + return _render_skills(value.all()) diff --git a/main/templates/main/pages/tools-languages-methodologies.html b/main/templates/main/pages/tools-languages-methodologies.html new file mode 100644 index 00000000..c83668e3 --- /dev/null +++ b/main/templates/main/pages/tools-languages-methodologies.html @@ -0,0 +1,22 @@ +{% extends "main/base.page.html" %} +{% load static %} +{% load render_table from django_tables2 %} +{% block title %} + Digital Research Competencies Framework +{% endblock title %} +{% block breadcrumb_items %} + + +{% endblock breadcrumb_items %} +{% block content %} +
+
+
+

Tools, languages and methodologies

+ {% render_table table %} +
+
+
+{% endblock content %} diff --git a/main/templates/main/snippets/navbar.html b/main/templates/main/snippets/navbar.html index ba313b63..491c8484 100644 --- a/main/templates/main/snippets/navbar.html +++ b/main/templates/main/snippets/navbar.html @@ -115,7 +115,11 @@