Author: 芳草苑主

  • 汇丰在我心中形象大损

    最近发生几件事情让我觉得汇丰大大的不好。

    首先,它不肯给我按揭。也罢,就这个只能说它古板。

    随后,我又发现同品种存款利率汇丰仅是人家的1/4!

  • Magento adminhtml getUrl

    $this->getUrl($route) can be used in templates to generate an absolute URL based on route, but it only works for frontend URLs. As for adminhtml URLs, unless you say No to “Add Secret Key to URLs” in System >> Configuration >> Admin, a valid adminhtml URL should have a secret key.

    $this->getUrl($route, $params) can take ‘_current’ as one of parameters, but it only attaches current URL’s parameters. Adminhtml URL secret keys vary with controller and action names. So how to get unique secret key by controller and action names? Easy peasy, just use:

    Mage::getSingleton('adminhtml/url')->getSecretKey($controllerName, $actionName);
    

    How to get URL to adminhtml route (attach the secret key automatically if it is enabled)? Just use:

    Mage::helper('adminhtml')->getUrl($route);
    
  • Double quotes or single quotes inside html tag, which one is the better?

    If you google “Double quotes or single quotes inside html tag, which is better”, you might hear someone is talking about using double quotes in html won’t pass XHMTL validation. I think it is nonsense.

    Both of these characters are valid for XHTML, i.e. both

    <tag att="value">
    

    and

    <tag att='value' >
    

    are valid. However, I have a good reason to encourage you to stick to double quotes.

    When value is taken from user input, it is a must to convert all applicable characters to HTML entities by htmlentities(), and htmlentities() default flag is ENT_COMPAT which convert double quotes but leave single quotes alone. That is to say,

    If I use

    <tag att="(value taken from user input)">
    

    constantly in templates, and if htmlentities() converts all double quotes in user input, whatever user input is, it will not break html output.

    I used to use double quotes and single quotes interchangeably, but I learned from Magento. Magento sticks to using double quotes. Its htmlEscape() bridges to htmlspecialchars() but it does not let you pass in a flag to control how to convert double quotes or single quotes. So, if you use

    <tag att='(value taken from user input)'>
    

    , and if you rely on Magento htmlEscape() to convert special charcters for you, when user input has some single quotes, it ruins html output. I am sure you do not want it happens, so stick to using double quotes, always.

  • Social network is rabbish, but we have to use it

    我不是 social network 的积极使用者,可能因为我笨,看不出 social network 为什么把 A 和 B 连起来。比如,在 live social 里,我被问到:

    您和 Jing Feng 不是好友。 添加为好友?

    我就奇怪了,我和他如果不是好友,你问我干吗?

    还有,大家把帖子转来转去,有几个人愿意跟我一样关注原创?

    但 social network 无孔不入,消极逃避不是办法。广告铺天盖地,如果你是单纯看广告,就会烦;如果我是广告商,我轰得你烦,那我至少也有点成就感。

  • Which part of MVC do Magento blocks belong to?

    Someone said Magento was not strictly MVC structured. I am intended to accept this point. But MVC does give people an easy way to understand how system works. So if I regard Magento as an MVC system, which part of MVC do Magento blocks fall into?

    I used to think blocks were Views because they were tied with templates. As time goes, now I think blocks are Models because blocks implement a lot of business logic as Magento model classes. Today I have another reason to support blocks are Models:

    When a frontend_model is initialised for a Sytem Configuration field or an EAV attribute field, it is actually a block class.

  • Lack of ideas to manage javascript in Magento

    In Magento System >> Configuration >> Catalog >> Frontend, when List Mode selected value is changed, some fields (i.e. Products per page on Grid allowed values, Products per Page on Grid default value, Products per Page on List allowed values, Products per Page on List default value) are shown/hidden accordingly.

    List mode showing both grid and list options
    List mode showing both grid and list options

    List mode showing only grid options
    List mode showing only grid options

    I had thought List Mode had a special frontend model defined so it could interact with other fields. I spent an hour to search for special settings of List Mode but did not find any. Instead I was disappointed to find out the frondend interaction is not defined in xml or php class, but by app/design/adminhtml/default/default/template/system/config/js.phtml.

    The way Magento did this kind of interaction is not replicable, which is a pity. By and large, the way how Magento uses javascript is messy. Maybe I am asking too much from Magento. What I am keen on is a “Google Web Toolkit” way, that means no need to manage javascript at all because javascript is compiled from server end script.

  • Constants are not overridden as varibles

    今天发现我写的一个底层的 Magento class 竟然有个低级错误。错误的根源是我在父类里定义了一个常量

    const XML_PATH_TO_SYSTEM_CONFIG = 'some value';
    

    然后在父类里有个方法用到了这个常量

    public static function getConfigValue()
    {
    	return Mage::getStoreConfig(self::XML_PATH_TO_SYSTEM_CONFIG);
    }
    

    然后在子类里复写了常量

    const XML_PATH_TO_SYSTEM_CONFIG = 'some other value';
    

    但子类并没有父类的方法 getConfigValue()。我指望通过复写每个子类的常量后调用子类的方法 getConfigValue() 得到不同的值,哪知道每次都得到跟父类的方法 getConfigValue() 相同的值。

    仔细一想,这是因为父类的 self::XML_PATH_TO_SYSTEM_CONFIG 并没有被复写。改用一个变量来存储值就能达到我的原定目的,但这个变量不能是静态变量,否则效果还是跟常量一样。

  • 【转】维基解密促成突尼斯革命

    【博主按】通常我不用我的博客转帖,今天破个例。原文出处不详。

    去年12月17日,一名26岁的突尼斯大学生因抗议城管暴力执法而选择自焚。他一定没有想到,自己无奈的反抗同时点燃了这个国家剧变的导火索。

    他的死,让早已对腐败、贫富差距、高失业、高物价等问题不满的民众愤然走上街头,在突尼斯引发大规模骚乱,造成70多人死亡,数百人受伤,最终逼迫总统本·阿里在14日深夜飞往沙特,匆忙逃离这个自己执政23年的国家。

    起因 青年自焚引发全国骚乱

    突尼斯爆发独立以来最大规模的社会动荡缘于一名男青年。26岁的布阿齐兹家中父亲早亡,独力承担供养兄弟姐妹的重任。他拥有大学学历,却没有找到工作,只好摆摊卖水果与蔬菜。由于没有经营许可证,其水果蔬菜6次被城管部门没收。为抗议城管粗暴执法,他于去年12月17日自焚,后因伤势严重于1月4日死亡。这一事件导致突尼斯发生大规模社会骚乱。在这场本阿里23年铁腕统治下的最严重动乱中,70多人死亡,数百人受伤。

    强硬 总统称不容忍这类行为

    骚乱最初,本·阿里采取了强硬态度。警方在处理示威抗议时,数次在“鸣枪示警无效后,被迫开枪进行自卫”,结果造成多人死亡和受伤。本·阿里10日下午向全国民众发表电视讲话,谴责“来自国外的黑手”不断在突尼斯制造社会骚乱和流血冲突,并表示突尼斯“不会容忍这类恐怖行为”。

    让步 承诺进行全面改革

    突尼斯当局的强硬措施并未起到预想效果,许多城市陷入无政府状态,骚乱愈演愈烈并蔓延到首都突尼斯市。示威者要求整治总统身边的腐败官员,包括其亲戚、女婿等人。工会也从支持政府转变为站在民众一边。13日,本·阿里骚乱发生后第3次发表全国电视讲话。他表示,已下令军队不许用实弹射击,除非出于自卫。本· 阿里承诺立即进行全面改革,“实现全面、彻底的新闻自由,取消对互联网的限制措施”,控制飞涨的食品价格。74岁的本·阿里还表示,无意修改宪法规定的 75岁总统年龄上限,将不再谋求连任。

    交权 总理议长抢着接班

    总统府前的示威民众越聚越多,口号已发展到“要面包、水,不要本·阿里”,“抗议示威直至政权垮台”。全国多地发生纵火、抢劫等暴力事件,局势接近失控。14日,1名目击者称突尼斯一座监狱起火。在押人员试图逃跑时,狱警朝他们开枪,造成42人死亡。

    14 日下午,本·阿里紧急召见总理格努希。格努希之后宣布,解散目前由执政党组成的一党制政府,同时在6个月内提前举行议会选举。当天稍晚时候,突尼斯突然宣布实施紧急状态,内容包括禁止三人以上的聚会,实施宵禁,对可疑人员可使用武器。不久又传来消息,称本·阿里已离开突尼斯,由总理格努希行使总统职权。格努希14日晚正式宣誓就职。

    但据英国《卫报》15日报道,突尼斯宪法委员会主席15日宣布,根据突尼斯宪法,总理格努希涉嫌违宪,应当由国会发言人、众议长迈巴扎代行临时总统职权,而非政府总理,并要求在60日之内进行新一轮总统选举。

    出逃 被法国拒绝后飞往沙特

    眼看所有措施都已无法扭转局势,本·阿里无奈下选择出逃。沙特阿拉伯媒体15日引用该国王室发表的声明说,突尼斯总统本·阿里已于15日凌晨抵达沙特。媒体称本阿里曾想到马耳他或法国避难,但两国都拒绝接纳。

    美国总统奥巴马赞赏突尼斯民众“勇敢的民主行动”。法国爱丽舍宫表示尊重突尼斯的民主选择。英国则表示,支持突尼斯的民主变革。据半岛电视台报道,突尼斯安全机构已开始对本·阿里的部分亲信实施逮捕,其中包括他的女婿。在法国巴黎,突尼斯侨民呐喊欢呼,又唱又跳,庆祝铁腕统治突尼斯23年的本阿里下台。

    根源

    高失业和腐败压垮本·阿里

    骚乱爆发前,突尼斯一直被认为是非洲和阿拉伯国家中最稳定、经济最具活力的国家之一,其全球竞争力排在非洲之首。但这种看似稳定的背后却暗流汹涌。

    突尼斯近20年来发展情况较好,但其经济结构失衡的问题始终没有得到改变,经济发展受惠最多的只是沿海发达地区。

    此外,突尼斯的失业率近年来连续攀升。尽管突尼斯官方公布的失业率为14%,但一些经济学家表示失业率其实超过20%,在某些领域甚至超过60%。失业大军中有将近3成是大学生,突尼斯每年有8万多名大学生踏入社会,但其中只有1/4的幸运者能找到工作。正是这些失业的年轻人成了此次骚乱的主力。

    另一个重要原因是,长期以来,突尼斯政治体制僵化,改革严重滞后。

    近乎独裁的统治导致突尼斯贪污腐败日益猖獗,贫富悬殊之大已达到令人发指的程度,以本·阿里为中心的权贵势力肆意贪污受贿、侵吞国家财产。突尼斯人的不满终于爆发,走上街头抗议示威,呼唤变革,并最终使得本阿里下台。

    本·阿里流亡标志着一个时代的结束。但突尼斯人能否接受新政权,骚乱是否将就此终结,都还是未知数。

    人物

    本·阿里铁腕统治23年

    在23年里,本·阿里始终独自执政,没有任何一个人同他分享权力。他成为阿拉伯国家中第一个在街头群众压力下放弃政权而出逃的领导人。

    本·阿里1936年9月3日出生。他早年先后在法国圣-西尔军械学校、炮兵学校和美国的情报与安全高等学校、野战与防空炮兵学校就读,曾获电子工程师文凭。

    本·阿里于1987年11月7日接任总统,于1989年4月正式当选。此后,他在1994年、1999年、2004年和2009年四次连选连任突尼斯总统。本·阿里同时一直担任突尼斯执政党宪政民主联盟主席。

    本·阿里被认为是阿拉伯国家中少有的西方盟友。他重视推广教育,使大批突尼斯学生进入大学深造。本·阿里推行自由经济政策,使突尼斯经济连续几年保持增长。

    丑闻

    总统家族是腐败核心

    本·阿里统治20多年,让突尼斯成为一个僵化的集权国家。裙带关系带来的丑闻越来越多,在权力圈内部的腐败持续增长。

    维基解密曝光的一份美国大使馆机密电文题为“突尼斯的腐败:你的就是我的”,文中称,在突尼斯,只要是总统家族成员看上的,无论现金、土地、房屋甚至游艇,最终都得落入他们手中。

    另一份电文将本·阿里的家族称为“准黑手党”,称其是突尼斯“腐败的核心”。许多突尼斯人对总统家族的奢华生活以及这些人对普通民众困苦的漠视感到不满。一份2009年的电文描述了在本·阿里女婿的豪宅里举办的一次宴会。罗马时期的文物随处可见;客人们享用着用私人飞机从法国南部小镇空运来的酸奶;一只宠物老虎在花园里漫游。

    关注

    中国使馆公布求助电话 提醒加强安全防范

    中国外交部领事司及驻突尼斯使馆提醒拟于近期赴突尼斯和已在突尼斯的中国公民加强安全防范,减少不必要的外出,尽量不要前往事发地区或人员聚集场所,务必注意安全。如遇紧急情况应及时报警,并可向驻突使馆寻求帮助。

    联系电话:00216-7178006400216-98463848

    外交部发言人洪磊15日表示,中方十分关注突尼斯局势发展,衷心希望突早日恢复社会稳定,这符合突人民的根本利益。

    全球金融危机使得许多没有油气资源的阿拉伯国家经济举步维艰。这些国家政治体制僵化,民众积蓄的不满情绪很容易被点燃。近来类似的骚乱在阿尔及利亚、约旦等国均有发生。

    元旦以来,阿尔及利亚部分食品价格上涨幅度达到30%,在全国多个地区引发骚乱,已致使3人死亡,约400人受伤。

    而在约旦首都安曼,数以千计的民众走上街头,抗议该国油价和食品价格高涨,并要求约旦现任首相里法伊下台。除安曼外,该国其他四个城市也举行了示威活动。

    突尼斯总统流亡 维基解密促成首起革命

    一个月前,一个水果摊被抄,竟导致铁腕统治突尼斯23年的总统本·阿里仓皇流亡海外。这堪称是阿拉伯世界近代第一场人民革命,称为“茉莉花(国花) 革命”,也可说是爆料网站维基解密促成的第一起革命。年轻人透过社群网站和手机串连上街示威,突破政府钳制的媒体,让邻近的阿拉伯专制政权都心惊。

    据外电报道,这场人民革命的起因是一名水果摊贩的自杀事件。一名受过教育的26岁失业青年去年12月中在路旁摆水果摊,警察以无照摆摊为由,没收他的蔬菜和水果,他愤而自焚,并引发模仿他的自杀潮。水果摊贩自焚的消息透过FACEBOOK等社交网站和手机快速传播,让原已对居高不下的失业率和粮价不满的民怨更深。

    这时维基解密网站扮演关键角色,该网站去年12月揭露2009年6月的美国外交电文,指本·阿里家族与一名黑道老大连手掌控突尼斯经济,并指第一夫人兴建贵族学校获得巨额利益。

    这些电文揭开突国统治菁英贪腐的面纱。另一封电文详述第一家庭如何被人民厌恶。美国驻突国大使葛戴克写道:“掌权小圈圈内的贪腐日益严重,连一般老百姓都注意到,民怨四起。”

    在几周内,这些电文内容经口耳相传和社群网站传播,最终让民众走上街头,演变为人民革命。突尼斯大学地质系教授马奈表示:“一个月前,我们压根儿不相信革命会成功,但是人民终于站起来了。”

    尽管本·阿里在最后关头承诺改革、解散内阁、半年内改选国会,并不再连任,但愤怒的群众仍在首都突尼斯暴动,要他下台。政府表示至少23人在三周的暴动中丧生,但反对阵营估计死亡人数是3倍多。本·阿里仓皇出走,长期盟友法国表示不欢迎,后来是沙特阿拉伯同意收留本·阿里全家。

  • Javascript bookmark this page in Chrome

    I have a stupid client asked me to add “Bookmark this page” to his web pages. I explained to him how bad usability it is but he did not listen to me. He insisted the majority of web users were as stupid as him, so him wanted to help them bookmark the page.

    Nevertheless, it is not my site and he is my customer. Customer is the God. So I spent some time digging around and found this script.

    <script type="text/javascript">
    //<![CDATA[
    function bookmark_us(){
    var url = window.location;
    var title = document.title;
    
    if (window.sidebar) // firefox
        window.sidebar.addPanel(title, url, "");
    else if(window.opera && window.print){ // opera
        var elem = document.createElement('a');
        elem.setAttribute('href',url);
        elem.setAttribute('title',title);
        elem.setAttribute('rel','sidebar');
        elem.click();
    } 
    else if(document.all)// ie
        window.external.AddFavorite(url, title);
    }
    //]]>
    </script>
    

    However, Chrome browser does not allow us to bookmark any page using javascript. There is no workaround, and I think Google is absolutely right on this.

    My concern is: the above script does not do anything in Chrome. Sooner or later my client will come back to me asking why my script does not work in Chrome. To avoid being questioned, I finally use another solution. It is a jQuery plugin called jBrowserBookmark. It will prompt the correct way to bookmark in unsupported browsers.

  • Set primary display in KDE for Fedora 14

    我用的一台机器的显示卡有两个输出接口,一个是 VGA 接口,另一个是 DVI-I 接口。我以前单用 DVI-I 接口,最近多出一个显示器接在了 VGA 接口,我把 DVI-I 显示在左边,VGA 显示在右边。DVI-I 是主显示器,我也希望 Fedora KDE 桌面环境的 Panel 能固定在 DVI-I 显示器上。

    刚开始用 VGA 时,Panel 仍在 DVI-I,用得很顺手,大概是因为 VGA 是在开机以后才插上的缘故。可是重启后,Panel 死活不肯固定在 DVI-I。登录 KDE 前,登录窗口还是在 DVI-I,可见那时 DVI-I 还是主显示器。可登录后,Panel 就显示在 VGA。我试过很多办法,比如调整 DVI-I 在 VGA 的上下左右各种位置,或者 disable VGA 再 enable VGA,可只要 KDE 探测到 VGA enabled,就把 Panel 移到 VGA。

    怎样在 KDE 里设置某个显示器为主显示器?我查了一下,似乎没有 GUI 可以让我这么做。原因是 KDE 本身不探测哪个显示器为主显示器,而是直接采用 plasma 里的值,而 plasma 本身有 bug(我不确定这个解释对不对)。

    不管原因是什么,我更关心的是解决方案。方法也很简单,run this:

    xrandr --output (primary display name) --primary
    

    其中 (primary display name) 是主显示器名称,可以在系统信息里找到,通常是显示器类型-序号,我的是 DVI-I-1。