【问题标题】:Easy way to translate a website翻译网站的简单方法
【发布时间】:2012-02-25 14:45:30
【问题描述】:

问题

我有一个相当静态的网站,只有一些基本的 PHP 用法。现在客户想要翻译这个网站。我确实有一个解决方案,但它很麻烦,我想知道其他人是如何做到的以及标准是什么(在框架等中)。

我的方式

我的方式(为了更容易理解,我将其简化了一点):我从数据库中为每种语言生成一个 PHP 数组,并将该数组存储在一个语言文件中,例如西班牙语的 es.php。

然后我使用这样的 tr 函数翻译 HTML 中的字符串:
之前:<h1>Hello World</h1>
之后:<h1><?php echo tr('Hello World'); ?></h1>,它为西班牙语提供 <h1>Hola Mundo</h1>

问题

这很麻烦且容易出错。我必须遍历每个 .php 文件,并用这个 PHP 标记替换所有硬编码的字符串。
有没有更好的办法?其他人是怎么做的?如果需要,我可以详细说明我的实现。

【问题讨论】:

标签: php html localization internationalization translation


【解决方案1】:

我做了一门课来做我的

class WILang

{

    function __construct() 
{
     $this->WIdb = WIdb::getInstance();

}

public static function all($jsonEncode = true) {
    // determine lanuage
    $language = self::getLanguage();
    //echo $language;

    $WIdb = WIdb::getInstance();
        //$file = WILang::getFile($language);
        //echo $file;
        //echo $language;
    if ( ! self::isValidLanguage($language) )
    die('Language file doesn\'t exist!');
    else {

        $sql = "SELECT * FROM `wi_trans` WHERE `lang` = :file";
        $query = $WIdb->prepare($sql);
        $query->bindParam(':file', $language, PDO::PARAM_STR);
        $query->execute();
        //$result = array();
        while ($result = $query->fetchAll(PDO::FETCH_ASSOC)) {
            echo "{";
            foreach ($result as $res) {
            echo '"' .$res['keyword'] .'":"' . $res['translation'] . '",';
             //return array($res['keyword'] => $res['translation'] ,);  
        }

        echo "}";
        }

        }
}

public static function get($key ) //, $bindings = array()
{
    // determine language
    $language = self::getLanguage();

    $WIdb = WIdb::getInstance();

    $sql = "SELECT * FROM `wi_trans` WHERE `keyword`=:key AND lang=:lang";
    $query = $WIdb->prepare($sql);
    $query->bindParam(':key', $key, PDO::PARAM_STR);
    $query->bindParam(':lang', $language, PDO::PARAM_STR);
    $query->execute();

    $res = $query->fetch(PDO::FETCH_ASSOC);
    if($res > 0)
        return $res['translation'];
    else
        return '';
}

 public static function setLanguage($language) 
 {

    // check if language is valid
    if ( self::isValidLanguage($language) ) {
        //set language cookie to 1 year
        setcookie('wi_lang', $language, time() + 60 * 60 * 24 * 365, '/');

        // update session
        WISession::set('wi_lang', $language);

        //refresh the page
        header('Location: ' . $_SERVER['PHP_SELF']);
    }
}

     public static function getLanguage() 
     {
    // check if cookie exist and language value in cookie is valid
    if ( isset ( $_COOKIE['wi_lang'] ) && self::isValidLanguage ( $_COOKIE['wi_lang'] ) )
        return $_COOKIE['wi_lang']; // return lang from cookie
    else
        return WISession::get('wi_lang', DEFAULT_LANGUAGE);
}


    private static function getTrans($language) 
    {
        $WIdb = WIdb::getInstance();
        //$file = WILang::getFile($language);
        //echo $file;
        //echo $language;
    if ( ! self::isValidLanguage($language) )
    die('Language file doesn\'t exist!');
    else {
        //$language = include $file;
        //return $language;

        $sql = "SELECT * FROM `wi_trans` WHERE `lang` = :file";
        $query = $WIdb->prepare($sql);
        $query->bindParam(':file', $language, PDO::PARAM_STR);
        $query->execute();
        //$result = array();
        while ($result = $query->fetchAll(PDO::FETCH_ASSOC)) {
            echo "{";
            foreach ($result as $res) {
            echo '"' .$res['keyword'] .'":"' . $res['translation'] . '",';
             //return array($res['keyword'] => $res['translation'] ,);  
        }

        echo "}";
        }

        }

}



 private static  function getFile($language) 
 {
    $WIdb = WIdb::getInstance();
    $sql = "SELECT * FROM `wi_lang` WHERE `lang` = :file";
    $query = $WIdb->prepare($sql);
    $query->bindParam(':file', $language, PDO::PARAM_STR);
    $query->execute();

    $res = $query->fetch(PDO::FETCH_ASSOC);
    //echo $res['lang'];
    if ($res > 0)
        return $res['lang'];
    else
        return '';


}

    private static function isValidLanguage($lang) 
    {
    $file = self::getFile($lang);
    //echo $file;

    if($file == "")
    //if ( ! file_exists( $file ) )
        return false;
    else
        return true;
}

}

