我是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和其他类的能力。
我能做到这一点的最佳方式是什么?我该怎么做/改变以及从哪里开始?
我知道这是一个更普遍的问题,但我们非常感谢任何帮助或指导。
非常感谢!
答案 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>';
}
}