Forum polskiej społeczności Zend Framework
Nie jesteś zalogowany.
Pierw przedstawię co mam, tzn. co udało mi się znaleźć w sieci:
- do booster (index.php)
<?php
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Europe/Warsaw');
set_include_path('.' . PATH_SEPARATOR . './library'
. PATH_SEPARATOR . './application/models/'
. PATH_SEPARATOR . get_include_path());
define('PUBLIC_DIR', dirname(__FILE__));
define('ROOT_DIR', dirname(PUBLIC_DIR));
require_once 'Zend/Loader/Autoloader.php';
require_once 'Zend/Session.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('My_');
$autoloader->setFallbackAutoloader(true);
Zend_Session::start();
// Zend_Form
$view = new Zend_View();
$view->addHelperPath('./library/Zend/View/Helper/');
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')
->setView($view);
// Konfiguracja bazy danych
$config = new Zend_Config_Ini('./application/config.ini', 'general');
$registry = Zend_Registry::getInstance();
$registry->set('config', $config);
// ustawienia bazy SQL
$db = Zend_Db::factory($config->db->adapter,
$config->db->config->toArray());
Zend_Db_Table::setDefaultAdapter($db);
Zend_Registry::set('db', $db);
// ustawienia kontrolera
$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory('./application/controllers');
$frontController->registerPlugin(new My_Language_Language());
// Dispatch
try {
$frontController->throwExceptions(true);
$frontController->dispatch();
} catch(Exception $ex) {
die($ex->getMessage());
}Language.php
<?php
/**
* Description of LangSelector
*
* @author jon
*/
class My_Language_Language extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
// Get the list of language files from lang directory
// Define the ROOT_DIR in your bootstrap
$dir = ROOT_DIR.'/kcms/languages/';
$dirIterator = new DirectoryIterator($dir);
$languages = array();
$translates = array();
foreach ($dirIterator as $subDir) {
if ($subDir->isDot() || !$subDir->isDir()) {
continue;
}
$file = $subDir->getFilename();
if ($file == '.svn') {
continue;
}
// Now $file = 'lang.xx_YY.ini'
// Get the language
$lang = explode('.', $file);
$lang = $lang[1];
// Now $lang = 'xx_YY'
$languages[] = $lang;
$translates[$lang] = new Zend_Translate('Ini', $file, $lang);
}
// Join supported languages
$languages = implode('|', $languages);
// Now $languages = 'en_US|fr_FR|xx_YY'
// Get the current URI
$currentUri = $request->getRequestUri();
$currentUri = ltrim($currentUri, '/');
// Compare it with supported lang URI
$pattern = '/('.$languages.')\/(\w+)\/(\w+)/';
if (preg_match($pattern, $currentUri, $matches)) {
$currLang = $matches[0];
$controller = $matches[1];
$action = $matches[2];
// Set the current language for view
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
if (null === $viewRenderer->view) {
$viewRenderer->initView();
}
$view = $viewRenderer->view;
$view->assign('translate', $translates[$currLang]);
// Set the controller, action for request
$request->setControllerName($controller)
->setActionName($action)
->setDispatched(true);
}
}
}w lang.en_US.ini
hello = "Hello"
w index.phtml
<?php echo $this->translate->_(hello); ?>
Błędy na stronie:
Fatal error: Call to a member function _() on a non-object in /home2/eurospl1/public_html/kcms/application/views/scripts/index/index.phtml on line 20
oraz
Notice: Undefined offset: 1 in /home2/eurospl1/public_html/kcms/library/My/Language/Language.php on line 29
deallas edit: Miałem napisać tytuł zgodny z pierwszym pytaniem, ale wątek nieco urósł więc stąd taki a nie inny tytuł![]()
Offline
w widoku dajesz:
<?php echo $this->translate('hello'); ?>Offline
Dziękuje za odpowiedź, jednak:
- na stronie zamiast Hello pojawia się hello
- po wpisaniu adres www.adres.pl/en/ lub www.adres.pl/en/index/ mam błąd:
Invalid controller specified (en)
Offline
Bardzo proszę o pomoc, sprawa jest pilna.
Offline
Nie wiem gdzie ty tego tutoriala znalazłeś, ale jest on strasznie przestarzały. Wyciąganie wersji językowej en/pl itd robi się przy pomocy routerów a nie pluginów (i to jeszcze w taki sposób brr:/). Zrób to proszę jak "Pan Bóg przykazał" wg tego video-tutoriala: http://alex-tech-adventures.com/develop … slate.html . Mimo, że jest po angielsku to większość da się zrozumieć patrząc choćby na sam kod. Autor dołącza także gotowe źródło więc możesz sobie podglądnąć jak to jest zrobione
Offline
Ok chyba się udało. A zrobiłem to tak:
- do index.php dodałem
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$route = new Zend_Controller_Router_Route(
':language/:controller/:action/*',
array(
'language' => 'pl',
'module' => 'default',
'controller' => 'index',
'action' => 'index'
)
);
$router->addRoute('lang_default', $route);
Zend_Controller_Front::getInstance()->registerPlugin(new My_Language_Language());Language.php
<?php
class My_Language_Language extends Zend_Controller_Plugin_Abstract
{
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
$lang = $request->getParam('language');
$locale = new Zend_Locale($lang);
Zend_Registry::set('Zend_Locale', $locale);
$translate = new Zend_Translate('gettext', './application/locale/pl/', 'pl');
$translate->addTranslation('./application/locale/eng/', 'en');
$requestParams = $this->getRequest()->getParams();
$language = (isset($requestParams['language'])) ? $requestParams['language'] : false;
if ($language == false) {
$language = ($translate->isAvailable($locale->getLanguage())) ? $locale->getLanguage() : 'pl';
}
$locale->setLocale($language);
$translate->setLocale($locale);
Zend_Form::setDefaultTranslator($translate);
setcookie('lang', $locale->getLanguage(), null, '/');
Zend_Registry::set('Zend_Translate', $translate);
}
}No i działa. Jak wpisze www.domena.pl/pl/ to pobiera dane z pliku pl a jak www.domena.pl/en/ do z pliku en.
Ok znalazłem sposób na linki ale teraz mam problem z:
Notice: The language 'root' has to be added before it can be used. in /home2/eurospl1/public_html/kcms/library/Zend/Translate/Adapter.php on line 322 Notice: No translation for the language 'root' available. in /home2/eurospl1/public_html/kcms/library/Zend/Translate/Adapter.php on line 335
Tzn zrobiłem to tak:
<a href="<?= $this->url(array('controller'=>'blog','action'=>'index')); ?>/">Blog</a>I tak dla każdego linka, a nie można jakoś zrobić żeby to /pl/ lub /en/ samo przechodziło bez dopisywania do każdego linka takiej formułki?
--------------------------------------------------------------
Już sobie ze wszystkim poradziłem ![]()
Ostatnio edytowany przez miSq (2010-02-16 15:59:38)
Offline
Pojawia się pytanie. Jak przy tym sposobie tłumaczyć label`e dla formów. Element mam zbudowany tak:
$name = new Zend_Form_Element_Text('name');
$name->setLabel('Imię i Nazwisko')
->setRequired(true)
->setAttrib('size', 45)
->addValidator('NotEmpty')
->setFilters(array('StripTags', 'StringTrim'))
->setDecorators(array(
'ViewHelper',
'Errors',
array(array('data' => 'HtmlTag'), array('tag' => 'td', 'class' => 'element')),
array('Label', array('tag' => 'td')),
array(array('row' => 'HtmlTag'), array('tag' => 'tr'))));Offline
miSq napisał:
Pojawia się pytanie. Jak przy tym sposobie tłumaczyć label`e dla formów.
$name->setLabel($this->getTranslator()->_('imie_i_nazwisko'));Offline
A wystarczy poczytać manuala...
http://framework.zend.com/manual/en/zend.form.i18n.html
Initializing I18n in Forms
In order to initialize I18n in forms, you will need either a Zend_Translate object or a Zend_Translate_Adapter object, as detailed in the Zend_Translate documentation. Once you have a translation object, you have several options:
Easiest: add it to the registry. All I18n aware components of Zend Framework will autodiscover a translate object that is in the registry under the 'Zend_Translate' key and use it to perform translation and/or localization:Kod:
// use the 'Zend_Translate' key; $translate is a Zend_Translate object: Zend_Registry::set('Zend_Translate', $translate);This will be picked up by Zend_Form, Zend_Validate, and Zend_View_Helper_Translate.
Dzięki temu formy (i w zasadzie wszystkie inne komponenty ZF) będą automatycznie używały translatora.
Ostatnio edytowany przez Diabl0 (2010-03-06 13:04:23)
Offline
Zrobiłem tak jak maciek.231 pokazał i super działa. Ostatnia rzecz jaka mi do szczęścia potrzebna to przełączanie języków. Obecnie mam tak zrobione że zmieniam język poprzez kliknięcie w flagę, wracam do głównej strony. Czyli jak mam www.domena.pl/pl/kontakt/ i chciałbym przejść na język angielski to adres będzie taki www.domena.pl/en/ . Jest jakiś sposób by zachować adres i zmienić tylko język?
Offline
na przykład poprzez view helpera:
public function langSwitch($lang) {
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$request = $front->getRequest();
$name = $router->getCurrentRouteName();
$params = $request->getParams();
$reset = TRUE;
if ($name != 'default') {
//czy jest lang
if (isset($params['lang'])) {
//zmienia
$params['lang'] = $lang;
}
unset($params['module']);
unset($params['controller']);
unset($params['action']);
$urlOptions = array_merge($params,array('@locale' => $lang));
return $this->view->url($urlOptions,$name,$reset);
}
// domyślna trasa bez lang
return $this->view->url($params,$name,$reset);
}Offline
Coś nie za bardzo mi to poszło, a zrobiłem tak. Utworzyłem sobie helpera:
<?php
class Zend_View_Helper_SwitchLang
{
public function langSwitch($lang) {
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$request = $frontController->getRequest();
$name = $router->getCurrentRouteName();
$params = $request->getParams();
$reset = TRUE;
if ($name != 'default') {
//czy jest lang
if (isset($params['language'])) {
//zmienia
$params['language'] = $lang;
}
unset($params['module']);
unset($params['controller']);
unset($params['action']);
$urlOptions = array_merge($params,array('@locale' => $lang));
return $this->view->url($urlOptions,$name,$reset);
}
// domyślna trasa bez lang
return $this->view->url($params,$name,$reset);
}
}W phtml dodałem tak na próbę:
<?php $this->switchLang("pl");?>A błąd mam taki:
<br /> <b>Warning</b>: call_user_func_array() [<a href='function.call-user-func-array'>function.call-user-func-array</a>]: First argument is expected to be a valid callback, 'Zend_View_Helper_SwitchLang::switchLang' was given in <b>/home/acm-group/ftp/proton/library/Zend/View/Abstract.php</b> on line <b>340</b><br />
Offline
Sorry za double posta ale chce napisać coś z innej beczki ale do tematu. Aktualnie wyskrobałem sobie taka funkcje w JS:
function LinkTo(object)
{
var www = window.location.href;
if (object == '/pl/')
{sitec=www.replace(object, "/en/");}
else
{sitec=www.replace(object, "/pl/");}
this.location.href = sitec;
}A adres zmieniam tak:
<a href="javascript:LinkTo('/en/')"><img src="<?php echo $this->baseUrl;?>/public/images/cms/flags/pl.png" alt="Polish" /></a>Działa bo działa. Ale nie wiem czy to jest bezpieczne i dobre.
Offline
co do kodu który Ci podałem to nazwa klasy helpera musi być taka sama jak nazwa metody w tym helperze. Czyli dla twojej klasy helpera metoda powinna nazywać się switchLang(). Poza tym prefix Zend_View_Helper_ powoduje że autoloader szuka jej w bibliotece zenda. Nie wiem jaką masz strukturę plików ale radzę do katalogów zenda nie pakować swoich rozszerzeń/klas.
Offline
Ok to teraz tak:
Notice: Undefined property: Zend_View_Helper_SwitchLang::$view in /home/acm-group/ftp/proton/library/Zend/View/Helper/SwitchLang.php on line 24 Fatal error: Call to a member function url() on a non-object in /home/acm-group/ftp/proton/library/Zend/View/Helper/SwitchLang.php on line 24
line 24: return $this->view->url($urlOptions,$name,$reset);
Offline
ok. nie zauważyłem że twój helper nie dziedziczy po Zend_View_Helper_Abstract
powinno być:
class Zend_View_Helper_SwitchLang extends Zend_View_Helper_Abstract
{
...
}Offline
Teraz wyświetla mi się tylko znak / . Może nie mam czegoś podpiętego bo w bootstrapie mam tak:
// ustawienia kontrolera
$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory('./application/controllers');
$router = $frontController->getRouter();
$route = new Zend_Controller_Router_Route(
':language/:controller/:action/*',
array(
'language' => 'pl',
'module' => 'default',
'controller' => 'index',
'action' => 'index'
)
);
$router->addRoute('lang_default', $route);
Zend_Controller_Front::getInstance()->registerPlugin(new My_Language_Language());
$frontController->throwExceptions(true);
$frontController->dispatch();Plik od języka:
<?php
class My_Language_Language extends Zend_Controller_Plugin_Abstract
{
public function routeShutdown(Zend_Controller_Request_Abstract $request) {
$lang = $request->getParam('language');
$locale = new Zend_Locale($lang);
Zend_Registry::set('Zend_Locale', $locale);
$translate = new Zend_Translate('gettext', './application/locale/pl/', 'pl');
$translate->addTranslation('./application/locale/eng/', 'en');
$requestParams = $this->getRequest()->getParams();
$language = (isset($requestParams['language'])) ? $requestParams['language'] : false;
if ($language == false) {
$language = ($translate->isAvailable($locale->getLanguage())) ? $locale->getLanguage() : 'pl';
}
if (!$translate->isAvailable($language)) {
throw new Zend_Controller_Action_Exception('Strona nie istnieje', 404);
} else {
$locale->setLocale($language);
$translate->setLocale($locale);
Zend_Form::setDefaultTranslator($translate);
setcookie('lang', $locale->getLanguage(), null, '/');
Zend_Registry::set('Zend_Translate', $translate);
}
}
}No i klasa cała do zmiany języka:
<?php
class Zend_View_Helper_SwitchLang extends Zend_View_Helper_Abstract
{
public function switchLang($lang) {
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$request = $frontController->getRequest();
$name = $router->getCurrentRouteName();
$params = $request->getParams();
$reset = TRUE;
if ($name != 'default') {
//czy jest lang
if (isset($params['language'])) {
//zmienia
$params['language'] = $lang;
}
unset($params['module']);
unset($params['controller']);
unset($params['action']);
$urlOptions = array_merge($params,array('@locale' => $lang));
return $this->view->url($params,$name,$reset);
}
// domyślna trasa bez lang
return $this->view->url($params,$name,$reset);
}
}Offline
Jak jestem na stronie "/en/sklep/" pojawia się /en jak wejdę w kategorię "/en/sklep/kat/cat_id/2/" to znika. Jak wejdę tak "/pl/sklep/" do dalej jest /en
Offline
wydaje mi się że problem związany jest z trasami. Rozumiem że masz zdefiniowaną tylko jedną trasę lang_default.
Ja wyłączyłem całkiem domyślne trasy i wszystkie definiuje na nowo.
Najlepiej zobacz co u Ciebie zawiera zmienna params w helperze zend_dump::debug($params);
Offline
Spróbuj tak:
<?php
class Zend_View_Helper_SwitchLang extends Zend_View_Helper_Abstract
{
public function switchLang($lang) {
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$request = $frontController->getRequest();
$name = $router->getCurrentRouteName();
$params = $request->getParams();
$reset = TRUE;
if ($name != 'default') {
if (isset($params['language'])) {
$params['language'] = $lang;
}
}
return $this->view->url($params,$name,$reset);
}
}Usunąłem co niepotrzebne.
Offline
Super to działa, jednak na koniec adresu dodaje "/module/default"
Offline
właśnie po to był fragment kodu
unset($params['module']); unset($params['controller']); unset($params['action']);
Offline
Zależy jak kto korzysta z routerów. Przykładowo przy takim routerze:
$router = $frontController->getRouter();
$route = new Zend_Controller_Router_Route(
':language/:module/:controller/:action/*',
array(
'language' => 'pl',
'module' => 'default',
'controller' => 'index',
'action' => 'index'
)
);
$router->addRoute('lang', $route);
$router->removeDefaultRoutes();i takim widoku:
<a href="<?=$this->switchLang('en') ?>">EN</a> | <a href="<?=$this->switchLang('pl') ?>">PL</a>wygeneruje ładnie:
<a href="/en/default/index/test">EN</a> | <a href="/pl/default/index/test">PL</a>
Offline
Zrobiłem tak:
class Zend_View_Helper_SwitchLang extends Zend_View_Helper_Abstract
{
public function switchLang($lang) {
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$request = $frontController->getRequest();
$name = $router->getCurrentRouteName();
$params = $request->getParams();
$reset = TRUE;
if ($name != 'default') {
if (isset($params['language'])) {
$params['language'] = $lang;
}
}
unset($params['module']);
return $this->view->url($params,$name,$reset);
}
}I jest dobrze. Dziękuje wszystkim za pomoc.
Offline
To ja zadam inne pytanie. Używam adaptera tmx i cache'owania tłumaczeń. Pod FF jest ok, nie ma notice'ów. Wchodzę pod Operę czy IE i dostaję:
Notice: No translation for the language 'pl_PL' available. in D:\wamp\www\application\library\Zend\Translate\Adapter.php on line 418
I o co tu chodzi? Po wyłączeniu cache wszystko działa pod każdą przeglądarką.
Kod translatora:
$frontendOptions = array('lifetime' => 86400,
'automatic_serialization' => true);
$backendOptions = array('cache_dir' => APPLICATION_PATH.'/cache');
$cache = Zend_Cache::factory('Page',
'File',
$frontendOptions,
$backendOptions);
Zend_Translate::setCache($cache);
$translate = new Zend_Translate('tmx',
APPLICATION_PATH . '/languages',
null,
array('scan' => Zend_Translate::LOCALE_FILENAME));A tu plik TMX:
<?xml version="1.0" ?>
<!DOCTYPE tmx SYSTEM "tmx14.dtd">
<tmx version="1.4">
<header>
</header>
<body>
<tu tuid='ok'>
<tuv xml:lang="pl"><seg>Dobrze</seg></tuv>
<tuv xml:lang="en"><seg>Okay</seg></tuv>
<tuv xml:lang="de"><seg>Ja wohl</seg></tuv>
</tu>
</body>
</tmx>Ostatnio edytowany przez robos85 (2010-06-16 09:39:48)
Offline