指南:hreflang 与多语言¶
django-seo-suite 与 Django 的 i18n_patterns 集成,在页面和站点地图中生成一致的 hreflang 备选链接。两者都以同一份 LANGUAGES 配置为唯一数据源。
工作原理¶
build_hreflang_alternates 会对 settings.LANGUAGES 中的每种语言调用 Django 的 translate_url,生成一个由 HreflangAlt(lang, absolute_url) 命名元组组成的列表。把这个列表传给 SeoMetadata.partial(hreflang=...),{% seo_hreflang %} 标签就会渲染出 <link rel="alternate" hreflang="..."> 元素。
配置¶
确认 URL 配置使用了 i18n_patterns:
# urls.py
from django.conf.urls.i18n import i18n_patterns
from django.urls import path
urlpatterns = i18n_patterns(
path("articles/<slug:slug>/", ArticleDetail.as_view(), name="article-detail"),
path("articles/", ArticleList.as_view(), name="article-list"),
)
在 settings 中设置 LANGUAGES 和 LANGUAGE_CODE:
LANGUAGES = [
("en", "English"),
("fr", "French"),
("de", "German"),
]
LANGUAGE_CODE = "en"
USE_I18N = True
在详情视图中添加 hreflang¶
from django.views.generic import DetailView
from seo_suite.mixins import SeoViewMixin
from seo_suite.hreflang import build_hreflang_alternates
from seo_suite.metadata import SeoMetadata
from .models import Article
class ArticleDetail(SeoViewMixin, DetailView):
model = Article
def get_seo_metadata(self, context=None):
alternates = build_hreflang_alternates(
self.request.path,
self.request,
)
return SeoMetadata.partial(hreflang=alternates)
当请求路径为 /en/articles/my-article/,且 LANGUAGES = [("en", …),
("fr", …)]、LANGUAGE_CODE = "en" 时,输出如下:
<link rel="alternate" hreflang="en" href="https://example.com/en/articles/my-article/">
<link rel="alternate" hreflang="fr" href="https://example.com/fr/articles/my-article/">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/articles/my-article/">
控制 x-default¶
当 SEO_SUITE["HREFLANG_X_DEFAULT"] 为 True(默认值)时,会自动添加 x-default 备选链接,指向 settings.LANGUAGE_CODE 对应语言的 URL。
全局禁用:
仅在单次调用中禁用:
自定义语言列表¶
传入 languages 参数即可限制或重新排序备选链接:
alternates = build_hreflang_alternates(
self.request.path,
self.request,
languages=["en", "fr"], # only these two, regardless of LANGUAGES
)
在列表视图中添加 hreflang¶
from django.views.generic import ListView
from seo_suite.mixins import SeoListViewMixin
from seo_suite.hreflang import build_hreflang_alternates
from seo_suite.metadata import SeoMetadata
class ArticleList(SeoListViewMixin, ListView):
model = Article
seo_title = "Articles"
def get_seo_metadata(self, context=None):
alternates = build_hreflang_alternates(self.request.path, self.request)
return SeoMetadata.partial(hreflang=alternates)
Note
hreflang 是 整体替换 字段:只要优先级更高的层提供了 hreflang 列表,
就会完全替换低优先级层的列表。每个页面只在一个层(通常是视图)设置 hreflang。
模板渲染¶
{% seo_head %} 会自动渲染 hreflang。它内部使用的标签是 {% seo_hreflang %},也可以单独使用:
站点地图中的 hreflang¶
要在站点地图中输出 hreflang,请将 Django 内置的站点地图 i18n 支持与 SeoSitemap 配合使用。完整示例见站点地图指南。