Add meta tags
This commit is contained in:
parent
af6449c9f8
commit
2dd660ed13
12 changed files with 74 additions and 9 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -161,7 +161,6 @@ eggs/
|
||||||
.eggs/
|
.eggs/
|
||||||
lib/
|
lib/
|
||||||
lib64/
|
lib64/
|
||||||
parts/
|
|
||||||
sdist/
|
sdist/
|
||||||
var/
|
var/
|
||||||
wheels/
|
wheels/
|
||||||
|
|
|
@ -15,3 +15,4 @@ gunicorn
|
||||||
psycopg2
|
psycopg2
|
||||||
djangorestframework
|
djangorestframework
|
||||||
django-htmx
|
django-htmx
|
||||||
|
wagtail-metadata
|
||||||
|
|
|
@ -48,9 +48,10 @@ sqlparse==0.4.2 # via django
|
||||||
tablib[xls,xlsx]==3.2.1 # via wagtail
|
tablib[xls,xlsx]==3.2.1 # via wagtail
|
||||||
telepath==0.2 # via wagtail
|
telepath==0.2 # via wagtail
|
||||||
urllib3==1.26.11 # via requests
|
urllib3==1.26.11 # via requests
|
||||||
wagtail==3.0.1 # via -r requirements/base.in, wagtail-draftail-snippet
|
wagtail==3.0.1 # via -r requirements/base.in, wagtail-draftail-snippet, wagtail-metadata
|
||||||
wagtail-draftail-snippet==0.4.1 # via -r requirements/base.in
|
wagtail-draftail-snippet==0.4.1 # via -r requirements/base.in
|
||||||
wagtail-generic-chooser==0.4.1 # via -r requirements/base.in
|
wagtail-generic-chooser==0.4.1 # via -r requirements/base.in
|
||||||
|
wagtail-metadata==4.0.0 # via -r requirements/base.in
|
||||||
webencodings==0.5.1 # via html5lib
|
webencodings==0.5.1 # via html5lib
|
||||||
whitenoise[brotli]==6.2.0 # via -r requirements/base.in
|
whitenoise[brotli]==6.2.0 # via -r requirements/base.in
|
||||||
willow==1.4.1 # via wagtail
|
willow==1.4.1 # via wagtail
|
||||||
|
|
|
@ -77,10 +77,11 @@ types-requests==2.28.5 # via -r requirements/dev.in
|
||||||
types-urllib3==1.26.17 # via types-requests
|
types-urllib3==1.26.17 # via types-requests
|
||||||
typing-extensions==4.3.0 # via mypy
|
typing-extensions==4.3.0 # via mypy
|
||||||
urllib3==1.26.11 # via -r requirements/base.txt, requests
|
urllib3==1.26.11 # via -r requirements/base.txt, requests
|
||||||
wagtail==3.0.1 # via -r requirements/base.txt, wagtail-draftail-snippet, wagtail-factories
|
wagtail==3.0.1 # via -r requirements/base.txt, wagtail-draftail-snippet, wagtail-factories, wagtail-metadata
|
||||||
wagtail-draftail-snippet==0.4.1 # via -r requirements/base.txt
|
wagtail-draftail-snippet==0.4.1 # via -r requirements/base.txt
|
||||||
wagtail-factories==3.1.0 # via -r requirements/dev.in
|
wagtail-factories==3.1.0 # via -r requirements/dev.in
|
||||||
wagtail-generic-chooser==0.4.1 # via -r requirements/base.txt
|
wagtail-generic-chooser==0.4.1 # via -r requirements/base.txt
|
||||||
|
wagtail-metadata==4.0.0 # via -r requirements/base.txt
|
||||||
webencodings==0.5.1 # via -r requirements/base.txt, html5lib
|
webencodings==0.5.1 # via -r requirements/base.txt, html5lib
|
||||||
wheel==0.37.1 # via pip-tools
|
wheel==0.37.1 # via pip-tools
|
||||||
whitenoise[brotli]==6.2.0 # via -r requirements/base.txt
|
whitenoise[brotli]==6.2.0 # via -r requirements/base.txt
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
{% load wagtailroutablepage_tags %}
|
{% load wagtailroutablepage_tags %}
|
||||||
|
|
||||||
{% block extra_head %}
|
{% block extra_css %}
|
||||||
<link rel="alternate" type="application/rss+xml" href="{% routablepageurl page 'feed' %}">
|
<link rel="alternate" type="application/rss+xml" href="{% routablepageurl page 'feed' %}">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
{% load wagtailroutablepage_tags %}
|
{% load wagtailroutablepage_tags %}
|
||||||
|
|
||||||
{% block extra_head %}
|
{% block extra_css %}
|
||||||
<link rel="alternate" type="application/rss+xml" href="{% routablepageurl page 'feed' %}">
|
<link rel="alternate" type="application/rss+xml" href="{% routablepageurl page 'feed' %}">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ from wagtail.images.views.serve import generate_image_url
|
||||||
from wagtail.models import Page, PageQuerySet
|
from wagtail.models import Page, PageQuerySet
|
||||||
from wagtail.search import index
|
from wagtail.search import index
|
||||||
from wagtail.snippets.models import register_snippet
|
from wagtail.snippets.models import register_snippet
|
||||||
|
from wagtailmetadata.models import MetadataMixin
|
||||||
|
|
||||||
from website.common.utils import count_words
|
from website.common.utils import count_words
|
||||||
from website.contrib.unsplash.widgets import UnsplashPhotoChooser
|
from website.contrib.unsplash.widgets import UnsplashPhotoChooser
|
||||||
|
@ -37,7 +38,7 @@ class BasePage(Page):
|
||||||
return self.get_ancestors().exclude(depth__lte=2)
|
return self.get_ancestors().exclude(depth__lte=2)
|
||||||
|
|
||||||
|
|
||||||
class BaseContentPage(BasePage):
|
class BaseContentPage(BasePage, MetadataMixin):
|
||||||
subtitle = models.CharField(max_length=255, blank=True)
|
subtitle = models.CharField(max_length=255, blank=True)
|
||||||
hero_image = models.ForeignKey(
|
hero_image = models.ForeignKey(
|
||||||
get_image_model_string(), null=True, blank=True, on_delete=models.SET_NULL
|
get_image_model_string(), null=True, blank=True, on_delete=models.SET_NULL
|
||||||
|
@ -113,6 +114,21 @@ class BaseContentPage(BasePage):
|
||||||
return generate_image_url(self.hero_image, "width-400")
|
return generate_image_url(self.hero_image, "width-400")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_meta_url(self) -> str:
|
||||||
|
return self.full_url
|
||||||
|
|
||||||
|
def get_meta_image_url(self, request: HttpRequest) -> Optional[str]:
|
||||||
|
return self.hero_image_url
|
||||||
|
|
||||||
|
def get_meta_title(self) -> str:
|
||||||
|
return self.seo_title or self.title
|
||||||
|
|
||||||
|
def get_meta_description(self) -> str:
|
||||||
|
return self.summary
|
||||||
|
|
||||||
|
def get_object_title(self) -> str:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class ContentPage(BaseContentPage):
|
class ContentPage(BaseContentPage):
|
||||||
subpage_types: list[Any] = []
|
subpage_types: list[Any] = []
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load wagtailmetadata_tags %}
|
||||||
|
|
||||||
{% block body_class %}{{ page.body_class }}{% endblock %}
|
{% block body_class %}{{ page.body_class }}{% endblock %}
|
||||||
|
|
||||||
{% block title %}{% if page.seo_title %}{{ page.seo_title }}{% else %}{{ page.title }}{% endif %}{% endblock %}
|
{% block title %}{% if page.seo_title %}{{ page.seo_title }}{% else %}{{ page.title }}{% endif %}{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_head %}
|
||||||
|
{% meta_tags %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block main_content %}
|
{% block main_content %}
|
||||||
{% if page.hero_image_url %}
|
{% if page.hero_image_url %}
|
||||||
<img class="hero" src="{{ page.hero_image_url }}">
|
<img class="hero" src="{{ page.hero_image_url }}">
|
||||||
|
|
23
website/common/templates/wagtailmetadata/parts/tags.html
Normal file
23
website/common/templates/wagtailmetadata/parts/tags.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{% extends "wagtailmetadata/parts/tags.html" %}
|
||||||
|
|
||||||
|
{% block twitter %}
|
||||||
|
{{ block.super }}
|
||||||
|
{% if object.reading_time %}
|
||||||
|
<meta name="twitter:label1" content="Reading time" />
|
||||||
|
<meta name="twitter:data1" content="{{ object.reading_time }} minutes" />
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block opengraph %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
<meta name="article:modified_time" content="{{ object.last_published_at|date:'c' }}" />
|
||||||
|
{% if object.date %}
|
||||||
|
<meta name="article:published_time" content="{{ object.date|date:'c' }}" />
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block meta %}
|
||||||
|
{{ block.super }}
|
||||||
|
<meta name="canonical" content="{{ object.get_meta_url }}" />
|
||||||
|
{% endblock %}
|
|
@ -35,7 +35,7 @@ class ContentPageTestCase(TestCase):
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_queries(self) -> None:
|
def test_queries(self) -> None:
|
||||||
with self.assertNumQueries(16):
|
with self.assertNumQueries(17):
|
||||||
self.client.get(self.page.url)
|
self.client.get(self.page.url)
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,5 +57,5 @@ class ListingPageTestCase(TestCase):
|
||||||
self.assertEqual(len(response.context["child_pages"]), 2)
|
self.assertEqual(len(response.context["child_pages"]), 2)
|
||||||
|
|
||||||
def test_queries(self) -> None:
|
def test_queries(self) -> None:
|
||||||
with self.assertNumQueries(19):
|
with self.assertNumQueries(20):
|
||||||
self.client.get(self.page.url)
|
self.client.get(self.page.url)
|
||||||
|
|
|
@ -2,12 +2,14 @@ from django.db import models
|
||||||
from django.http.request import HttpRequest
|
from django.http.request import HttpRequest
|
||||||
from wagtail.admin.panels import FieldPanel
|
from wagtail.admin.panels import FieldPanel
|
||||||
from wagtail.images import get_image_model_string
|
from wagtail.images import get_image_model_string
|
||||||
|
from wagtail.images.models import Image
|
||||||
|
from wagtailmetadata.models import WagtailImageMetadataMixin
|
||||||
|
|
||||||
from website.blog.models import BlogPostPage
|
from website.blog.models import BlogPostPage
|
||||||
from website.common.models import BasePage
|
from website.common.models import BasePage
|
||||||
|
|
||||||
|
|
||||||
class HomePage(BasePage):
|
class HomePage(BasePage, WagtailImageMetadataMixin):
|
||||||
max_count = 1
|
max_count = 1
|
||||||
|
|
||||||
heading = models.CharField(max_length=128, blank=True)
|
heading = models.CharField(max_length=128, blank=True)
|
||||||
|
@ -20,6 +22,21 @@ class HomePage(BasePage):
|
||||||
FieldPanel("image"),
|
FieldPanel("image"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_meta_url(self) -> str:
|
||||||
|
return self.full_url
|
||||||
|
|
||||||
|
def get_meta_image(self) -> Image | None:
|
||||||
|
return self.image
|
||||||
|
|
||||||
|
def get_meta_title(self) -> str:
|
||||||
|
return self.seo_title or self.title
|
||||||
|
|
||||||
|
def get_meta_description(self) -> str:
|
||||||
|
return self.search_description
|
||||||
|
|
||||||
|
def get_object_title(self) -> str:
|
||||||
|
return ""
|
||||||
|
|
||||||
def get_context(self, request: HttpRequest) -> dict:
|
def get_context(self, request: HttpRequest) -> dict:
|
||||||
from website.search.models import SearchPage
|
from website.search.models import SearchPage
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ INSTALLED_APPS = [
|
||||||
"wagtail.search",
|
"wagtail.search",
|
||||||
"wagtail.admin",
|
"wagtail.admin",
|
||||||
"wagtail",
|
"wagtail",
|
||||||
|
"wagtailmetadata",
|
||||||
"modelcluster",
|
"modelcluster",
|
||||||
"taggit",
|
"taggit",
|
||||||
"generic_chooser",
|
"generic_chooser",
|
||||||
|
|
Loading…
Reference in a new issue