2009-11-25 14 views
20

में प्रत्येक यूआरएल में एक उपसर्ग जोड़ना एक भाषा पैरामीटर की तरह केकेपीएचपी में प्रत्येक यूआरएल में उपसर्ग जोड़ने का सबसे साफ तरीका क्या है?केकेपीएचपी

http://example.com/en/controller/action 
http://example.com/ru/admin/controller/action 

यह admin की तरह 'असली' उपसर्गों के साथ काम करने के लिए, और आदर्श रूप में नंगे यूआरएल /controller/action/DEFAULT-LANGUAGE/controller/action पर पुनः निर्देशित किया जा सकता है की जरूरत है।

यह अब मेरे लिए एक रेट्रो-फिट अनुप्रयोग में काम कर रहा है, लेकिन यह एक हैक था, और मुझे अधिकांश लिंक में हाथ से भाषा पैरामीटर शामिल करना होगा, जो अच्छा नहीं है।

तो सवाल दोहरा है:

  • सबसे अच्छा तरीका मार्गों की संरचना करने के क्या है, इसलिए भाषा पैरामीटर परोक्ष प्रत्येक नव परिभाषित मार्ग के लिए निर्दिष्ट किया जा बिना डिफ़ॉल्ट रूप से शामिल है?
    • Router::connect('/:controller/:action/*', ...) में उपसर्ग शामिल होना चाहिए।
    • पैरामीटर $this->params['lang'] में उपलब्ध होना चाहिए या AppController::beforeFilter() में कहीं भी मूल्यांकन किया जाना चाहिए।
  • यूआरएल में उपसर्ग को स्वचालित रूप से निर्दिष्ट करने के लिए Router::url() कैसे प्राप्त करें, अगर स्पष्ट रूप से निर्दिष्ट नहीं किया गया है?
    • Router::url(array('controller' => 'foo', 'action' => 'bar'))/en/foo/bar
    • लौटना चाहिए Controller::redirect() के बाद से, Form::create() या यहाँ तक कि Router::url() सीधे अधिभावी हर एक समारोह वास्तव में एक विकल्प नहीं है, एक ही व्यवहार की आवश्यकता है। उदाहरण के लिए Html::image() हालांकि उपसर्ग-कम यूआरएल उत्पन्न करना चाहिए।

निम्न विधियों Router::url कॉल करने के लिए लग रहे हैं।

  • Controller::redirect
  • Controller::flash
  • Dispatcher::__extractParams के माध्यम से Object::requestAction
  • Helper::url
  • JsHelper::load_
  • JsHelper::redirect_
  • View::uuid, लेकिन केवल एक हैश पीढ़ी के लिए

उनमें से बाहर ऐसा लगता है कि नियंत्रक और सहायक विधि को ओवरराइड करने की आवश्यकता होगी, मैं JsHelper के बिना रह सकता हूं। मेरा विचार पैरामीटर सम्मिलन को संभालने के लिए AppController या शायद bootstrap.php में एक सामान्य फ़ंक्शन लिखना होगा। ओवरराइड कंट्रोलर और हेल्पर विधियां इस फ़ंक्शन का उपयोग करेंगी, जैसे कि मैं मैन्युअल रूप से Router::url पर कॉल करना चाहता हूं। क्या यह पर्याप्त होगा?

आईआरसी से

उत्तर

5

rchavik इस लिंक का सुझाव दिया: CakePHP URL based language switching for i18n and l10n internationalization and localization

सामान्य में, ऐसा लगता है कि अधिभावी Helper::url समाधान हो सकता है।

/config/bootstrap.php

define('DEFAULT_LANGUAGE', 'jpn'); 

if (!function_exists('router_url_language')) { 
    function router_url_language($url) { 
     if ($lang = Configure::read('Config.language')) { 
      if (is_array($url)) { 
       if (!isset($url['language'])) { 
        $url['language'] = $lang; 
       } 
       if ($url['language'] == DEFAULT_LANGUAGE) { 
        unset($url['language']); 
       } 
      } else if ($url == '/' && $lang !== DEFAULT_LANGUAGE) { 
       $url.= $lang; 
      } 
     } 

     return $url; 
    } 
} 

