diff --git a/mandelstudio/settings/env/prd.py b/mandelstudio/settings/env/prd.py index 7bacd53..da94ee4 100644 --- a/mandelstudio/settings/env/prd.py +++ b/mandelstudio/settings/env/prd.py @@ -18,6 +18,7 @@ ALLOWED_HOSTS = [ "www.mandelblog.com", "mandelblog.com", ] +CANONICAL_BASE_URL = "https://www.mandelblog.com" if "salt_target" in globals(): ALLOWED_HOSTS.append("mandelstudio.%s" % salt_target) # pylint: disable=E0602 # pylint: disable=E0602 diff --git a/mandelstudio/sitemaps.py b/mandelstudio/sitemaps.py index e1ac0b6..97d4ab2 100644 --- a/mandelstudio/sitemaps.py +++ b/mandelstudio/sitemaps.py @@ -1,5 +1,6 @@ from django.contrib.sitemaps.views import index as sitemap_index_view from django.contrib.sitemaps.views import sitemap as sitemap_section_view +from django.conf import settings from django.http import HttpResponse from wagtail.models import Locale, Page @@ -15,6 +16,13 @@ from ocyan.plugin.wagtail_oscar_integration.sitemap import ( ) +def _absolute_sitemap_url(request, path: str) -> str: + canonical_base = getattr(settings, "CANONICAL_BASE_URL", "").rstrip("/") + if canonical_base: + return f"{canonical_base}{path}" + return request.build_absolute_uri(path) + + class WagtailSitemap(BaseWagtailSitemap): def items(self): page_ids = [] @@ -74,7 +82,7 @@ def sitemap_section(request, section=None): def robots_txt(request): - sitemap_url = request.build_absolute_uri("/sitemap.xml") + sitemap_url = _absolute_sitemap_url(request, "/sitemap.xml") content = "\n".join( [ "User-agent: *", diff --git a/mandelstudio/templatetags/localized_navigation.py b/mandelstudio/templatetags/localized_navigation.py index 017aaa7..310a367 100644 --- a/mandelstudio/templatetags/localized_navigation.py +++ b/mandelstudio/templatetags/localized_navigation.py @@ -2,12 +2,41 @@ from __future__ import annotations from django import template from django.conf import settings +from urllib.parse import urlsplit, urlunsplit from wagtail.models import Page register = template.Library() +def _canonical_base_url() -> str: + return getattr(settings, "CANONICAL_BASE_URL", "").rstrip("/") + + +def _with_canonical_host(url_or_path: str | None) -> str: + value = url_or_path or "" + base = _canonical_base_url() + if not base: + return value + if not value: + return f"{base}/" + if value.startswith("/"): + return f"{base}{value}" + parsed = urlsplit(value) + if parsed.scheme and parsed.netloc: + canonical = urlsplit(base) + return urlunsplit( + ( + canonical.scheme, + canonical.netloc, + parsed.path, + parsed.query, + parsed.fragment, + ) + ) + return f"{base}/{value.lstrip('/')}" + + def _normalize_language_code(language_code: str | None) -> str: return (language_code or settings.LANGUAGE_CODE).split("-")[0] @@ -41,10 +70,10 @@ def _translated_pages(page): def _build_absolute_url(request, path: str | None, page=None) -> str: if path and request is not None: - return request.build_absolute_uri(path) + return _with_canonical_host(request.build_absolute_uri(path)) if page is not None: - return getattr(page, "full_url", "") or path or "" - return path or "" + return _with_canonical_host(getattr(page, "full_url", "") or path or "") + return _with_canonical_host(path or "") @register.simple_tag @@ -89,7 +118,7 @@ def page_canonical_url(context): if page is not None and getattr(page, "url", None): return _build_absolute_url(request, page.url, page) if request is not None: - return request.build_absolute_uri() + return _with_canonical_host(request.build_absolute_uri()) return ""