2008年8月10日

有备无患:truncatehanzi - 按字数截取中文的 Django template filter

Django 自带的一个模板过滤器(Template Filter)truncatewords,可以按单词数截取字符串生成摘要。不过,truncatewords 只能用空格来分隔单词,对汉字就无能为力了。所以,我写了另一个模板过滤器 truncatehanzi,它通过 unicode 编码来区分西方字符和 CJK 汉字,对包括英语字母在内的西方字符以空格或其他符号来分隔并计算单词数,而对 CJK 汉字则是按字数计算。

使用方法和 truncatewords 一样,
{{ value|truncatehanzi:6 }}
如果 value 为“截取English、Γρεεκ等字母语言和CJK汉字。”,输出“截取English、Γρεεκ等字...”。

代码分为两个部分,截取汉字的脚本 truncate_hanzi.py 和生成过滤器的脚本 filters.py。

truncate_hanzi.py

 # -*- coding: UTF-8 -*-

import re
from django.utils.encoding import force_unicode
from django.utils.functional import allow_lazy

def truncate_hanzi(s, num):
    s = force_unicode(s)
    length = int(num)
    if length <= 0:
        return u'...'
    # Set up regex for alphanumeric characters
    # \u00c0-\u02af: Latin
    # \u0370-\u1fff: Greek and alphabet characters in other language
    re_alnum = re.compile(ur'[a-zA-Z0-9_\-\u00c0-\u02af\u0370-\u1fff]', re.U)
    # Set up regex for hanzi
    # \u3040-\ufaff: CJK characters
    re_hanzi = re.compile(ur'[\u3040-\ufaff]', re.U)
    hanzi = u''
    hanzi_len = 0
    word_temp = u''
    for char in s:
        # Check for alphabet characters
        if re_alnum.match(char):
            word_temp += char
            continue
        if word_temp:
            hanzi += word_temp
            hanzi_len += 1
            word_temp = ''
        # Check for length
        if hanzi_len >= length:
            if not hanzi.endswith('...'):
                hanzi += '...'
                break
        # Check for hanzi
        if re_hanzi.match(char):
            hanzi_len += 1
        hanzi += char
    hanzi += word_temp
    return hanzi
truncate_hanzi = allow_lazy(truncate_hanzi, unicode)

def demo():
    print truncate_hanzi('截取段落工具,支持English、Γρεεκ等字母语言和CJK汉字。', 6)
    print truncate_hanzi('截取段落工具,支持English、Γρεεκ等字母语言和CJK汉字。', 11)
    print truncate_hanzi('截取段落工具,支持English、Γρεεκ等字母语言和CJK汉字。', 20)

if __name__ == '__main__':
    demo()

filters.py

 # -*- coding: UTF-8 -*-
from django.template import Library
from django.template.defaultfilters import stringfilter

register = Library()

@stringfilter
def truncatehanzi(value, arg):
    """
    Truncates a string after a certain number of words including
    alphanumeric and CJK characters.

    Argument: Number of words to truncate after.
    """
    from truncate_hanzi import truncate_hanzi
    try:
        length = int(arg)
    except ValueError: # Invalid literal for int().
        return value # Fail silently.
    return truncate_hanzi(value, length)
truncatehanzi.is_safe = True

register.filter('truncatehanzi', truncatehanzi)

2008年8月6日

有备无患:一个 jQuery 的时间选择插件

Yet another jQuery time picker plugin. Google 上兜了一圈,没找到中意的时间选择(Time Picker)插件,于是自己写了一个。timepicker 是一个弹出式的对话框,分为上下两个部分,上半部分是可以分别设定时分秒的计数器,下半部分提供一些常用的时间选项,比如“Now”,“Noon”,“8 p.m.”等。通过聚焦(focus)到相应的 input 控件,可以激活 timepicker。选择好时间后,点击对话框底部的 Close 按钮会将结果保存到 input 控件中,而点击 Clear 按钮会清除 input 控件中已存的时间。键盘上的 Tab 键和 ESC 键也有与之对应的功能。

这是我的第一个 jQuery 插件,欢迎大家使用,我也会继续完善这个插件。如果有任何的 Bug,建议和意见,欢迎在文章后留言,或者 Email 给我,或者在插件的主页写下你的评论。:-)

使用方法

$('#time-picker').timepicker();

截图


Yet another jQuery time picker plugin.

演示

演示网址



下载

你可以选择下载压缩档。
下载

或者用 Git 从架设在 GitHub 的软件仓库中检出源代码使用。
$ git clone git://github.com/wuyuntao/timepicker.git

2008年8月4日

有备无患:Google Reader 风的豆瓣广播 widget

最近,豆瓣连续发布了几个重要的 API 更新,包括了备受期待的友邻广播相关的接口。特别是广播的 API,自从用豆瓣广播取代了 Twitter 当作吐口水的工具之后,我一直期待广播也有像 TwitterFox 一样的客户端,有个 widget 可以在 blog 上显示最近的状态,而这些都是要以广播的 API 为基础的。

言归正传,我写了一个类似 Google Reader 的分享阅读剪辑(Shared Item Clips)风格的豆瓣广播 widget,可以放在 blog 的侧边栏。使用的方法很简单,只需要将下面这段代码插入到你的 blog 模板中。(wyt:如果不知道怎么操作的话,可以参考豆瓣秀指南。)

<script type="text/javascript" src="http://luliban.com/scripts/miniblog.js?username=wyt&amp;maxresults=16&amp;style=blue"></script>

注意上面代码中粗体的部分,首先我们要将``wyt``换成自己的用户名;``maxresults``为 widget 显示的广播条数(最大值为50,默认为10,可以省略);``style``表示 widget 的配色,和 Google Reader 分享阅读的配色基本一致,包括:black、blue、gray、green、khaki、pink、slate 和 none。默认为 green,如果输入的 style 不在上述配色中,则返回 none。none 为不带任何 style 的原始 HTML,适合希望自定义广播风格的 blogger。

最终效果如下图。想看看实物 demo 的话,可以点击这里。要说明的是,看得到漂亮的圆角效果的只有 Firefox 用户(wyt:这也是 Google Reader 的风格之一,:p),IE、OperaSafari 用户对不住了。如果有任何的建议或意见,欢迎留言 :-)

订阅我的博客

搜索我的博客

正在加载...

我的豆瓣广播

分享阅读

豆瓣秀

休斯敦火箭

我的文章归档

版权申明