Kohana 3.3.3多语言网站

时间:2015-02-03 22:03:05

标签: php kohana-3.3

我是Kohana的新手,使用版本3.3.3.1,我试图建立一个简单的动态网站,内容/页面存储在mySQL DB中。该网站应该有多种语言。我尝试到处寻找一个好的解决方案/模块,但我找不到任何适用于最新版Kohana的东西。我也尝试了这个:https://github.com/shockiii/kohana-multilang但它没有在最新的kohana上工作。

我想将语言放在这样的URL中(并且可能隐藏默认语言的参数):

http://www.domain.com/topics/page-name-here.html   -- this would be default EN
http://www.domain.com/de/test/some-page-name-here.html
http://www.domain.com/fr/category/other-page-name-here.html

在我的bootstrap.php中,我有以下路由(在添加语言逻辑之前):

Route::set('page', '(<category>)(/<pagename>.html)', array(
    'category' => '.*', 
    'pagename' => '.*'))
    ->defaults(array(
                'controller' => 'Page',
                'action' => 'index',
)); 

如果可能的话,我希望在模块中拥有所有这些多语言逻辑。但我读到了覆盖Request,URL,Route和其他类的能力。

我能做到这一点的最佳方式是什么?我该怎么做/改变以及从哪里开始?

我知道这是一个更普遍的问题,但我们非常感谢任何帮助或指导。

非常感谢!

2 个答案:

答案 0 :(得分:0)

我找到了一个与Kohana 3.3.3合作的好模块:https://github.com/creatoro/flexilang

答案 1 :(得分:0)

1)将<lang>添加到bootstrap.php中的路由中:

Route::set('default', '((<lang>)(/)(<controller>)(/<action>(/<id>)))', array('lang' => "({$langs_abr})",'id'=>'.+'))
    ->defaults(array(
        'lang'          => $default_lang,
        'controller'    => 'Welcome',
        'action'        => 'index',
    ));

- 以某种方式定义$ default_lang - 我使用位于application/config内的siteconfig.php文件 - 见下文。

2)在Request Controller中扩展/重新定义工厂方法:

<?php defined('SYSPATH') or die('No direct script access.');

class Request extends Kohana_Request {
    /**
     * Main request singleton instance. If no URI is provided, the URI will
     * be automatically detected using PATH_INFO, REQUEST_URI, or PHP_SELF.
     *
     * @param   string   URI of the request
     * @return  Request
     */
    public static function factory( $uri = TRUE,$client_params = array(), $allow_external = TRUE, $injected_routes = array())
    {

        $instance = parent::factory($uri);

        $index_page     = Kohana::$index_file;
        $siteconfig     = Model_Siteconfig::load();
        $lang_uri_abbr  = $siteconfig['lang_uri_abbr'];
        $default_lang   = $siteconfig['language_abbr'];
        $lang_ignore    = $siteconfig['lang_ignore'];

        $ignore_urls    = $siteconfig['ignore_urls'];

        /* get the lang_abbr from uri segments */
        $segments = explode('/',$instance->detect_uri());

        $uri_detection  = array_intersect($segments, $ignore_urls);

        if(empty($uri_detection))
        {

            $lang_abbr = isset($segments[1]) ? $segments[1]:'';

            /* get current language */
            $cur_lang = $instance->param('lang',$default_lang);

            /* check for invalid abbreviation */
            if( ! isset($lang_uri_abbr[$lang_abbr]))
            {       
                /* check for abbreviation to be ignored */
                if ($cur_lang != $lang_ignore) {
                    /* check and set the default uri identifier */
                    $index_page .= empty($index_page) ? $default_lang : "/$default_lang";

                    /* redirect after inserting language id */
                    header('Location: '.URL::base().$index_page . $instance->detect_uri());
                    die();
                }
            }
        }

        return $instance;

    }
}

我使用带有语言定义的“siteconfig”数组:

array(
        'language_abbr'     => 'cs',
        'lang_uri_abbr'     => array("cs" => "česky", "en" => "english"),
        'lang_ignore'       => 'it', 
)

3)在Controller类中扩展/重新定义“重定向”方法以自动添加语言:

<?php defined('SYSPATH') or die('No direct script access.');

class Controller extends Kohana_Controller {

    /**
     * Issues a HTTP redirect.
     *
     * Proxies to the [HTTP::redirect] method.
     *
     * @param  string  $uri   URI to redirect to
     * @param  int     $code  HTTP Status code to use for the redirect
     * @throws HTTP_Exception
     */
    public static function redirect($uri = '', $code = 302)
    {
        $lng = Request::current()->param('lang');
        return HTTP::redirect( (string) '/'.$lng.$uri, $code);
    }
}

如果你要使用HTML类(例如模板),你应该重新定义一些其他方法,比如“anchor”,用于创建带有自动语言添加的锚点:

<?php defined('SYSPATH') OR die('No direct script access.');

class HTML extends Kohana_HTML {

    /**
     * Create HTML link anchors. Note that the title is not escaped, to allow
     * HTML elements within links (images, etc).
     *
     *     echo HTML::anchor('/user/profile', 'My Profile');
     *
     * @param   string  $uri        URL or URI string
     * @param   string  $title      link text
     * @param   array   $attributes HTML anchor attributes
     * @param   mixed   $protocol   protocol to pass to URL::base()
     * @param   boolean $index      include the index page
     * @return  string
     * @uses    URL::base
     * @uses    URL::site
     * @uses    HTML::attributes
     */
    public static function anchor($uri, $title = NULL, array $attributes = NULL, $protocol = NULL, $index = FALSE)
    {

        //default language
        $lng = Request::current()->param('lang');

        if ($title === NULL)
        {
            // Use the URI as the title
            $title = $uri;
        }

        if ($uri === '')
        {
            // Only use the base URL
            $uri = URL::base($protocol, $index).$lng;
        }
        else
        {
            if (strpos($uri, '://') !== FALSE)
            {
                if (HTML::$windowed_urls === TRUE AND empty($attributes['target']))
                {
                    // Make the link open in a new window
                    $attributes['target'] = '_blank';
                }
            }
            elseif ($uri[0] !== '#')
            {
                // Make the URI absolute for non-id anchors
                $uri = URL::site($lng.$uri, $protocol, $index);
            }
        }

        // Add the sanitized link to the attributes
        $attributes['href'] = $uri;

        return '<a'.HTML::attributes($attributes).'>'.$title.'</a>';
    }

}