1 Commits

Author SHA1 Message Date
9f4fd9278a Harden canonical and robots URLs to production host 2026-05-24 17:44:52 +02:00
3 changed files with 43 additions and 5 deletions

View File

@@ -18,6 +18,7 @@ ALLOWED_HOSTS = [
"www.mandelblog.com", "www.mandelblog.com",
"mandelblog.com", "mandelblog.com",
] ]
CANONICAL_BASE_URL = "https://www.mandelblog.com"
if "salt_target" in globals(): if "salt_target" in globals():
ALLOWED_HOSTS.append("mandelstudio.%s" % salt_target) # pylint: disable=E0602 ALLOWED_HOSTS.append("mandelstudio.%s" % salt_target) # pylint: disable=E0602
# pylint: disable=E0602 # pylint: disable=E0602

View File

@@ -1,5 +1,6 @@
from django.contrib.sitemaps.views import index as sitemap_index_view from django.contrib.sitemaps.views import index as sitemap_index_view
from django.contrib.sitemaps.views import sitemap as sitemap_section_view from django.contrib.sitemaps.views import sitemap as sitemap_section_view
from django.conf import settings
from django.http import HttpResponse from django.http import HttpResponse
from wagtail.models import Locale, Page 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): class WagtailSitemap(BaseWagtailSitemap):
def items(self): def items(self):
page_ids = [] page_ids = []
@@ -74,7 +82,7 @@ def sitemap_section(request, section=None):
def robots_txt(request): def robots_txt(request):
sitemap_url = request.build_absolute_uri("/sitemap.xml") sitemap_url = _absolute_sitemap_url(request, "/sitemap.xml")
content = "\n".join( content = "\n".join(
[ [
"User-agent: *", "User-agent: *",

View File

@@ -2,12 +2,41 @@ from __future__ import annotations
from django import template from django import template
from django.conf import settings from django.conf import settings
from urllib.parse import urlsplit, urlunsplit
from wagtail.models import Page from wagtail.models import Page
register = template.Library() 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: def _normalize_language_code(language_code: str | None) -> str:
return (language_code or settings.LANGUAGE_CODE).split("-")[0] 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: def _build_absolute_url(request, path: str | None, page=None) -> str:
if path and request is not None: 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: if page is not None:
return getattr(page, "full_url", "") or path or "" return _with_canonical_host(getattr(page, "full_url", "") or path or "")
return path or "" return _with_canonical_host(path or "")
@register.simple_tag @register.simple_tag
@@ -89,7 +118,7 @@ def page_canonical_url(context):
if page is not None and getattr(page, "url", None): if page is not None and getattr(page, "url", None):
return _build_absolute_url(request, page.url, page) return _build_absolute_url(request, page.url, page)
if request is not None: if request is not None:
return request.build_absolute_uri() return _with_canonical_host(request.build_absolute_uri())
return "" return ""