add middleware to add signposting links into html head (#3)

* add middleware to add signposting links into html head
This commit is contained in:
Daniel Bauer
2024-11-25 15:44:46 +01:00
committed by GitHub
parent 06d745e4a4
commit b29f19d78a
6 changed files with 530 additions and 3 deletions

View File

@@ -42,8 +42,49 @@ class SignpostingMiddleware:
response["Link"] = " , ".join(link_snippets)
class JsonLdSignpostingParserMiddleware(MiddlewareMixin):
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):
def process_response(
self, request: HttpRequest, response: HttpResponse
) -> HttpResponse: