diff --git a/mandelstudio/management/commands/_agency_content.py b/mandelstudio/management/commands/_agency_content.py index 6dd9db6..8c5d1b9 100644 --- a/mandelstudio/management/commands/_agency_content.py +++ b/mandelstudio/management/commands/_agency_content.py @@ -139,6 +139,15 @@ FOOTER_CONTENT = { } +def _contact_form_anchor(url: str | None) -> str | None: + if not url: + return url + if url.endswith("#contact-form"): + return url + base = url.split("#", 1)[0] + return f"{base}#contact-form" + + def uid() -> str: return str(uuid.uuid4()) @@ -3904,6 +3913,11 @@ def _standard_body( cta = COMMON_CTA[locale] common = STANDARD_COPY[locale] cfg = common["pages"][page_key] + contact_cta_url = ( + _contact_form_anchor(urls["contact"]) + if page_key == "contact" + else urls["contact"] + ) blocks = [ block( "saas_hero_banner", @@ -3934,7 +3948,7 @@ def _standard_body( "headline": cfg["headline"], "sub_headline": cfg["sub"], "primary_cta_text": cta["primary"], - "primary_cta_url": urls["contact"], + "primary_cta_url": contact_cta_url, "secondary_cta_text": "", "secondary_cta_url": "", "hero_image": ( @@ -4066,7 +4080,7 @@ def _standard_body( "headline": cfg["cta"], "subheadline": common["cta_sub"], "primary_cta_text": cta["primary"], - "primary_cta_url": urls["contact"], + "primary_cta_url": contact_cta_url, "secondary_cta_text": "", "secondary_cta_url": "", "background_image": AGENCY_SUPPORT_IMAGE_ID, diff --git a/mandelstudio/management/commands/apply_agency_website_refresh.py b/mandelstudio/management/commands/apply_agency_website_refresh.py index c348929..e08ab09 100644 --- a/mandelstudio/management/commands/apply_agency_website_refresh.py +++ b/mandelstudio/management/commands/apply_agency_website_refresh.py @@ -15,6 +15,7 @@ from mandelstudio.management.commands._agency_content import ( CTA_VARIANTS, FOOTER_CONTENT, NL_REPLACEMENTS, + _contact_form_anchor, ) from mandelstudio.management.commands._agency_content import ( body_for as localized_body_for, @@ -548,6 +549,11 @@ def nl_home(urls: dict[str, str]) -> list[dict[str, Any]]: def nl_standard_page(page_key: str, urls: dict[str, str]) -> list[dict[str, Any]]: primary = COMMON_CTA["nl"]["primary"] secondary = COMMON_CTA["nl"]["secondary"] + contact_cta_url = ( + _contact_form_anchor(urls["contact"]) + if page_key == "contact" + else urls["contact"] + ) page_data = { "about": { "headline": "Wie MandelBlog is en hoe we werken", @@ -809,7 +815,7 @@ def nl_standard_page(page_key: str, urls: dict[str, str]) -> list[dict[str, Any] "headline": cfg["headline"], "sub_headline": cfg["sub"], "primary_cta_text": primary, - "primary_cta_url": urls["contact"], + "primary_cta_url": contact_cta_url, "secondary_cta_text": secondary, "secondary_cta_url": urls["services"], "hero_image": 1 if page_key != "process" else 24, @@ -836,8 +842,10 @@ def nl_standard_page(page_key: str, urls: dict[str, str]) -> list[dict[str, Any] "link_text": primary if page_key in {"contact", "about"} else secondary, - "link_url": urls["contact"] - if page_key in {"contact", "about"} + "link_url": contact_cta_url + if page_key == "contact" + else urls["contact"] + if page_key == "about" else urls["services"], "highlight": "none", } @@ -884,7 +892,7 @@ def nl_standard_page(page_key: str, urls: dict[str, str]) -> list[dict[str, Any] ], "show_contact_cta": "card", "contact_cta_text": primary, - "contact_cta_url": urls["contact"], + "contact_cta_url": contact_cta_url, }, ) ) @@ -898,7 +906,7 @@ def nl_standard_page(page_key: str, urls: dict[str, str]) -> list[dict[str, Any] "headline": cfg["cta"], "subheadline": "
Plan een kennismakingsgesprek en we laten zien welke route logisch is voor uw bedrijf.
", "primary_cta_text": primary, - "primary_cta_url": urls["contact"], + "primary_cta_url": contact_cta_url, "secondary_cta_text": secondary, "secondary_cta_url": urls["services"], "background_image": 1, diff --git a/mandelstudio/management/commands/fix_contact_cta_anchor.py b/mandelstudio/management/commands/fix_contact_cta_anchor.py new file mode 100644 index 0000000..287bb7d --- /dev/null +++ b/mandelstudio/management/commands/fix_contact_cta_anchor.py @@ -0,0 +1,139 @@ +from __future__ import annotations + +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 + +CONTACT_SLUGS = { + "nl": "contact", + "en": "contact", + "de": "kontakt", + "fr": "contact", + "es": "contacto", + "it": "contatto", + "pt": "contato", + "ru": "контакт", +} + +CONTACT_ANCHOR = "#contact-form" +CTA_BLOCK_TYPES = {"saas_hero_banner", "saas_cta_footer"} + + +def _with_contact_anchor(url: str | None) -> str | None: + if not url: + return url + if url.endswith(CONTACT_ANCHOR): + return url + return f"{url.split('#', 1)[0]}{CONTACT_ANCHOR}" + + +def _localized_page_url(source: Page, locale: Locale) -> str | None: + translated = ( + Page.objects.filter(translation_key=source.translation_key, locale=locale) + .specific() + .first() + ) + chosen = translated or source + return getattr(chosen, "url", None) + + +class Command(BaseCommand): + help = "Anchor contact page CTA buttons to the contact form across locales" + + def add_arguments(self, parser): + parser.add_argument( + "--page-id", + type=int, + help="Optional Wagtail page id to fix.", + ) + 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"] + page_id = options.get("page_id") + + with transaction.atomic(): + if page_id: + page = Page.objects.filter(id=page_id).specific().first() + if page is None: + raise CommandError(f"Page id={page_id} not found") + self._fix_page(page, apply_changes=apply_changes) + else: + source = self._find_contact_source_page() + if source is None: + raise CommandError("Could not find a source contact page") + + for locale in Locale.objects.all().order_by("language_code"): + page = ( + Page.objects.filter( + translation_key=source.translation_key, + locale=locale, + ) + .specific() + .first() + ) + if page is None: + self.stdout.write( + f"SKIP {locale.language_code}: no contact translation" + ) + continue + self._fix_page(page, apply_changes=apply_changes) + + if not apply_changes: + raise CommandError( + "Dry-run complete. Re-run with --apply to persist changes." + ) + + def _find_contact_source_page(self) -> Page | None: + for code, slug in CONTACT_SLUGS.items(): + locale = Locale.objects.filter(language_code=code).first() + if locale is None: + continue + page = Page.objects.filter(locale=locale, slug=slug).specific().first() + if page is not None: + return page + return None + + def _fix_page(self, page: Page, *, apply_changes: bool) -> None: + specific = page.specific + code = page.locale.language_code + + if not hasattr(specific, "body"): + self.stdout.write(f"SKIP {code}: no body streamfield") + return + + localized_contact_url = _with_contact_anchor( + _localized_page_url(page, page.locale) + ) + body = specific.body + raw_data = list(body.raw_data) + changed = False + + for block in raw_data: + if block.get("type") not in CTA_BLOCK_TYPES: + continue + value = block.get("value") + if not isinstance(value, dict): + continue + if value.get("primary_cta_url") != localized_contact_url: + value["primary_cta_url"] = localized_contact_url + block["value"] = value + changed = True + + if not changed: + self.stdout.write(f"OK {code}: contact CTA already anchored") + return + + self.stdout.write(f"CHG {code}: anchored contact CTA buttons") + specific.body = StreamValue(body.stream_block, raw_data, is_lazy=True) + if apply_changes: + rev = specific.save_revision() + rev.publish() diff --git a/mandelstudio/templates/highbiza_saas/blocks/demo_request/variants/split.html b/mandelstudio/templates/highbiza_saas/blocks/demo_request/variants/split.html index 2323a3f..d09ec8c 100644 --- a/mandelstudio/templates/highbiza_saas/blocks/demo_request/variants/split.html +++ b/mandelstudio/templates/highbiza_saas/blocks/demo_request/variants/split.html @@ -106,7 +106,7 @@