nephila / django-meta

Pluggable app to allow Django developers to quickly add meta tags and OpenGraph, Twitter, and Google Plus properties to their HTML responses.
https://django-meta.readthedocs.io
Other
477 stars 68 forks source link

Object_type property seems to have no effect on og:type because of the defaults #186

Open myriadhero opened 9 months ago

myriadhero commented 9 months ago

Description

The doc says:

object_type

This key is used to render the og:type property.

however, when adding it to the model _metadata, I could only get og:type Article. .as_meta() method outputted object_type of my choosing but og_type is always set as Article.

-> Setting og_type instead of object_type fixes the issue, but it doesn't seem to be what the docs recommend?

Steps to reproduce

  1. Set object_type: 'website' in _metadata; or even in settings.py of the django site setMETA_SITE_TYPE = "website"
  2. Observe the object_type gets assigned correctly but the template renders og:type as Article

Versions

Python 3.11, Django 4.2.7, django-meta 2.4.0

Expected behaviour

Docs seem to imply that setting object_type or META_SITE_TYPE will have effect on og:type.

Actual behaviour

Object type seems to have no effect on og:type because of the defaults

Additional information

The template (meta/meta.html) checks for og_type first:

        {% if meta.og_type %}{% og_prop 'type' meta.og_type %}
        {% elif meta.object_type %}{% og_prop 'type' meta.object_type %}{% endif %}

og_type gets filled with defaults, so it'll never fail over. It also doesn't get filled with META_SITE_TYPE or object_type during meta building as far as i understand.

myriadhero commented 9 months ago

My model looks like this:

from meta.models import ModelMeta

class SiteIdentity(ModelMeta, models.Model):
    title = models.CharField(max_length=100)
    seo_description = models.TextField(
        blank=True, help_text="Used in SEO meta tags, should be 50-160 characters long"
    )
    seo_keywords = models.CharField(
        max_length=250,
        blank=True,
        help_text="List of words in SEO meta tags, eg 'blog, django, python' without quotes, comma separated",
    )
    logo_title = models.ImageField(
        upload_to="site_identity/", blank=True, help_text="Used for the main top logo"
    )
    logo_square = models.ImageField(
        upload_to="site_identity/",
        blank=True,
        help_text="Used for seo and other places where a square logo is needed",
    )
    favicon = models.ImageField(upload_to="site_identity/", blank=True)

    _metadata = {
        "title": "title",
        "description": "seo_description",
        "keywords": "get_seo_keywords",
        "image": "get_logo_square_url",
        # "og_type": "Website", # adding this fixes the issue
        "object_type": "Website",
    }

    def get_logo_square_url(self):
        return self.logo_square.url if self.logo_square else None

    def get_seo_keywords(self):
        return (
            [
                stripped_word
                for word in self.seo_keywords.split(",")
                if (stripped_word := word.strip())
            ]
            if self.seo_keywords
            else None
        )

my settings.py:

META_USE_SITES = True
META_USE_OG_PROPERTIES = True
META_USE_TWITTER_PROPERTIES = True
META_SITE_PROTOCOL = "http" if DEBUG else "https"
META_IMAGE_URL = MEDIA_URL
META_SITE_TYPE = "Website"
myriadhero commented 9 months ago

I would offer to help fix this, but I'm not super confident and I'd need guidance as I'm a beginner and I'm not sure whether the issue is with docs or my understanding or the code. 🤔😅

protoroto commented 9 months ago

@myriadhero Thanks for reporting this: I'll have a look into it tomorrow and get back to you!