add middleware to add signposting links into html head

This commit is contained in:
Daniel Bauer
2024-11-22 12:04:15 +01:00
parent 06d745e4a4
commit 8d8a92e5d5
5 changed files with 514 additions and 0 deletions

View File

@@ -41,6 +41,48 @@ class SignpostingMiddleware:
response["Link"] = " , ".join(link_snippets)
class HtmlSignpostingMiddleware(SignpostingMiddleware):
def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]):
self.get_response = get_response
def __call__(self, request: HttpRequest) -> HttpResponse:
response = self.get_response(request)
if not hasattr(response, "_signposts"):
return response
# Adding Signposts via HTML is only supported for HTML responses
if not response.headers["Content-Type"].startswith("text/html"):
return response
content = response.content.decode("utf-8")
soup = BeautifulSoup(content, "html.parser")
# Html should have a root element
if not soup.html:
raise Exception("Could not find HTML root element")
# Add head element if not present
if not soup.head:
head_tag = soup.new_tag("head")
soup.html.insert(0, head_tag)
# BUild links for each signpost and add them to the html
for signpost in response._signposts:
link_tag = soup.new_tag("link")
link_tag["rel"] = signpost.rel
link_tag["href"] = signpost.target
if signpost.type:
link_tag["type"] = signpost.type
soup.head.append(link_tag)
# Override the original content with the new HTML
response.content = soup.prettify().encode("utf-8")
response['Content-Length'] = len(response.content)
return response
class JsonLdSignpostingParserMiddleware(MiddlewareMixin):