Category: 小小草

IT 技术领域学海无涯。其实任何领域都学海无涯,无非 IT 发展太快了,让我有更多嘘唏。希望我掌握的技术有如小小草,虽然渺小,却有旺盛的生命力。

  • Hotmail now open for POP3

    微软被人诟病得比较多的地方,一是卖得贵,二是不开放。我觉得卖什么价是微软的事情,只要它觉得有市场,谋求利润最大化不该受到指责;但我深恶痛绝不开放的行为。

    用户在选择一个产品前,不会了解这个产品的所有功能和限制。只有在使用产品的过程中,不停地发掘它的功能也了解到它的限制。如果发掘了一项功能是意料之外的,那就是惊喜,如果了解到一项限制是卖方强加的(不是因为成本高昂或技术不成熟),那就是不给用户自由——希望用“不开放”去限制用户不去选择竞争对手的产品?那是不可能的。我更甚之,如果哪个卖方敢这样干,我立马改投它竞争对手的环抱。

    所以,我说 Google mail 比 Hotmail 好,主要是因为 Google 远比微软开放。

    今天发现,有人博文说 Hotmail 支持 POP3 了。很久没用 Hotmail 了,我也不晓得它什么时候开始支持 POP3。我赶紧试了一下,果然,Google mail 里很轻松地把 Hotmail 帐号添加了进来,而且 Google mail 一见到是 Hotmail 帐号,直接把参数给设置好了。

    Gmail add another account from Hotmail
    Gmail add another account from Hotmail

    看来微软也在进步,不过是不是太迟了点?我从不用 Hotmail 作邮箱 (only as IM),不过还是很高兴看到它支持了开放协议。

  • Better to custom Magento interface from base/default

    Magento 官方推荐以 blank interface 为基础开发个性化的 interface。这说法没错,但有局限性。如果不熟悉 Magento interface 的构成,blank interface 确实一个很好的出发点,如”blank“的名称所言,它没有花里胡哨的背景影响你的构思,如果你是设计师,blank interface 给了你极大的方便。

    但世上难有两全其美的事情——blank interface 方便了设计师,但不方便最终用户(我指后台用户)。设计是一时的,用户是一世的,所以我认为两者有冲突时应该更多地照顾用户。Magento interface 有三层 fall-back 机制,在 System > Configuration > Design 可以设置 theme 和 default theme,系统还有最底层的 fall-back to base/default。

    设想一下,如果基于 blank interface 开发 my_wonderful_theme,那在后台只能设置 theme 为 “my_wonderful_theme”,设置 default theme 为 “blank”。同时,严格按照 Magento 的规范,只把 “blank” 中需要修改的文件拷贝到 “my_wonderful_theme” 中进行修改。最终 “my_wonderful_theme” 保存了一些修改文件。如果全站页面统一使用 “my_wonderful_theme”,则没有问题;可是,Magento 允许个别 cms, category 或 product page 使用不同的 theme,通常会是 “my_wonderful_theme” 局部的变种,这样就有问题了。假设需要对某个 category 下的页面使用 “my_fantastic_theme”,而 “my_fantastic_theme” 只是在“my_wonderful_theme” 基础上修改了 header 部分,但 “my_fantastic_theme” 无法就它所缺的文件 fall-back to “my_wonderful_theme”——很可惜,Magento 只提供了三层 fall-back 机制,假如它就多给一层 fall-back,那就没有我这篇文章了。

    简言之,如果基于 blank interface 开发,那么 cms, category 或 product page 里的 custom design 功能就成了鸡肋。如果设计师/开发者交付一个基于 blank interface 的 theme 和若干变种,用户无法方便地完成切换,这就是个败笔。以后还是以 base/default interface 为起点开发吧,其实也很方便。

  • Lightbox not working in Magento 1.4 solved

    My case is special –

    很久以前为 Magento 1.3 加装 Lightbox 2 时,我听从某人的建议,去掉了 Magento 自带的 scriptaculous effects.js,安装了当时最新的 scriptaculous 1.8.3 effects.js。Lightbox 调试成功后一直没去动它。

    Magento 升级到 1.4 后,默认启用 Merge JavaScript Files,这时 Lightbox 就不工作了。如果禁用 Merge JavaScript Files,Lightbox 恢复正常。我调试不出 Lightbox 失效的原因,大概是 js library 版本不兼容。再看了一下 Magento 如今自带 scriptaculous 1.8.2,估计和 1.8.3 相差不大,为了兼容性,干脆就用 Magento 原装的 js。

    于是去掉我自装的 scriptaculous 1.8.3 effects.js,启用 Merge JavaScript Files,如我所愿 Lightbox 恢复正常。

  • Do not use is_null()

    测试一个变量是否为 NULL,我曾喜欢用 is_null() 函数,现在发现还比如直接用 === 比较来得快。

    php.net 上有人写了个测试,得出的结论是 === 比 is_null() 快30倍。

    
    $v = NULL;
    
    $s = microtime(TRUE);
    for($i=0; $i<1000; $i++) {
        is_null($v);
    }
    print microtime(TRUE)-$s;
    print "<br>";
    
    $s = microtime(TRUE);
    for($i=0; $i<1000; $i++) {
        $v===NULL;
    }
    print microtime(TRUE)-$s;
    
    

    这是2007年的事情了,我不清楚他的环境配置。如今在我 Intel(R) Celeron(R) CPU 2.80GHz PC 充当的测试服务器上,running zend server php 5.2.9,得出的结论是 === 比 is_null() 快1-2倍。看来 php is_null() 的效率进步了不少,但还是慢。以后我得改用 NULL === $v 的方式了。

  • Magento theme improvements from 1.3 to 1.4

    There are loads of improvements in the newest version of Magento themes. I just list some from my point of view. I observed these changes when I started using Magento 1.4 three days ago, but they may exist in the late version of 1.3.x.x already for long.

    Everyone knows we should separate presentation from content. Magento does it very well since its first public version. Magento 1.4 just makes separation even better. A theme is about presentation, usually made of two parts, app/design and skin. Compared with skin, app/design part is somehow closer to content. Magento 1.4 themes remove layouts and templates from app/design, which means they are fully rely on css to present different themes. Base/default theme is an exception, but it is a fall-back theme.

    In 2-column or 3-column page templates, main column code comes before left/right column. I think it hugely helps SEO. I first saw this kind layout in a Zen-Cart template. Maybe Magento was inspired by it. Under template/page, one-column.phtml was deleted, which saves confusion with 1column.phtml.

    The header logo is no longer displayed as a background image, which is a minor change but makes big improvement.

    I spent 3 days to re-write my theme to be compliant with Magento 1.4 but I love these changes.

  • How to call a Block multi times in Magento

    我觉得我对 Magento 的理解与日俱增(哈,这不是废话)。

    今天更新以前写的一段代码,有关在 block 里多次调用同一个 child block,但 child block 在每次调用时出现不同的内容,比如 product list block 去调用每个产品的 product block。Magento default theme 对此的处理方式跟我设想的不同,它把整个 product list block 就写成一个 block,没有 child block。在产品表现比较复杂的时候,特别是不同类的产品使用不同表现的时候,混写在一个 block 里代码就很乱,我想用 product list block 套用 product block 的方法去理清代码。

    这里涉及四个要点:

    1. 如果用 getChildHtml(‘product_block_name’),Magento 默认 block 只被调用一次,在 product list 循环里多次调用 getChildHtml(‘product_block_name’),结果所有产品显示的都是第一个产品。这是因为 Magento 缓存了 getChildHtml 返回值。如果要求每次都不用缓存值,必须使用 $useCache = false。$useCache 是 getChildHtml 的第二个可选参数,默认为 true,所以 getChildHtml(‘product_block_name’) 每次都得到了相同的结果;getChildHtml(‘product_block_name’, false) 就可以得到想要的不同结果。

    2. 既然说到缓存 $useCache,请分清这不是 block html cache。前者只是一个变量 cache,存储在 block class 的属性里;后者是 php code cache,存储在 files/apc/memcached, etc.

    3. Block 和 child block 之间怎么传递变量?亦即 product block 需要知道当前计算的哪个产品。很久以前我只会用 Mage::registry,于是每次在 product list block 里注册一个当前产品,然后调用 product block,在 product block 再取出注册值。我当时就不满意这种方案,我总觉得没有必要在全局注册一个变量来解决此类问题,但当时水平有限,想不到其他办法。现在有了:在 product list block 里使用

    getChild('product_block_name’)->setProduct($product)->toHtml();
    

    在 product block 写一个 setProduct() 方法:

    public function setProduct($product) {
    $this->_product = $product;
    return $this;
    }
    

    请注意 block 不同于 model,没有 magic method 可以用,所以必须老老实实写一个对应的setProduct() 方法。

    4. 如果用 getChild,就不用担心返回值被缓存,因为 getChild 不同于 getChildHtml,根本就不缓存返回值。

  • Editable Order extension for Magento is excellent

    Magento 要求太严,后台想修改 Order billing address or delivery address,必须 cancel the order and raise a new one。为了 traceability?我们觉得没有必要,怎么才能直接修改?

    找到两个 extension,一个 commercial,收 $89;一个 community,叫 Editable Order。

    当然先试试 Editable Order,一试很满意,虽然是德文,不影响使用。就用它了,有空再看看怎么把界面改成英文。

  • Cleanup after upgrade Magento to 1.4

    升级总有这样那样的问题,我不想节外生枝,也就不想在项目中途升级。我把一个正在开发中的 Magento 商店开始开发时版本是 1.3.2.4,但今天一不小心,敲入了

    ./pear install magento-core/Mage_All_Latest

    就把 Magento 升级到了 1.4。

    (要怪 Magento 升级太方便了?其实,今天的不小心是有原因的:我发现 Magento Connect 启动不了。尝试进入 Magento Connect 时通常要求再次输入管理员密码,但今天这个页面只有 Magento Connect logo,看上去页面意外中止。而我急着想试用一下某个 community extension,就用了 pear 命令。在敲键盘的过程中,脑筋没多想,竟然敲入 ./pear install magento-core/Mage_All_Latest,就坏事了。)

    升级以后发现后台 System/Configuration 保存时经常出错,错误提示:

    Error while saving this configuration: Invalid mode for clean() method

    CMS/Pages 也无法保存页面,错误提示:

    Error while saving Page. Please try again later

    Catalog/Products 也无法保存修改…

    我猜想所有这些错误都来自一个地方。错误多了反而好办——肯定他人也会碰到。果然,google 一下不怎么费力就找到答案:删除 app/code/core/Zend/Cache 目录就可以了。

    这证明了我的一个保证升级后不出错的土办法:先保持原有文件不动进行升级,然后把新老版本混合在一起的文件夹删除,然后再上传一份干净的新版本(被新版本抛弃的老文件就被删除了)。当然也可以用版本比较工具来找不同,但土办法更省事。

  • Dull_Addressfields Magento extension

    I could not edit customer order delivery address at backend using Magento 1.3.2.4. Checkbox “Same As Billing Address” is always ticked. When I untick it, it automatically tick itself. I was able to edit it some while ago. What happened since then?

    Half an hour later I found the problem was caused by installation of Dull_Addressfields 1.0. This extension was installed because I wanted to “Same As Billing Address” as a default choice at checkout. But even if I set “Default delivery address to billing address” to “No” without uninstall Dull_Addressfields. I upgrade Magento to 1.4. Problem remains.

    So I have to uninstall Dull_Addressfields. Actually, with the skills I acquired nowadays, I can make “Same As Billing Address” as a default choice without 3rd party extension. But my boss don’t want to make “Same As Billing Address” as a default choice. Situation changed since I installed Dull_Addressfields.

    Btw, Dull_Addressfields rewrites two classes: Mage_Customer_Model_Address and Mage_Sales_Model_Quote_Address. As Magento can’t safely handle two extensions rewrite a same class, I don’t want Mage_Customer_Model_Address and Mage_Sales_Model_Quote_Address to be rewritten by Dull_Addressfields (just to achieve a simple goal?). I’d like these important classes be untouched for future rewriting for important functionalities.

  • My third DNS server down for a month

    今年初,我退掉了 godaddy vps,把原来 godaddy vps 担当的辅助 DNS 角色转给了 1&1 server,却忘了开 1&1 server firewall port (硬件防火墙那道关)。

    今天才发现这台辅助 DNS 在过去的一个月根本无法执行 DNS 解析(因为我设置了三台 DNS,挂了一台没引起警觉)。难怪最近 webceo 给我的评分只有 5 分上下,google 的排名也有下降。

    赶紧打开防火墙,希望分数能上去。