feat: add direct-save CMS and About archive
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
from django.http import HttpResponse
|
||||
from django.utils import timezone
|
||||
from ninja import Router
|
||||
from ninja.errors import HttpError
|
||||
|
||||
from apps.events.models import Event
|
||||
from apps.content.current import AboutContent, HomeContent, ListingContent, SiteContent
|
||||
from apps.content.api.schemas import AboutPageOut, HomePageOut, ListingPageOut, PageContentOut, SiteContentOut
|
||||
|
||||
@@ -23,6 +25,27 @@ def _seo(request, obj):
|
||||
}
|
||||
|
||||
|
||||
def _about_member_out(request, member, year_label=None):
|
||||
return {
|
||||
"name": member.name,
|
||||
"role": member.role,
|
||||
"entry_year": year_label or member.entry_year,
|
||||
"bio": member.bio,
|
||||
"photo": _media(request, member.photo, member.photo_alt),
|
||||
"position": member.position,
|
||||
}
|
||||
|
||||
|
||||
def _about_event_out(request, event):
|
||||
return {
|
||||
"id": event.pk,
|
||||
"title": event.title,
|
||||
"slug": event.slug,
|
||||
"start_time": event.start_time,
|
||||
"featured_image": _media(request, event.featured_image, f"پوستر {event.title}"),
|
||||
}
|
||||
|
||||
|
||||
@content_router.get("/site", response=SiteContentOut)
|
||||
def get_site_content(request, response: HttpResponse):
|
||||
site = SiteContent.objects.filter(pk=1).first()
|
||||
@@ -50,6 +73,8 @@ def get_site_content(request, response: HttpResponse):
|
||||
},
|
||||
"address": site.address,
|
||||
"footer_copy": site.footer_copy,
|
||||
"enamad_image": _media(request, site.enamad_image, site.enamad_image_alt),
|
||||
"enamad_url": site.enamad_url,
|
||||
"seo": _seo(request, site),
|
||||
}
|
||||
|
||||
@@ -66,32 +91,105 @@ def get_page_content(request, response: HttpResponse, slug: str):
|
||||
"hero_heading": page.hero_heading, "hero_body": page.hero_body,
|
||||
"hero_image": _media(request, page.hero_image, page.hero_image_alt),
|
||||
"hero_action_label": page.hero_action_label,
|
||||
"hero_action_url": page.hero_action_url,
|
||||
"hero_secondary_action_label": page.hero_secondary_action_label,
|
||||
"hero_secondary_action_url": page.hero_secondary_action_url,
|
||||
"featured_events_heading": page.featured_events_heading,
|
||||
"featured_events_intro": page.featured_events_intro,
|
||||
"featured_events_link_label": page.featured_events_link_label,
|
||||
"featured_events_url": page.featured_events_url,
|
||||
"featured_event_action_label": page.featured_event_action_label,
|
||||
"featured_posts_heading": page.featured_posts_heading,
|
||||
"featured_posts_intro": page.featured_posts_intro,
|
||||
"featured_posts_link_label": page.featured_posts_link_label,
|
||||
"featured_posts_url": page.featured_posts_url,
|
||||
"featured_post_action_label": page.featured_post_action_label,
|
||||
"participation_heading": page.participation_heading,
|
||||
"participation_body": page.participation_body,
|
||||
"participation_image": _media(request, page.participation_image, page.participation_image_alt),
|
||||
"participation_action_label": page.participation_action_label,
|
||||
"participation_action_url": page.participation_action_url,
|
||||
"participation_secondary_action_label": page.participation_secondary_action_label,
|
||||
"participation_secondary_action_url": page.participation_secondary_action_url,
|
||||
}
|
||||
|
||||
if slug == "about":
|
||||
page = AboutContent.objects.filter(pk=1).first()
|
||||
if page is None:
|
||||
raise HttpError(404, "Page content not found")
|
||||
event_statuses = (Event.StatusChoices.PUBLISHED, Event.StatusChoices.COMPLETED)
|
||||
years_by_label = {}
|
||||
for year in page.years.prefetch_related("members", "events").all():
|
||||
label = year.year_label.strip() or "سال نامشخص"
|
||||
events = year.events.filter(
|
||||
is_deleted=False,
|
||||
status__in=event_statuses,
|
||||
start_time__lte=timezone.now(),
|
||||
).order_by("-start_time", "-pk")
|
||||
years_by_label[label] = {
|
||||
"year_label": label,
|
||||
"position": year.position,
|
||||
"_pk": year.pk,
|
||||
"members": [
|
||||
_about_member_out(request, member, label)
|
||||
for member in year.members.all()
|
||||
],
|
||||
"selected_events": [_about_event_out(request, event) for event in events],
|
||||
}
|
||||
|
||||
legacy_members = page.members.filter(year_group__isnull=True).order_by("entry_year", "position", "pk")
|
||||
for member in legacy_members:
|
||||
label = member.entry_year.strip() or "سال نامشخص"
|
||||
year_data = years_by_label.setdefault(
|
||||
label,
|
||||
{
|
||||
"year_label": label,
|
||||
"position": 0,
|
||||
"_pk": 0,
|
||||
"members": [],
|
||||
"selected_events": [],
|
||||
},
|
||||
)
|
||||
year_data["members"].append(_about_member_out(request, member, label))
|
||||
|
||||
years = sorted(
|
||||
years_by_label.values(),
|
||||
key=lambda year: (year["position"], year["_pk"], year["year_label"]),
|
||||
)
|
||||
all_members = [member for year in years for member in year["members"]]
|
||||
return {
|
||||
"slug": "about", "title": page.title, "intro": page.intro, "seo": _seo(request, page),
|
||||
"identity_heading": page.identity_heading, "identity_body": page.identity_body,
|
||||
"mission_heading": page.mission_heading, "mission_body": page.mission_body,
|
||||
"vision_heading": page.vision_heading, "vision_body": page.vision_body,
|
||||
"activities_heading": page.activities_heading, "activities_body": page.activities_body,
|
||||
"values_heading": page.values_heading, "values_body": page.values_body,
|
||||
"committees_heading": page.committees_heading, "committees_body": page.committees_body,
|
||||
"affiliations_heading": page.affiliations_heading, "affiliations_body": page.affiliations_body,
|
||||
"faq_heading": page.faq_heading, "contact_heading": page.contact_heading,
|
||||
"items": list(page.items.values("kind", "title", "text", "position")),
|
||||
"members_heading": page.members_heading, "members_intro": page.members_intro,
|
||||
"gallery_heading": page.gallery_heading, "gallery_intro": page.gallery_intro,
|
||||
"past_events_heading": page.past_events_heading,
|
||||
"history_heading": page.history_heading,
|
||||
"audience_heading": page.audience_heading,
|
||||
"year_events_heading": page.year_events_heading,
|
||||
"cta_heading": page.cta_heading,
|
||||
"cta_body": page.cta_body,
|
||||
"cta_action_label": page.cta_action_label,
|
||||
"cta_action_url": page.cta_action_url,
|
||||
"items": list(page.items.exclude(kind__in=("committees", "affiliations")).values("kind", "title", "text", "position")),
|
||||
"members": all_members,
|
||||
"gallery_images": [
|
||||
{
|
||||
"image": _media(request, item.image, item.image_alt),
|
||||
"caption": item.caption, "position": item.position,
|
||||
}
|
||||
for item in page.gallery_images.all()
|
||||
],
|
||||
"audiences": list(page.audiences.values("title", "text", "icon", "position")),
|
||||
"milestones": list(page.milestones.values("year_label", "title", "description", "position")),
|
||||
"years": [
|
||||
{key: value for key, value in year.items() if not key.startswith("_")}
|
||||
for year in years
|
||||
],
|
||||
}
|
||||
|
||||
if slug in ("events", "blog"):
|
||||
|
||||
Reference in New Issue
Block a user