feat: make people group labels editable

This commit is contained in:
mohamad
2026-10-29 04:11:36 +08:00
parent cb54e96db6
commit 9a8551ae23
8 changed files with 81 additions and 7 deletions
+7
View File
@@ -50,6 +50,13 @@ class SiteBrandingAdmin(admin.ModelAdmin):
"description": "These headings are shared by main projects and sub-projects that have people cards.",
},
),
(
"People role headings",
{
"fields": ("lead_group_label", "organizer_group_label", "collaborator_group_label"),
"description": "Shared across About, blog articles, project articles, main projects, and sub-projects. Empty headings are hidden; people cards remain visible.",
},
),
(
"Brand assets",
{
@@ -0,0 +1,28 @@
# Generated by Django 5.2.16 on 2026-10-28 20:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0007_sitebranding_project_people_eyebrow_and_more'),
]
operations = [
migrations.AddField(
model_name='sitebranding',
name='collaborator_group_label',
field=models.CharField(blank=True, default='Collaborators', help_text='Heading for Collaborators. Leave empty to hide the heading while keeping their cards.', max_length=100),
),
migrations.AddField(
model_name='sitebranding',
name='lead_group_label',
field=models.CharField(blank=True, default='Lead / Leader', help_text='Heading for Lead and Leader people. Leave empty to hide the heading while keeping their cards.', max_length=100),
),
migrations.AddField(
model_name='sitebranding',
name='organizer_group_label',
field=models.CharField(blank=True, default='Organizers', help_text='Heading for Organizers. Leave empty to hide the heading while keeping their cards.', max_length=100),
),
]
+12
View File
@@ -49,6 +49,18 @@ class SiteBranding(models.Model):
max_length=200, default="Organizers & collaborators",
help_text="Heading above the people cards on main projects and sub-projects.",
)
lead_group_label = models.CharField(
max_length=100, blank=True, default="Lead / Leader",
help_text="Heading for Lead and Leader people. Leave empty to hide the heading while keeping their cards.",
)
organizer_group_label = models.CharField(
max_length=100, blank=True, default="Organizers",
help_text="Heading for Organizers. Leave empty to hide the heading while keeping their cards.",
)
collaborator_group_label = models.CharField(
max_length=100, blank=True, default="Collaborators",
help_text="Heading for Collaborators. Leave empty to hide the heading while keeping their cards.",
)
icon = models.ImageField(
upload_to="branding/",
+3 -3
View File
@@ -2,7 +2,7 @@ from collections import OrderedDict
ROLE_PRIORITY = {"lead": 0, "leader": 0, "organizer": 1, "collaborator": 2}
ROLE_TITLES = {0: "Lead / Leader", 1: "Organizers", 2: "Collaborators"}
ROLE_LABEL_FIELDS = {0: "lead_group_label", 1: "organizer_group_label", 2: "collaborator_group_label"}
def person_sort_key(person):
@@ -10,7 +10,7 @@ def person_sort_key(person):
return (ROLE_PRIORITY.get(role, 3), role if role not in ROLE_PRIORITY else "", person.order, person.pk or 0)
def group_people(people):
def group_people(people, branding):
groups = OrderedDict()
for person in sorted(people, key=person_sort_key):
role = (person.role or "").strip()
@@ -18,7 +18,7 @@ def group_people(people):
key = priority if priority < 3 else role.casefold()
if key not in groups:
groups[key] = {
"title": ROLE_TITLES[priority] if priority < 3 else role or "Other contributors",
"title": getattr(branding, ROLE_LABEL_FIELDS[priority], "") if priority < 3 else role,
"people": [],
}
groups[key]["people"].append(person)
+2 -2
View File
@@ -6,5 +6,5 @@ register = template.Library()
@register.filter
def people_rows(people):
return group_people(people)
def people_rows(people, branding):
return group_people(people, branding)