【讨论】:

    【解决方案2】:

    试试这个解决方案。这个对我有用。它有法语和英语翻译。

    索引.php

    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
    <title>How to Translate your Site in Runtime using Jquery - demo</title>
    <link rel="stylesheet" href="css/main.css" type="text/css" />
    <script src="js/jquery.min.js"></script>
    <script src="js/main.js"></script>
    </head>
    <body>
    <div class="example">
    <h3><a href="#">How to Translate your Site in Runtime using Jquery - demo</a></h3>
    <div id="content">
    <div class="lang_switcher">
    <button id="en" class="lang">EN</button>
    <button id="fr" class="lang">FR</button>
    </div>
    <div style="clear:both;"></div>
    <!-- nav menu start -->
    <ul id="nav">
    <li><a href="#nogo" key="home" class="tr">Home</a></li>
    <li><a href="#nogo" key="peoples" class="tr">Peoples >></a>
    <ul>
    <li><a href="#nogo" key="all_list" class="tr">All list</a></li>
    <li><a href="#nogo" key="online" class="tr">Online</a></li>
    </ul>
    </li>
    <li><a href="#nogo" key="articles" class="tr">Articles >></a>
    <ul>
    <li><a href="#nogo" key="js" class="tr">JavaScript</a></li>
    <li><a href="#nogo" key="php" class="tr">PHP</a></li>
    <li><a href="#nogo" key="html" class="tr">HTML</a></li>
    <li><a href="#nogo" key="css" class="tr">CSS</a></li>
    </ul>
    </li>
    <li><a href="#nogo" key="contact_us" class="tr">Contact us</a></li>
    </ul>
    <!-- nav menu end -->
    <div style="clear:both;"></div>
    <h2 key="welcome" class="tr">Welcome guests</h2>
    <hr />
    <div key="a_man" class="tr">A man bribes a rabbit with wicked dentures to run away with him in a sailboat via an ambulance. Bribing Koalas to remain illegally in one place. Trees anchor me in place. / Your mom drives the ambulance, but the city is farther than it appears.</div>
    </div>
    </div>
    </body>
    </html>
    

    main.js

    // preparing language file
    var aLangKeys=new Array();
    aLangKeys['en']=new Array();
    aLangKeys['fr']=new Array();
    aLangKeys['en']['home']='Home';
    aLangKeys['en']['peoples']='Peoples >>';
    aLangKeys['en']['all_list']='All list';
    aLangKeys['en']['online']='Online';
    aLangKeys['en']['articles']='Articles >>';
    aLangKeys['en']['js']='JavaScript';
    aLangKeys['en']['php']='PHP';
    aLangKeys['en']['html']='HTML';
    aLangKeys['en']['css']='CSS';
    aLangKeys['en']['contact_us']='Contact us';
    aLangKeys['en']['welcome']='Welcome guests';
    aLangKeys['en']['a_man']='A man bribes a rabbit with wicked dentures to run away with him in a sailboat via an ambulance. Bribing Koalas to remain illegally in one place. Trees anchor me in place. / Your mom drives the ambulance, but the city is farther than it appears.';
    
    aLangKeys['fr']['home']='Accueil';
    aLangKeys['fr']['peoples']='Peuples >>';
    aLangKeys['fr']['all_list']='Toutes les listes';
    aLangKeys['fr']['online']='En ligne';
    aLangKeys['fr']['articles']='Articles >>';
    aLangKeys['fr']['js']='JavaScript';
    aLangKeys['fr']['php']='Php';
    aLangKeys['fr']['html']='Html';
    aLangKeys['fr']['css']='Css';
    aLangKeys['fr']['contact_us']='Contactez nous';
    aLangKeys['fr']['welcome']='Bienvenue aux invites';
    aLangKeys['fr']['a_man']="Un homme soudoie un lapin avec des prothèses méchantes pour s'enfuir avec lui dans un voilier via une ambulance. Corruption des Koalas pour qu'ils restent illégalement à un endroit. Les arbres m'ancrent en place. / Votre mère conduit l'ambulance, mais la ville est plus loin qu'il n'y paraît.";
    $(document).ready(function() {
    // onclick behavior
    $('.lang').click( function() {
    var lang = $(this).attr('id'); // obtain language id
    // translate all translatable elements
    $('.tr').each(function(i){
    $(this).text(aLangKeys[lang][ $(this).attr('key') ]);
    });
    } );
    });
    

    还有一些 css-main.css

    body{background:#eee;font-family:Verdana, Helvetica, Arial, sans-serif;margin:0;padding:0}
    .example{background:#FFF;width:500px;height:500px;font-size:80%;border:1px #000 solid;margin:0.5em 10% 0.5em;padding:1em 2em 2em;-moz-border-radius:3px;-webkit-border-radius:3px}
    .lang_switcher{float:right;overflow:hidden;}
    /* nav menu styles */
    #nav,#nav ul{list-style:none;font:10px verdana, sans-serif;border:1px solid #000;background:#fff;position:relative;z-index:200;border-color:#eca #b97 #a86 #edb;border-width:1px 2px 2px 1px;margin:0;padding:0 0 5px}
    #nav{height:25px;padding:0}
    #nav table{border-collapse:collapse}
    #nav li{float:left;padding:0 20px 0 10px}
    #nav li li{float:none}
    #nav li a li{float:left}
    #nav li a{display:block;float:left;color:#888;height:25px;padding-right:5px;line-height:25px;text-decoration:none;white-space:nowrap}
    #nav li li a{height:20px;line-height:20px;float:none}
    #nav li:hover{position:relative;z-index:300;background:#fff}
    #nav a:hover{position:relative;z-index:300;text-decoration:underline;color:#b75}
    #nav :hover ul{left:0;top:22px}
    #nav a:hover ul{left:-10px}
    #nav li:hover li:hover > ul{left:-15px;margin-left:100%;top:-1px}
    #nav li:hover > ul ul{position:absolute;left:-9999px;top:-9999px;width:auto}
    #nav li:hover > a{text-decoration:underline;color:#b75}
    #nav a:hover a:hover ul,#nav a:hover a:hover a:hover ul,#nav a:hover a:hover a:hover a:hover ul,#nav a:hover a:hover a:hover a:hover a:hover ul{left:100%;top:-1px}
    #nav ul,#nav a:hover ul ul,#nav a:hover a:hover ul ul,#nav a:hover a:hover a:hover ul ul,#nav a:hover a:hover a:hover a:hover ul ul{position:absolute;left:-9999px;top:-9999px}
    

    【讨论】:

      【解决方案3】:

      我翻译我的网站的方式是 在 doctype 下有 lang 然后是您选择的 lang,例如下面,

      然后创建一个php函数通过$_POST['get']获取这个, 并让该功能加载选定的语言文件/数据库等,

      【讨论】:

        【解决方案4】:

        我想你有点晚了,但万一像我这样的人偶然发现了这个线程......因为我目前遇到了同样的问题。 不幸的是,似乎没有一种“非繁琐的方式”可以用 PHP 做到这一点。一切似乎都涉及大量函数调用(如果您有很多文本)。

        嗯...有一种方便的方法。虽然不完全安全。在将输出缓冲区发送给用户之前对其进行操作: => http://dev-tips.com/featured/output-buffering-for-web-developers-a-beginners-guide

        因此,您可以根据选择的语言定义一个填充“from->to”-data 的数组,并通过循环替换缓冲区中的所有可读文本。

        但是当然...如果您例如将“send”(英语)替换为“senden”(德语)并链接到“send.html”,它会破坏该链接。

        因此,如果一个人不仅要翻译长的、绝对唯一的字符串,还要翻译较短的字符串,那么就必须只处理用户可读的文本。也有一个解决方案 - 但是,这是基于 JavaScript 的: => http://www.isogenicengine.com/documentation/jquery-multi-language-site-plugin/

        【讨论】:

        【解决方案5】:

        您始终可以使用 Google 的 Tools and Resourcesyour site 进行下注和翻译。

        一般来说,我认为多语言网站不再是“静态的”。我使用Drupal 来实现站点。它有一些很棒的internationalization options

        【讨论】:

        • 不,这不是一个选项,因为翻译必须是专业的,网站的设计也必须是专业的,即没有一些丑陋的谷歌翻译
        • @MetropolisCZ,十一年后,我并不感到惊讶;谷歌会定期让产品过期,永远不要长期依赖谷歌。然而,Drupal 解决方案仍然受到积极支持,并且无论如何是两者中更好的。
        【解决方案6】:

        您应该查看 PHP GETTEXT 扩展,它非常快,并且会扫描您的 PHP 文件中的字符串以使用 .MO 和 .PO 文件进行翻译

        然后您可以简单地执行__('Hello World'); 之类的操作,或者如果您已经拥有tr('Hello World'); 的所有字符串,那么您可以修改tr 函数以将其传递给__(string)gettext(string) 之类的......

        function tr($string){
            __($string)
        }
        

        【讨论】:

        • 这如何解决我的问题?这不会改变我在 HTML 中使用翻译的方式,而且由于我已经实现了后端,所以我没有看到任何好处。
        • 首先你的问题是说你确实使用 PHP,这是进行语言翻译的标准和最佳方式,比使用 PHP 数组要好得多。基本搜索将支持这些陈述,但如果您知道更好的解决方案,请继续使用。
        • 就像我说的,你的解决方案并不比我的好,而且对我的问题没有任何好处。
        • 翻译就是这样完成的。您可以提供一个字符串/键以从资源文件中执行直接查找,该资源文件将根据您的应用程序当前所处的任何语言检索正确的值。或者您创建指定页面的副本并将翻译后的文本放入英文文本的位置并将用户路由到子域(例如 es.mySite.com)。这些是本质上 i18n 仅有的两种方法 - 查找或复制代码。
        猜你喜欢
        • 1970-01-01
        • 2010-12-30
        • 1970-01-01
        • 2010-12-07
        • 1970-01-01
        • 2013-08-27
        • 1970-01-01
        • 2013-04-07
        • 2011-07-07
        相关资源
        最近更新 更多