mezzanine blog に rel=”next”とrel=”prev” を設定する


mezzanine blog の ページング表示した際の 2ページ目とか、3ページ目などが、
検索エンジンにindexされていました。
そもそも表示内容が記事量で変わっていくpage なので、
indexされないようにする、または、いい感じで表示できる方法がないか、調べてみました。

一般的なrel=”next”とrel=”prev” の説明

ざっくりの理解だと、

  1. 全記事をリスト表示したページがある場合は、canonical を使う
  2. 全記事をリスト表示したページがない場合は、next, prev を使う

ということかと思います。
当Blog は、2. なので、next, prev を使用します。

以下のサイトが参考になりました


django の pagination

django の pagination は、標準機能もあり、
plugin も いろいろありますが、pagination のコア機能は、mezzanineで持っているようなので、
pluginインストールはちょっと導入は大げさな気がしましたので、
mezzanine の標準機能で実装する方向で考えます。


mezzanine の pagination 機能

実際にpagination を使っているmezzanine/blog_post_list.html at master · stephenmcd/mezzanine を見てみると、
{% pagination_for blog_posts %} というタグを使って出力しています。
タグの実態は、mezzanine/mezzanine_tags.py at master · stephenmcd/mezzanine にあり、以下のような実装になっています。
そこまで、難しいことはやっていないように見えるので、
この実装を参考に、`<head>タグ内に埋め込むテンプレートタグを作成します。

@register.inclusion_tag("includes/pagination.html", takes_context=True)
def pagination_for(context, current_page, page_var="page", exclude_vars=""):
    """
    Include the pagination template and data for persisting querystring
    in pagination links. Can also contain a comma separated string of
    var names in the current querystring to exclude from the pagination
    links, via the ``exclude_vars`` arg.
    """
    querystring = context["request"].GET.copy()
    exclude_vars = [v for v in exclude_vars.split(",") if v] + [page_var]
    for exclude_var in exclude_vars:
        if exclude_var in querystring:
            del querystring[exclude_var]
    querystring = querystring.urlencode()
    return {
        "current_page": current_page,
        "querystring": querystring,
        "page_var": page_var,
    }

実装内容

1.tags.py

template html を作った感じですと、
@register.inclusion_tag で読み込みtemplate html のみ変更すれば、OKでした。
以下のようになりました。
tags.py は django app の templatetags ディレクトリ内に配置します。

from __future__ import absolute_import, division, unicode_literals

from mezzanine import template

register = template.Library()

@register.inclusion_tag("includes/pagination_prev_next.html", takes_context=True)
def pagination_prev_next_for(context, current_page, page_var="page", exclude_vars=""):
    querystring = context["request"].GET.copy()
    exclude_vars = [v for v in exclude_vars.split(",") if v] + [page_var]
    for exclude_var in exclude_vars:
        if exclude_var in querystring:
            del querystring[exclude_var]
    querystring = querystring.urlencode()
    return {
        "current_page": current_page,
        "querystring": querystring,
        "page_var": page_var,
    }

2.pagination_prev_next.html

template html の実装は以下の通りです。
前ページがあれば、prev を、 次ページがあれば、next を実装します。
template.html は template ディレクトリ内に配置します。

{% if current_page.has_previous %}
    <link rel=”prev”
          href="?{{ page_var }}={{ current_page.previous_page_number }}{% if querystring %}&{{ querystring }}{% endif %}"/>
{% endif %}
{% if current_page.has_next %}
    <link rel=”next”
          href="?{{ page_var }}={{ current_page.next_page_number }}{% if querystring %}&{{ querystring }}{% endif %}"/>
{% endif %}

3.blog_post_list.html

2箇所編集します。

    1. で作成したtagを、ロード する
{% load i18n mezzanine_tags blog_tags keyword_tags disqus_tags xxx_tags %}
  • extrahead ブロックでテンプレートを呼び出す。
{% block extra_head%}
    {% pagination_prev_next_for blog_posts %}
{% endblock %}

補足

  • 検索結果ページについて

検索結果ページであるmezzanine/search_results.html at master · stephenmcd/mezzanine にも、
{% pagination_for blog_posts %} は含まれますが、
こちらは、noindexタグがありますので、入れる必要がなく追加しませんでした。

{% block extra_head %}
<meta name="robots" content="noindex">
{% endblock %}

以上です。

コメント