最近すっかりPHP&symfonyを捨ててdjangoばかり使ってます(汗
さて、仕事(一応プログラマではなくWEB屋でっす^^;)柄、主に完パケ納品できるCMS・ブログ系を作ることを念頭においてdjangoをあれこれ触ってるわけですが、そうすると必然的に「コンテンツの概要」を表示して「続きを読む」ってやつをやりたいわけです。そう、MovableTypeにもあるアレ。
もとのテキストが英語(に限らず、シングルバイト文字のみの言語)なら話は簡単です。
何語で区切る・何文字で区切るってのが間違いようがないので。
事実、djangoの組み込みフィルタにもありますよね<truncatewords
ところが、日本語(に限らず、マルチバイト文字を使う言語)だと、単純に「何文字」で区切ると、ひとつの文字の途中で切られてしまうことがありえます。
これがあまりパソコンに詳しくないクライアントに見つかると、「文字化け!文字化け!早くなんとかして!」と大騒ぎして電話がかかってくるのでもう大変(爆
その点、MovableTypeの概要(MTEntryExcerpt)は変なところで切れたのを見たことが無いので、何かうまいことやってるんだと思うんです。つまり、方法はある!ということ。
本来であれば、この時点でMovaleTypeのコード読みをして(Perlキラーイだけど。泣)、どうやって日本語でtruncate処理をしているのか解明してみるべきなんでしょう。
が、やはりPerl苦手の私がPerlのコード読みをするとハマる可能性が高いこと(恥)、まとまった勉強時間が取れないこと、から判断して、簡易truncate処理を考え付きました。
使うのは例によってカスタムフィルタです。(←最近こればっかり。汗)
myproject > myapp > templatetags > truncate.py
from django import template
import string
register = template.Library()
@register.filter
def truncate_first_break(value):
list = value.rsplit("¥n")
str = list.pop(0)
return str
@register.filter
def truncate_second_break(value):
list = value.rsplit("¥n")
str = list.pop(0) + list.pop(1)
return str
ハイ、なんとも原始的でお粗末です。
スミマセン。
まず、日本語の文章を書いていると「改行」というのは一まとまりの文章の区切りになりやすいということに着目しました。(これが文系出身の強み?)
そこで、生のテキストをフィルタが受け取ったら(value)、それを¥n(改行コード)で切ります(rsplit("¥n"))。
区切られたテキストをpop()で取ってきて、テキスト内の最初の改行まで(上記truncate_first_break)又はテキスト内の2番目の改行まで(上記truncate_second_break)だけを返します。
すると…
「1番目の改行はここです→
2番目の改行はココです→
3番目の改行はありません」
という文章がobject.bodyに入っているとして、
テンプレートに
{{ object.body|truncate_first_break }}...<a href="{{ object.get_absolute_url }}">続きを読む</a>
と書けば
「1番目の改行はここです→...続きを読む」
という表示ができますし、
テンプレートに
{{ object.body|truncate_second_break }}...<a href="{{ object.get_absolute_url }}">続きを読む</a>
と書けば
「1番目の改行はここです→2番目の改行はココです→...続きを読む」
という表示ができます。
力不足のため「何文字」と指定して切る方法はまだ思いつきませんが(汗
これで結構代用がききそうな気がしませんか(^−^)
「何文字以内」で良いのであれば、list.popをループで廻して、strの文字数が指定文字数を超えない範囲で止めれば近いことは実現できそうです♪