Adding a prefix to every URL in CakePHP

后端 未结 3 567
感情败类
感情败类 2020-12-04 17:15

What\'s the cleanest way to add a prefix to every URL in CakePHP, like a language parameter?

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


        
相关标签:
3条回答
  • 2020-12-04 17:31

    An easier way might be to store the chosen language in a cookie and then not have to rewrite all the URLs. You could also potentially detect the user's browser language automatically.

    However, search engines would be unlikely to pickup the various languages and you'd also lose the language if someone tried to share the link.

    But love the full solution you posted, very comprehensive, thanks. :-)

    0 讨论(0)
  • 2020-12-04 17:40

    rchavik from IRC suggested this link: CakePHP URL based language switching for i18n and l10n internationalization and localization

    In general, it seems that overriding Helper::url might be the solution.

    0 讨论(0)
  • 2020-12-04 17:48

    This is essentially all the code I implemented to solve this problem in the end (at least I think that's all ;-)):

    /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;
        }
    }
    

    /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}'));
    

    This allows default URLs like /controller/action to use the default language (JPN in my case), and URLs like /eng/controller/action to use an alternative language. This logic can be changed pretty easily in the router_url_language() function.

    For this to work I also need to define two routes for each route, one containing the /:language/ parameter and one without. At least I couldn't figure out how to do it another way.

    0 讨论(0)
提交回复
热议问题