add support for article specific og image
This commit is contained in:
parent
1d190fe182
commit
6b689704b0
5 changed files with 49 additions and 6 deletions
|
@ -69,8 +69,8 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||||
(
|
(
|
||||||
"Images",
|
"Images",
|
||||||
{
|
{
|
||||||
"fields": ("image_library",),
|
"fields": ("image_library", "og_image"),
|
||||||
"description": "Select an image from the Image Library.",
|
"description": "Select an image from the Image Library and optionally upload a specific Open Graph image for social sharing.",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
25
hub/services/migrations/0045_add_og_image_to_article.py
Normal file
25
hub/services/migrations/0045_add_og_image_to_article.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Generated by Django 5.2 on 2025-07-08 13:53
|
||||||
|
|
||||||
|
import hub.services.models.base
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("services", "0044_add_svg_support"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="article",
|
||||||
|
name="og_image",
|
||||||
|
field=models.ImageField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Optional Open Graph image for social sharing (max 1MB). If not provided, the article's main image will be used.",
|
||||||
|
null=True,
|
||||||
|
upload_to="article_og_images/",
|
||||||
|
validators=[hub.services.models.base.validate_image_size],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -51,6 +51,15 @@ class Article(ImageReference):
|
||||||
help_text="Link this article to a cloud provider",
|
help_text="Link this article to a cloud provider",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Open Graph image for social sharing
|
||||||
|
og_image = models.ImageField(
|
||||||
|
upload_to="article_og_images/",
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
validators=[validate_image_size],
|
||||||
|
help_text="Optional Open Graph image for social sharing (max 1MB). If not provided, the article's main image will be used."
|
||||||
|
)
|
||||||
|
|
||||||
# Publishing controls
|
# Publishing controls
|
||||||
is_published = models.BooleanField(
|
is_published = models.BooleanField(
|
||||||
default=False, help_text="Only published articles are visible to users"
|
default=False, help_text="Only published articles are visible to users"
|
||||||
|
@ -90,6 +99,15 @@ class Article(ImageReference):
|
||||||
return self.image_library.image
|
return self.image_library.image
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get_og_image(self):
|
||||||
|
"""Returns the Open Graph image for social sharing"""
|
||||||
|
# Use specific OG image if available
|
||||||
|
if self.og_image:
|
||||||
|
return self.og_image
|
||||||
|
# Fall back to main article image
|
||||||
|
return self.get_image
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def related_to(self):
|
def related_to(self):
|
||||||
"""Returns a string describing what this article is related to"""
|
"""Returns a string describing what this article is related to"""
|
||||||
|
|
|
@ -63,9 +63,9 @@ def social_meta_tags(context):
|
||||||
article = context["article"]
|
article = context["article"]
|
||||||
title = f"Servala - {article.title}"
|
title = f"Servala - {article.title}"
|
||||||
description = article.excerpt
|
description = article.excerpt
|
||||||
# Use article image if available, otherwise default
|
# Use OG image if available, otherwise fall back to article image, then default
|
||||||
if article.get_image:
|
if article.get_og_image:
|
||||||
image_url = request.build_absolute_uri(article.get_image.url)
|
image_url = request.build_absolute_uri(article.get_og_image.url)
|
||||||
|
|
||||||
# Determine og:type based on view
|
# Determine og:type based on view
|
||||||
og_type = "website" # default
|
og_type = "website" # default
|
||||||
|
|
2
uv.lock
generated
2
uv.lock
generated
|
@ -384,7 +384,7 @@ requires-dist = [
|
||||||
{ name = "django-import-export", specifier = ">=4.3.7" },
|
{ name = "django-import-export", specifier = ">=4.3.7" },
|
||||||
{ name = "django-jazzmin", specifier = ">=3.0.1" },
|
{ name = "django-jazzmin", specifier = ">=3.0.1" },
|
||||||
{ name = "django-nested-admin", specifier = ">=4.1.1" },
|
{ name = "django-nested-admin", specifier = ">=4.1.1" },
|
||||||
{ name = "django-prose-editor", extras = ["sanitize"], specifier = ">=0.10.3" },
|
{ name = "django-prose-editor", extras = ["sanitize"], specifier = ">=0.15.0" },
|
||||||
{ name = "django-schema-viewer", specifier = ">=0.5.2" },
|
{ name = "django-schema-viewer", specifier = ">=0.5.2" },
|
||||||
{ name = "djangorestframework", specifier = ">=3.15.2" },
|
{ name = "djangorestframework", specifier = ">=3.15.2" },
|
||||||
{ name = "environs", extras = ["django"], specifier = "~=14.0" },
|
{ name = "environs", extras = ["django"], specifier = "~=14.0" },
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue