Template tagでrequest.pathがActiveページか判別する
Blogなどで、メニュー/ナビなどlistタグを使って表示します。
htmlファイルで作ったサイトであれば簡単に表現できますが、
Djangoでは、テンプレートのみでは表現できません。
そこでTemplate tagを使って実現させましょう。
メニュー/ナビの仕様
- listタグで作成。
- カレントページには、classに"active"をつける
-
メニュー/ナビは Home(/), Blog(/blog/), About(/about/)とします。
home, aboutはFlatpagesで作成しています。 - listタグで構成されたメニュー/ナビは、base.html内にあるものとします。
settings.pyの編集
"django.core.context_processors.request"を使うため、settings.pyの"TEMPLATE_CONTEXT_PROCESSORS"に追加します。
settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.request', #追加
)
Blog表示のviews.py
views.py
from django.template import RequestContext
from django.shortcuts import render_to_response
…
def blog(request):
…
return render_to_response('blog/page.html', {…},
context_instance = RequestContext(request))
Template tag作成
activeタグを作成します。
tags.py
from django import template
register = template.Library()
@register.simple_tag
def active(request, pattern):
if request.path.startswith(pattern):
return "active"
return ""
テンプレートの作成
base.html(抜粋)
…
{% load tags %}
…
<ul>
<li><a class = {% active request "/" %}" href = "/">Home</a></li>
<li><a class = {% active request "/blog/" %}" href = "/blog/">Blog</a></li>
<li><a class = {% active request "/about/" %}" href = "/about/">About</a></li>
</ul>
…
検証
各ページにアクセスしてhtmlのソースを確認してみてください。
Blog, AboutにアクセスしたときHomeも"active"になってしまいます。
一見実現しているようですが、あともう一歩です。
Template tagとテンプレートの修正
"active"の判断はstartswithではなく、reモジュールを使います。
patternはurls.pyのように正規表現を使います。
tags .py
from django import template
register = template.Library()
@register simple_tag
def active(request, pattern):
import re
if re.search(pattern, request.path):
return 'active'
return ''
base.html
…
{% load tags %}
…
<ul>
<li><a class = {% active request "^/$" %}" href = "/">Home</a></li>
<li><a class = {% active request "^/blog/" %}" href = "/blog/">Blog</a></li>
<li><a class = {% active request "^/about/" %}" href = "/about/">About</a></li>
</ul>
…
これでrequest.pathごとに"active"をつけることができました。
あとはCSSを編集してデザインにあわせます。