Kohana 3.3.3 多语言网站


Kohana 3.3.3 multi language site

我是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

在我的引导程序中.php我有以下路线(在添加语言逻辑之前):

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

如果可能的话,我希望在模块中拥有所有这些多语言逻辑。但是我读到了覆盖请求、URL、路由和其他类才能做到这一点的信息。

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

我知道这更像是一个一般性的问题,但任何帮助或指导都非常感谢。

非常感谢!

1) 将<lang>添加到引导程序中的路由中.php:

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

以某种方式定义 $default_lang - 我使用 siteconfig.php 放置在 application/config 中的文件 - 见下文。

2) 在请求控制器中扩展/重新定义工厂方法:

<?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) 在控制器类中扩展/重新定义"重定向"方法以进行自动语言添加:

<?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 类(例如用于模板),您可能应该重新定义一些其他方法,例如"锚点",用于创建具有自动语言添加的锚点:

<?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>';
    }
}

我找到了一个很棒的模块,它正在使用Kohana 3.3.3:https://github.com/creatoro/flexilang