指南:Open Graph 与社交分享图片

只要页面已经有 title、meta_description 和 canonical_url,就会自动生成可用的 Open Graph 和 Twitter 卡片标签。基础用法不需要任何额外配置。


自动输出的内容

解析器在最终确定元数据时,会用已解析的页面级字段填补 og 和 twitter 字典中的空缺:

标签 自动来源
og:title title(除非已设置 og:title)
og:description meta_description(除非已设置 og:description)
og:url canonical_url(除非已设置 og:url)
og:image og_image(除非已设置 og:image)
twitter:title og:title
twitter:description og:description
twitter:image og:image
twitter:card 有图片时为 "summary_large_image",否则为 "summary"

og:type 的默认值 "website" 来自 SEO_SUITE["DEFAULTS"]["og"]。


添加社交分享图片

最简单的做法是映射你的图片字段:

class Article(SeoModelMixin, models.Model):
    cover = models.ImageField(upload_to="covers/", blank=True)

    SEO_FIELD_MAP = {"og_image": "cover"}

如果字段名本身就是约定名称之一(image、cover_image、photo、thumbnail、og_image),则完全不需要映射。

设置了 og_image 之后,og:image 和 twitter:image 都会自动填充,twitter:card 也会变为 "summary_large_image"。


按模型设置 og:type

og:type 默认为 "website"。文章和博客帖子通常应使用 "article",可以通过 og 字典覆盖:

class Article(SeoModelMixin, models.Model):
    ...

    def get_seo_metadata(self, context=None):
        from seo_suite.metadata import SeoMetadata
        base = super().get_seo_metadata(context)
        og_override = SeoMetadata.partial(og={"type": "article"})
        return SeoMetadata.merge(base, og_override)

更简洁的方式是在视图层设置:

class ArticleDetail(SeoViewMixin, DetailView):
    model = Article

    def get_seo_metadata(self, context=None):
        from seo_suite.metadata import SeoMetadata
        return SeoMetadata.partial(og={"type": "article"})

自定义 og: 和 twitter: 标签

任何 Open Graph 或 Twitter 标签都可以作为键放进对应的字典。键名是去掉 og: 或 twitter: 前缀之后的部分:

class ArticleDetail(SeoViewMixin, DetailView):
    model = Article

    def get_seo_metadata(self, context=None):
        from seo_suite.metadata import SeoMetadata
        return SeoMetadata.partial(
            og={
                "type": "article",
                "site_name": "My Blog",
                "locale": "en_US",
            },
            twitter={
                "site": "@myblog",
                "creator": "@author",
            },
        )

og 和 twitter 字典在各层之间是深度合并的(见解析机制):高优先级层的键逐个覆盖低优先级层的同名键,整个字典不会被整体替换。


全站统一的 og:site_name

og:site_name 通常在全站范围内只设置一次。把它加到全局默认值中:

SEO_SUITE = {
    "DEFAULTS": {
        "title_suffix": " | My Blog",
        "robots": "index,follow",
        "og": {
            "type": "website",
            "site_name": "My Blog",
        },
    },
}

所有页面都会继承这个默认的 og:site_name;任何高优先级层仍可按页面覆盖 og:type,而不会影响 og:site_name。


在特定页面上隐藏 og 或 twitter 标签

把某个键设为 None 或 "",即可在特定页面上隐藏对应标签。由于 og 和 twitter 字典是深度合并的,隐藏一个键不会清掉其他键:

class InternalToolView(SeoViewMixin, TemplateView):
    def get_seo_metadata(self, context=None):
        from seo_suite.metadata import SeoMetadata
        return SeoMetadata.partial(og={"image": None})  # suppress og:image only

渲染后的 HTML 输出

对于一篇带封面图的文章页面,渲染结果类似于:

<meta property="og:type" content="article">
<meta property="og:site_name" content="My Blog">
<meta property="og:title" content="How Django Routing Works">
<meta property="og:description" content="A deep dive into URL resolvers.">
<meta property="og:url" content="https://example.com/articles/how-django-routing-works/">
<meta property="og:image" content="https://example.com/media/covers/routing.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="How Django Routing Works">
<meta name="twitter:description" content="A deep dive into URL resolvers.">
<meta name="twitter:image" content="https://example.com/media/covers/routing.jpg">