スポンサーサイト

0

    一定期間更新がないため広告を表示しています


    • 2014.12.23 Tuesday
    • -
    • -
    • -
    • -
    • -
    • by スポンサードリンク

    日本語テキストをtruncate@django(Python全般にも??)

    0
      最近すっかり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の文字数が指定文字数を超えない範囲で止めれば近いことは実現できそうです♪


      スポンサーサイト

      0

        • 2014.12.23 Tuesday
        • -
        • 09:43
        • -
        • -
        • -
        • -
        • by スポンサードリンク

        コメント
        > 力不足のため「何文字」と指定して切る方法

        バイト単位ではなく、文字数単位で切る、という処理が何で言語自体にないんでしょうね。

        ここ半年くらいに出た Python の本にそんな処理/関数があったような、なかったような (一文字の途中で切れるから注意したほうがいい、みたないコラムだったかなぁ...)
        たぶんこれで。
        >>> a = 'あいうえお'
        >>> unicode(a, 'utf8')[:1].encode('utf8')


        もっときちんとした手があるきがする。切り取るの自体はunicodeにしてスライスするだけなんだけれど、そのあとのencodeなんだかなぁな気がしますね。
        • everes
        • 2007/05/25 7:02 PM
        yamazakiさん

        シングルバイト使いさんが開発した言語&フレームワークなので、そこは諦めてます^^;
        Python本、土日に書店で探してみたいと思います^^


        everesさん

        なるほど!それなら文字単位で指定できそうですね。
        個人的にはPHPよりPythonのほうが、こういうバイト単位の文字列処理関係は充実してる印象があります^^
        PHPだとブラックボックスですが、Pythonだと自由度が高いというか。
        > unicode(a, 'utf8')[:1]

        あっ、そうだそうだ、こんな感じだった気がします。。

        今、本見返してみました。ats さんの「みんなの Python」のP.44, 45あたりです。

        他の書籍でも似たような解説を見たような気がしてきました。結構オーソドックスな日本語処理、Python の unicode の考え方 ? なのでしょうね。
        コメントする








           
        この記事のトラックバックURL
        トラックバック
        Djang Project: Changeset 5333 今夜Updateします Google Code: django-opendocument django-helpers things Django Snippets: Tablify templatetag URL Query Parameter Menu Blog: 日本語テキストをtruncate@django(Python全般にも??) Truncate Characters Filte
        • 常山日記
        • 2007/05/25 7:52 PM

        PR

        calendar

        S M T W T F S
              1
        2345678
        9101112131415
        16171819202122
        23242526272829
        3031     
        << July 2017 >>

        twitter

        selected entries

        categories

        archives

        recent comment

        • 結局CodeIgniter用汎用Modelクラス&汎用CRUDスクリプトを書きました
          プログラマー
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          ななうぇぶ
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • WindowsのPCで開発するphperがxhprofを使う方法
          ななうぇぶ
        • WindowsのPCで開発するphperがxhprofを使う方法
          川本
        • [バッドノウハウ]Symfony2で別テーブルの集計項目を一覧に含めたいとき
          よし
        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
          77web
        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
          ktz

        recent trackback

        • HTMLの表(TABLE)のセル(TD)に斜線を引くjavascriptライブラリ slash.js 作っちゃいました
          常山日記
        • django対symfony 日本語メール送信(その1 symfony編)
          CPA-LABテクニカル
        • CodeIgniterでユーザー認証
          されどLAMPな日々
        • 久々にdjangoを最新版にしたらHTMLがエスケープされちゃった!!(解決済み)
          常山日記
        • FastCGIを諦めてmod_pythonを使う。Apacheのアップグレード
          サーバー用語集
        • さくらインターネット、sqlite3でdjango@CGI版を使う際の設定メモ
          常山日記
        • さくらインターネット スタンダードプランでdjango使ってる方、DBは?
          mitszoの日記
        • python多次元リストをsort(並べ替え)する方法?
          mitszoの日記
        • フォームから送信した値とrequest.POSTの挙動($_POST@PHPとの比較)
          Humming Via Kitchen
        • 日本語テキストをtruncate@django(Python全般にも??)
          常山日記

        recommend

        links

        profile

        search this site.

        others

        mobile

        qrcode

        powered

        無料ブログ作成サービス JUGEM