on Aug 22nd, 2009用 Ajax 方式实现 Django Comments 提交

Django 自带的 Comments 模块还蛮好用的,但是提交的时候貌似有点麻烦,虽然可以手动去掉那个预览的按钮,只留下提交按钮,但还是想用户体验更好一些,用 Ajax 的方式来改进评论的提交。

想要的效果很简单,用户写完评论,点击提交按钮,这时候出现 loading 图标,显示正在提交,提交成功后,用 YFT 的方式把刚才的评论加到评论列表最后,同时评论数加一,loading 图标消失。当然,需要用到我最喜欢的 jQuery 和她的伙伴 Effect.Highlight

在我的页面中,需要对每一个产品作评论,于是在 product_detail.html 的头部,加上如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<script type="text/javascript" charset="utf-8">
    function bindComment() {
        $('#comments form').submit(function() {
            $('input[type=submit]').attr('disabled', 'disabled');
            $.ajax({
                type: "POST",
                data: $('#comments form').serialize(),
                url: "{% comment_form_target %}",
                cache: false,
                dataType: "html",
                success: function(html, textStatus) {
                    n = Number($('#commentCount').text());
                    c = $(html).find('[class^=comment]:last');
                    c.hide();
                   
                    if (n == 0)
                    {
                        $('h2.comment').after(c);
                    }
                    else
                    {
                        $('[class^=comment]:last').after(c);
                    }
                   
                    $('#commentCount').text(n+1);
                    c.effect("highlight", {}, 5000);
                    $('input[type=submit]').removeAttr('disabled');
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert('Sorry, your comment was unable to be posted at this time. Please try later.');
                }
            });
            return false;
        });
    }
   
    $(document).ready(function() {
        bindComment();
        $("#loading").bind("ajaxSend", function() {
            $(this).show();
        }).bind("ajaxComplete", function() {
            $(this).hide();
        });
    });
</script>

然后,需要在 Submit 按钮下加个隐藏的 loading 图标:

1
<span id="loading"><img src="/media/loading.gif" />Submitting your comment, please wait...</span>

最后,记得在 css 文件中添加 loading 的样式,这样评论的改进就完成了。当然还可以加上对提交数据的验证和提示,通过 jQuery,实现起来会很简单。

on Aug 12th, 2009Windows 下 Pidgin 字体设置

界面字体设置

修改 C:\Program Files\Common Files\GTK\2.0\etc\gtk-2.0\gtkrc 就可以了,比如:

1
2
3
gtk-font-name = "SimSun 9"

gtk-theme-name = "Raleigh"

对话框的字体设置

在 C:\Program Files\Common Files\GTK\2.0\etc\pango\pango.aliases 中添加一行:

1
msst = "SimSun"

在 C:\Program Files\Common Files\GTK\2.0\etc\gtk-2.0\ 下新建文件 gtkrc.zh_CN,输入内容:

1
2
3
4
5
6
7
style "user-font" {
    font_name = "msst 9"
}

widget_class "*" style "user-font"

gtk-font-name="msst 9"

这也是修改 GTK 程序界面的方法。

on Jun 18th, 2009Greasemonkey 技巧

Greasemonkey 会把对象包裹起来返回 XPCNativeWrapper,写 JS 的时候需要留心。下面这些要点来自 Greasemonkey Hacks

1. 调用函数

1
2
3
4
5
//工作
window.setTimeout(my_func, 1000)

//不工作
window.setTimeout("my_func()", 1000)

2. 事件处理

1
2
3
4
5
6
7
8
9
10
//工作
var elmLink = document.getElementById('somelink');
elmLink.addEventListener("click", my_func, true);

//不工作
var elmLink = document.getElementById('somelink');
elmLink.onclick = my_func;

var elmLink = document.getElementById('somelink');
elmLink.onclick = 'my_func(this)';

3. 命名表单和表单元素

1
2
3
4
<!--假如有表单-->
<form id="gs">
    <input name="q" type="text" value="foo" />
</form>
1
2
3
4
5
6
7
//工作
var form = document.forms.namedItem("gs");
var input = form.elements.namedItem("q");
var q = input.value;

//不工作
var q = document.gs.q.value;

4. 自定义属性

1
2
3
4
5
6
7
//工作
var elmFoo = document.getElementById('foo');
elmFoo.setAttribute('myProperty', 'bar');

//不工作
var elmFoo = document.getElementById('foo');
elmFoo.myProperty = 'bar';

5. 迭代集合

1
2
3
4
5
6
7
8
9
10
11
//工作
for (var i = 0; i &lt; arInputs.length; i++) {
    var elmInput = arInputs[i];
    …
}

//不工作
var arInputs = document.getElementsByTagName("input");
for (var elmInput in arInputs) {
    …
}

6. scrollIntoView

1
2
3
4
5
6
7
8
//工作
var elmFoo = document.getElementById('foo');
var elmUnderlyingFoo = elmFoo.wrappedJSObject || elmFoo;
elmUnderlyingFoo.scrollIntoView();

//不工作
var elmFoo = document.getElementById('foo');
elmFoo.scrollIntoView();

7. location

1
2
3
4
5
//工作
window.location.href = "http://example.com/";

//不工作
window.location = "http://example.com/";

8. 调用远程页面脚本

1
2
3
4
5
6
7
8
9
//工作
var searchForm = getNode("s");
searchForm.elements.namedItem("q").value = this.getRunnableQuery();
top.js._MH_OnSearch(unsafeWindow, 0);

//不工作
var searchForm = getNode("s");
searchForm.elements.namedItem("q").value = this.getRunnableQuery();
top.js._MH_OnSearch(window, 0);

