CodeIgniter Forums
Negotiating locales - nicer urls - automatic routes - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Using CodeIgniter (https://forum.codeigniter.com/forumdisplay.php?fid=5)
+--- Forum: Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=11)
+--- Thread: Negotiating locales - nicer urls - automatic routes (/showthread.php?tid=78765)



Negotiating locales - nicer urls - automatic routes - versigtm - 03-08-2021

Hi there!

I thought I'd share some pieces of code with you about localization, because this has been one of my issues with CodeIgniter, that I solved in a more elegant way than using locales in the url & defining routes all the time.

I'll be using locale negotiation, the cookie helper, and the session library (partially, because I am still more comfortable using the $_SESSION variable).

1. First I needed to configure the App to handle more locales:

File: app\Config\App.php - the example is based on my needs for an app that runs by default in Romanian, but feel free to change it to whatever suits your needs
PHP Code:
public $defaultLocale 'ro';
public 
$negotiateLocale true;
public 
$supportedLocales = ['ro','en']; 

2. Then, I altered app\Controllers\BaseController.php - which is extended in all the controllers I used:
PHP Code:
//load cookie helper
protected $helpers = ['cookie']; 

I also changed the initController function as follows:
PHP Code:
//initialize session
$this->session = \Config\Services::session();

/* LOCALIZATION */

//check for locale cookie
if (!empty(get_cookie('locale')))
  $_SESSION['locale'] = get_cookie('locale');

//get request locale if locale session variable not yet set
isset($_SESSION['locale']) || $_SESSION['locale'] = $this->request->getLocale();

//define LOCALE constant, to use in lang() calls
defined ('LOCALE') || define ('LOCALE',$_SESSION['locale']); 

3. Then, I created the controller app\Controllers\Locale.php to change the selected locale, for users who want to change to another locale than the one negotiated by the browser:
PHP Code:
<?php

namespace App\Controllers;

class 
Locale extends BaseController
{

    
//set a new locale, overriding the negotiated locale
    
public function setlocale($locale)
    {

        if (
in_array($locale,config('App')->supportedLocales)) {
            
//set locale cookie
            
set_cookie('locale',$locale,MONTH);
        }

        return 
view('redirect',['url'=>$_SESSION['_ci_previous_url']]);

    }



The redirect view - app\Views\redirect.php:
Code:
<!DOCTYPE html>
<html lang="ro">
  <head>
    <meta charset="utf-8">
    <title>Redirecting</title>
    <script type="text/javascript">
      window.location.href = "<?=$url?>";
    </script>
  </head>
  <body>
    Redirecting...
  </body>
</html>

4. Finally, the only thing you need to use now is the LOCALE constant as the third parameter, when calling the lang() function.
PHP Code:
<?=lang('label.defined.in.Language.folder',[],LOCALE)?>

And here's how it works.

When visiting a page that extends BaseController:

  1. If a cookie containing the locale was previously set, the BaseController defines it as the locale session variable;
  2. If there is no locale session variable set, it acts as if visiting the site for the first time, and sets the negotiated locale as the locale session variable;
  3. Sets the LOCALE constant - just so that calling the lang() function looks prettier :)
When a user wants to change the locale, they should have a link to click, to access the setlocale method of the Locale controller - e.g. <?=site_url('locale/setlocale/en')?>
  1. If the specified locale is in the $supportedLocales configuration array, it sets the locale cookie to that value
  2. Displays the redirect view, so that the cookie is saved in the browser, which redirects afterwards to the previous url and selects the new locale using the cookie that was just set.
I hope this was useful.

Happy coding!