:

+0

और टिप्पणियों के अनुसार, अधिभावी 'AppController :: url' यह नियंत्रकों के लिए करना होगा। अब तक इतना अच्छा है, क्या कुछ और है? अन्य भागों को सीधे 'राउटर :: यूआरएल' कहते हैं? – deceze

14

यह अनिवार्य रूप से सभी कोड मैं अंत में इस समस्या को हल करने के लिए (कम से कम मुझे लगता है कि सब है ;-)) लागू किया है /config/core.php

Configure::write('Config.language', 'jpn'); 

/app_helper.php

class AppHelper extends Helper { 

    public function url($url = null, $full = false) { 
     return parent::url(router_url_language($url), $full); 
    } 

} 

/app_controller.php

class AppController extends Controller { 

    public function beforeFilter() { 
     if (isset($this->params['language'])) { 
      Configure::write('Config.language', $this->params['language']); 
     } 
    } 

    public function redirect($url, $status = null, $exit = true) { 
     parent::redirect(router_url_language($url), $status, $exit); 
    } 

    public function flash($message, $url, $pause = 1) { 
     parent::flash($message, router_url_language($url), $pause); 
    } 

} 

/config/routes.php

Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home')); 
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display')); 
Router::connect('/:language/', array('controller' => 'pages', 'action' => 'display', 'home'), array('language' => '[a-z]{3}')); 
Router::connect('/:language/pages/*', array('controller' => 'pages', 'action' => 'display'), array('language' => '[a-z]{3}')); 
Router::connect('/:language/:controller/:action/*', array(), array('language' => '[a-z]{3}')); 

यह /controller/action तरह डिफ़ॉल्ट यूआरएल डिफ़ॉल्ट भाषा के उपयोग करने के लिए अनुमति देता है (JPN में मेरा मामला), और वैकल्पिक उपयोग करने के लिए /eng/controller/action जैसे यूआरएल निष्क्रिय भाषा। router_url_language() फ़ंक्शन में यह तर्क बहुत आसानी से बदला जा सकता है।

इस काम के लिए मुझे प्रत्येक मार्ग के लिए दो मार्गों को परिभाषित करने की भी आवश्यकता है, जिसमें /:language/ पैरामीटर और बिना किसी एक है। कम से कम मैं यह नहीं समझ सका कि इसे कैसे एक और तरीका करना है।

+0

महान जवाब, यह वास्तव में मेरी मदद की। – gacrux

+2

@gacrux ध्यान दें कि यह केक 1.3 में बहुत कम जटिल होना चाहिए, जिसमें अनुकूलन उपसर्ग शामिल हैं। उपरोक्त केक 1.2 पर लागू होता है, जो केवल * एक * उपसर्ग जानता था। :) – deceze

0

एक आसान तरीका एक कुकी में चुनी गई भाषा स्टोर करने के लिए और फिर सभी URL पुनः लिखने की जरूरत नहीं हो सकती है। आप संभावित रूप से उपयोगकर्ता की ब्राउज़र भाषा का पता लगा सकते हैं।

हालांकि, खोज इंजन विभिन्न भाषाओं पिक करने की संभावना नहीं होगा और आप भी भाषा खो देंगे अगर कोई लिंक साझा करने की कोशिश की।

लेकिन, धन्यवाद पूर्ण समाधान आप पोस्ट, बहुत व्यापक प्यार करता हूँ। :-)

+1

"यूआरएल-कम" भाषा स्विच के साथ समस्या खोज इंजन है। वे केवल एक ही भाषा को अनुक्रमित करेंगे या एक ही यूआरएल पर अलग-अलग सामग्री देखते हैं, तो वे अपने पैंटी को एक गुच्छा में प्राप्त करेंगे। यह केवल आपकी साइट के निजी (केवल लॉगिन) क्षेत्रों के लिए काम करता है। – deceze

+0

ओह, हाँ यह एक अच्छा मुद्दा है। मैं ध्यान देने के लिए अपना जवाब अपडेट करूंगा। –

संबंधित मुद्दे