diff --git a/apps/blog/tests/test_seo.py b/apps/blog/tests/test_seo.py new file mode 100644 index 0000000..16efae9 --- /dev/null +++ b/apps/blog/tests/test_seo.py @@ -0,0 +1,35 @@ +import pytest + +from apps.blog.models import ArticleIndexPage, ArticlePage +from apps.blog.tests.factories import AuthorFactory + + +@pytest.mark.django_db +def test_article_page_renders_core_seo_meta(client, home_page): + index = ArticleIndexPage(title="Articles", slug="articles") + home_page.add_child(instance=index) + author = AuthorFactory() + article = ArticlePage( + title="SEO Article", + slug="seo-article", + author=author, + summary="Summary content", + body=[("rich_text", "

Body

")], + ) + index.add_child(instance=article) + article.save_revision().publish() + + resp = client.get("/articles/seo-article/") + html = resp.content.decode() + assert resp.status_code == 200 + assert ' str: + site_settings = SiteSettings.for_request(request) + image = article.hero_image or site_settings.default_og_image + if isinstance(image, Image): + rendition = image.get_rendition("fill-1200x630") + return request.build_absolute_uri(rendition.url) + return "" + + +@register.simple_tag(takes_context=True) +def canonical_url(context, page=None) -> str: + request = context["request"] + target = page or context.get("page") + if target and hasattr(target, "get_full_url"): + return target.get_full_url(request) + return request.build_absolute_uri() + + +@register.simple_tag(takes_context=True) +def article_og_image_url(context, article) -> str: + return _article_image_url(context["request"], article) + + @register.simple_tag(takes_context=True) def article_json_ld(context, article): request = context["request"] - site_settings = SiteSettings.for_request(request) - image = article.hero_image or site_settings.default_og_image - image_url = "" - if isinstance(image, Image): - rendition = image.get_rendition("fill-1200x630") - image_url = request.build_absolute_uri(rendition.url) - data = { "@context": "https://schema.org", "@type": "Article", @@ -30,7 +46,7 @@ def article_json_ld(context, article): "dateModified": article.last_published_at.isoformat() if article.last_published_at else "", "description": article.search_description or article.summary, "url": article.get_full_url(request), - "image": image_url, + "image": _article_image_url(request, article), } return mark_safe( '" diff --git a/templates/base.html b/templates/base.html index 3f1963b..1afe279 100644 --- a/templates/base.html +++ b/templates/base.html @@ -5,6 +5,7 @@ {% block title %}No Hype AI{% endblock %} + {% block head_meta %}{% endblock %} diff --git a/templates/blog/article_index_page.html b/templates/blog/article_index_page.html index 3a67743..b39d72f 100644 --- a/templates/blog/article_index_page.html +++ b/templates/blog/article_index_page.html @@ -1,6 +1,14 @@ {% extends 'base.html' %} -{% load core_tags %} +{% load core_tags seo_tags %} {% block title %}Articles | No Hype AI{% endblock %} +{% block head_meta %} + {% canonical_url page as canonical %} + + + + + +{% endblock %} {% block content %}

{{ page.title }}

{% for article in articles %} diff --git a/templates/blog/article_page.html b/templates/blog/article_page.html index ff661da..c43f36b 100644 --- a/templates/blog/article_page.html +++ b/templates/blog/article_page.html @@ -1,6 +1,21 @@ {% extends 'base.html' %} {% load wagtailcore_tags wagtailimages_tags seo_tags %} {% block title %}{{ page.title }} | No Hype AI{% endblock %} +{% block head_meta %} + {% canonical_url page as canonical %} + {% article_og_image_url page as og_image %} + + + + + + + {% if og_image %}{% endif %} + + + + {% if og_image %}{% endif %} +{% endblock %} {% block content %}

{{ page.title }}

diff --git a/templates/blog/home_page.html b/templates/blog/home_page.html index cfd06f6..08bae09 100644 --- a/templates/blog/home_page.html +++ b/templates/blog/home_page.html @@ -1,5 +1,15 @@ {% extends 'base.html' %} +{% load seo_tags %} {% block title %}No Hype AI{% endblock %} +{% block head_meta %} + {% canonical_url page as canonical %} + + + + + + +{% endblock %} {% block content %}
{% if featured_article %}