from __future__ import annotations import uuid from typing import Any from django.core.management.base import BaseCommand, CommandError from django.db import transaction from wagtail.blocks import StreamValue from wagtail.models import Locale, Page from mandelstudio.management.commands._agency_content import COMMON_CTA, HOME_COPY def _make_faq_items(locale_code: str) -> list[dict[str, Any]]: cfg = HOME_COPY.get(locale_code) or {} faqs = cfg.get("faqs") or [] items: list[dict[str, Any]] = [] for question, answer, category in faqs: items.append( { "type": "item", "id": str(uuid.uuid4()), "value": { "question": question, "answer": answer, "category": category, }, } ) return items def _update_saas_faq_block(value: dict[str, Any], *, locale_code: str) -> bool: """Update a `saas_faq` block in-place. Returns True if changed.""" desired_items = _make_faq_items(locale_code) if not desired_items: return False changed = False if value.get("faqs") != desired_items: value["faqs"] = desired_items changed = True # Keep the existing CTA URL (it is page-specific and already localized), # but ensure the CTA label is consistent for the locale. if "contact_cta_text" in value and locale_code in COMMON_CTA: desired_cta = COMMON_CTA[locale_code]["primary"] if value.get("contact_cta_text") != desired_cta: value["contact_cta_text"] = desired_cta changed = True return changed def _update_page_body(page: Page, *, locale_code: str) -> bool: specific = page.specific if not hasattr(specific, "body"): return False body = specific.body raw_data = list(body.raw_data) changed = False for block in raw_data: if block.get("type") != "saas_faq": continue value = block.get("value") if isinstance(value, dict): if _update_saas_faq_block(value, locale_code=locale_code): block["value"] = value changed = True if not changed: return False specific.body = StreamValue(body.stream_block, raw_data, is_lazy=True) return True class Command(BaseCommand): help = "Fix the Capabilities (mogelijkheden) page FAQ items across locales" def add_arguments(self, parser): parser.add_argument( "--apply", action="store_true", help="Persist and publish changes (default is dry-run).", ) def handle(self, *args, **options): apply_changes = options["apply"] nl_locale = Locale.objects.filter(language_code="nl").first() if nl_locale is None: raise CommandError("Locale nl not found") source = ( Page.objects.filter(locale=nl_locale, slug="mogelijkheden") .specific() .first() ) if source is None: raise CommandError("Could not find source page nl/slug=mogelijkheden") target_locales = list(Locale.objects.all().order_by("language_code")) with transaction.atomic(): for locale in target_locales: code = locale.language_code page = ( Page.objects.filter( translation_key=source.translation_key, locale=locale ) .specific() .first() ) if page is None: self.stdout.write(f"SKIP {code}: no translation for mogelijkheden") continue changed = _update_page_body(page, locale_code=code) if not changed: self.stdout.write(f"OK {code}: no FAQ changes needed") continue self.stdout.write(f"CHG {code}: updated saas_faq items") if apply_changes: rev = page.save_revision() rev.publish() if not apply_changes: raise CommandError( "Dry-run complete. Re-run with --apply to persist changes." )