Jan 31

解决cakePHP中i18n的单复数问题

如果不了解如何在cakephp中解决i18n问题,或者不知道什么是i18n问题,请先阅读:如何使用cakephp实现多语言网站

在开发的时候,尤其是英文,单数和复数的问题很难搞,编码要考虑周全何时预留单数复数的占位符,并且要根据数量写很多if-else。如果baker们只是通过阅读cookbook来学习cake,那么是找不到好办法解决这个问题的,不知为什么,官方并没有写这方面的解决文档。通过看源码、google,今天终于想清楚了这个问题,在这里分享一下。

假设我们有一个需求,要在页面输出这样的文本:Mr Brown has 3 apples at all. 其中3是变量,可能是1-n的自然数,当布朗先生只有一个苹果时,我们应当输出:Mr Brown has 1 apple at all. 在编码时,我们可以这样写:
$text = __n("Mr Brown has %d apple at all.", "Mr Brown has %d apple at all.", 3, true);
printf($text, 3);

这里使用了cake提供的__n()方法,而不是__()方法。它的前两个参数分别是文本的单数和复数占位符,第三个参数是苹果的个数,第四个参数表示此文本只是作为结果返回给$text,而不直接输出到页面。

之后使用cake提供的命令行工具:cake i18n,生成pot文件后,可以找到这样的内容:
msgid "Mr Brown has %d apple at all."
msgid_plural "Mr Brown has %d apple at all."
msgstr[0] ""
msgstr[1] ""

前两行就是刚才我们在代码中写的第一和第二个参数。后两行分别对应翻译语句的单数和复数形式,我们根据pot来生成po,翻译第三、四句如下:
msgstr[0] "Mr Brown has %d apple at all."
msgstr[1] "Mr Brown has %d apples at all."

在查看页面,就得到了我们想要的结果:Mr Brown has 3 apples at all.

在这个过程中,有个问题需要注意:po文件的头部有这样的设置语句:"Plural-Forms: nplurals=2; plural=(n != 1);\n"。这里配置的是当前语言(English、Chinese等)的复数特征,上面所写是英文的。如果是中文po文件,应当写成:"Plural-Forms: nplurals=1; plural=0;\n"。其他语言可以到这里去查:http://translate.sourceforge.net/wiki/l10n/pluralforms。

即便如此,生成pot文件之后的翻译工作也相当麻烦,尤其是项目中有新旧版本需要比较、合并的时候。下一篇博客将会想办法改进翻译过程,敬请期待。

Aug 02

[收藏]cakePHP自定义404页面

  • Create your error layout in app/view/layouts/ (with name error.ctp)
  • Create your 404 error view in app/view/errors/ (with name error404.ctp).
    In /cake/libs/view/errors you will find all the default error views.
    You can copy and paste error404.ctp in your app/view/errors directory or create a new file and customize this view as you like.
  • Then add this to your app_controller.php :
  • function _setErrorLayout() {

    if ($this->name == ‘CakeError’) {
    $this->layout = ‘error’;
    }
    }function beforeRender () {
    $this->_setErrorLayout();
    }

Jul 10

如何用cakePHP读取wordpress的rss

1.cakePHP中,可以使用HttpSocket这个lib

2.默认使用get方法获取wp的rss http://hulucat.com/?feed=rss时,是得不到字符串返回的。到wp服务器检查了一下,原来这次请求得到了一个301状态返回;如何解决呢?首先,到wp后台,修改permlinks,改成Month and name格式;之后,确保wp根目录有.htaccess,并且有wp提示的跳转代码。

3.之后,用HttpSocket访问http://hulucat.com/feed/rss,就可以得到输出了。

Jul 01

收藏:如何使用cakePHP实现多语言网站

看过CakePHP的程序例子就会发现,在Controller或者View中,大多数输出都是用一个函数 __(”xxxx”) 来执行
这个函数是CakePHP遵循标准的gettext方 案.
但是CakePHP不用加载php-gettext模块就可以使用,因为它已经用php代码在CakePHP内核中解决它了.这种方法在用来处理多国语言 的时候,非常方便

什 么是 i18n,l10n
首 先要先明白Localization & Internationalization两个单词,分别叫本地化和国际化. Localization 表示将 Web 应用转化以适应某种语言(或文化)的需求,而 Internationalization 表示 Web 应用可以被本地化的能力。Internationalization 和 localization 常被缩写为 i18n 和 l10n; 数字 18 和 10 是该单词的第一个字母到最后一个字母之间的字母数量

CakePHP的语言文件存放何处
在CakePHP中,存放语言文件的地方在(下面不同语言的命名必须符合ISO 639-2 标准)

/app/locale/eng/LC_MESSAGES/default.po (English)
/app/locale/fre/LC_MESSAGES/default.po (French)
/app/locale/por/LC_MESSAGES/default.po (Portuguese)
/app/locale/chi/LC_MESSAGES/default.po (Chinese)

po文件如何编辑
这些po文件可以用一个叫poedit的免费软件来编辑,存储后即可生成 mo文件

如何自动生成po文件
CakePHP的目的就是减少我们的工作量,我们写代码的时候,只管用英文 __(’xxx’)去输出东西,CakePHP会帮你从app文件中找出这些英文放到 po文件中,步骤如下(windows下)

  1. 打开命令行,进入需要应用的app目录路径
  2. 输入 cake i18n ,即会出现提示,全部默认后,cake会帮你生成一个 app/locale/default.pot 文件.这个就是你需要翻译的文件了
  3. 将该文件移动到相应的目录下,如 “/app/locale/chi/LC_MESSAGES/default.po”,用poedit编辑它,完毕后存储,看到该目录下生成 default.mo文件,即成功。编辑时,复数形式的选项可以这样填:Plural-Forms: nplurals=2; plural=(n != 1)

CakePHP中如何输出多语言信息
使 用位于 cake/basics.php 下的这个函数,例 __(’po mo’);输入函数的字符串将会在扫描后出现在/app/locale/xxx/LC_MESSAGES/default.po中,在用poedit去翻 译它,存储后,程序被调用时将会输出翻译后的信息

/**
* Returns a translated string if one is found, or the submitted message if not found.
*
* @param string $singular Text to translate
* @param boolean $return Set to true to return translated string, or false to echo
* @return mixed translated string if $return is false string will be echoed
*/
function __($singular, $return = false) {…}

如何让程序调用不同的语言文件
CakePHP会根据浏览器的HTTP_ACCEPT_LANGUAGE来读不同的文件,但是如果没有这些文件,便会输出默认的英文
若你需要切换语言,在程序开始前调用一下以下代码即可

$this->Session->write (”Config.language”,”chi”);

总结自:

http://book.cakephp.org/view/161/Localization-Internationalization

http://blog.darkhero.net/?p=300