9. watch

1
2
3
4
5
6
7
//工作
unsafeWindow.watch("location", watchLocation);
unsafeWindow.location.watch("href", watchLocation);

//不工作
window.watch("location", watchLocation);
window.location.watch("href", watchLocation);

10. 样式

1
2
3
4
5
6
7
8
//工作
var elmFoo = document.getElementById("foo");
elmFoo.style.margin = 0;
elmFoo.style.padding = 0;

//不工作
var elmFoo = document.getElementById("foo");
elmFoo.setAttribute("style", "margin:0; padding:0;");

on Jun 8th, 2009Peterzahlt Auto Click

Peterzahlt 很不错,天下竟然有免费的午餐。不过现在学精了,会在中途插播广告(人家也要吃饭的嘛),过了 10 分钟以后,会随机出现 5、6 次广告,如果在 30 秒之内不点击的话就自动切断,够狠啊。这样就必须一直紧盯着它广告,万一漏点就要重新排队,很长很长的队哦。

不过还好有强大的 Firefox,再加上 Greasemonkey,那么这件非常不人性化的事情就可以由机器代劳了。

假设你已经装好 Greasemonkey,那么点击安装就可以了。代码很简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
// ==UserScript==
// @name           Peterzahlt Auto Click
// @namespace      http://userscripts.org/users/ant21
// @description    Auto click Peterzahlt ads and you can lie on bed to call.
// @include        http://www.peterzahlt.de/*
// ==/UserScript==

window.detect = function()
{
    location.href = "javascript:void(clickbanner(0));"; //click banner
}

window.setInterval(detect, 10000);

on May 29th, 2009Google Chrome Nightly Builds

Google Chrome 3.0 Dev 版已经放出,可以从这里下载,非常不错哦。而且还有一个小工具可以帮你检测最新版本并下载。想要为 Chrome 开发扩展的话,官方的开发者老家ChromePlugins 都不容错过哦。

on May 28th, 2009easy_install uninstall

Sphinx 0.6.1 没有 0.5.1 好用,而且用来编译 Django 文档时会出错。用 easy_install 安装的,调用的时候总是默认选择了最新版,没找到切换版本的方法,还是把 0.6.1 卸载了吧。运行命令:

1
easy_install -m PackageName

两遍以后,再调用 Sphinx 就会切换到 0.5.1 版本了。

on May 4th, 2009WordPress 2.7.1 乱码

貌似从用上 WP 乱码就如影随形,现在倒也见怪不怪了。今天鼓足勇气升级到 2.7.1 还是乱码,手动解决吧。

wp-includes 目录下,wp-db.php 在 348 行

1
$this->select($dbname);

的上面加上

1
mysql_query(”SET NAMES utf8″,$this->dbh);

就行了。

on May 3rd, 2009痘,逗?

好笑啊,想知道,从脸上的痘如何上升到苦难的生活。或许已经惯于用一种悲观和敌对的态度来看待周遭的人和事。再通过自己的放大镜来无休止的放大,好让自己觉得受了天大的委屈,全世界都因为这点鸡毛蒜皮而蠢蠢欲动、风起云涌。或许时刻生活在这种感觉中才会让自己觉得踏实和舒服,我痛苦我存在?

生活本就是充满亿万种可能,风平浪静也好,风起云涌也好,乐也好,苦也好。本来如此,更不必去寻个是非曲直好坏享乐苦难的来头上安头,担得起才是真丈夫,一来一档,二来二收,找什么葛藤往自己身上遮羞。歇了吧。

两个黄鹂鸣翠柳,一行白鹭上青天。

美!

on May 3rd, 2009diggfoto hack

diggfoto 上的图片还蛮不错的,但是要一张一张去点确实有点不人道(总在期望下一张更精彩?),下面的程序可以帮忙把它的图片都下回来,事先最好准备一个 diggfoto 文件夹,嘿嘿。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#! /usr/bin/env python
#coding=utf-8

import os
import sys
import urllib
import urllib2
from BeautifulSoup import BeautifulSoup

def download(url='http://diggfoto.com/'):    
    try:
        r = urllib2.urlopen(url)
        page = r.read()
       
        soup = BeautifulSoup(page)
        entry = soup.find('div', 'entry')
        a = entry.find('a')
        nextLink = a['href']
        img = a.find('img')
        imageUrl = img['src']
        dotindex = imageUrl.rindex('.')        
    except AttributeError, e:
        print e
    except IndexError, e:
        print e
    except UnicodeDecodeError, e:
        print e
    except:
        print 'Oops'
    else:        
        if len(img['alt']) == 0:
            slash = url.rfind('/', 0, len(url)-2)
            rand = url[slash+1:url.rfind('/')]
        else:
            rand = img['alt']
       
        if not os.path.exists('diggfoto'):
            print 'Is there a directory named diggfoto?'
            sys.exit(0)
       
        name = os.path.join('diggfoto', rand + imageUrl[dotindex:dotindex+4])
        exist = os.path.exists(name)

        if imageUrl and not exist:
            try:
                print 'Downloading Image ==> %s' % name
            except:
                print 'Downloading Image ...'
            try:
                urllib.urlretrieve(imageUrl, name)
            except:
                download(nextLink)
       
        if nextLink:
            print 'Next url ==> %s' % nextLink
            if nextLink.endswith('tags/') or nextLink.endswith('archive/') \
                or nextLink.endswith('about/'):
                print 'Complete'
            else:
                download(nextLink)
   
if __name__ == "__main__":
    sys.exit(download())

on May 2nd, 2009How to get a girl