Step 4.2 – Set up the language for a multilanguage site in CodeIgniter

(created at: February 9, 2014; last update: December 2, 2015)

Once we’ve created the admin area for the multilanguage site is time for us to create the infrastructure so that the language is automatically passed to our controllers.

The routes.php

Going to our application/config/development/routes.php, we will add two lines so that in the end the file would look like below:

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

$route['default_controller'] = 'welcome';
$route['404_override'] = '';
$route['translate_uri_dashes'] = TRUE;

$route['admin'] = 'admin/dashboard';

$route['^(\w{2})/(.*)$'] = '$2';
$route['^(\w{2})$'] = $route['default_controller'];

Now, inside our application/core/MY_Controller.php we will change the MY_Controller so that it will keep the language slug in a session variable that will then be accessible by all the controllers. Also we will make available to all our controllers the available languages:

class MY_Controller extends CI_Controller
{
  protected $data = array();
  protected $langs = array();
  function __construct()
  {
    parent::__construct();
    $this->data['page_title'] = 'CI App';
    $this->data['before_head'] = '';
    $this->data['before_body'] = '';
    $this->load->model('language_model');
    $languages = $this->language_model->get_all();
    if($languages !== FALSE)
    {
      foreach($languages as $language)
      {
        $this->langs[$language->slug] = $language->id;
        if($language->default == '1') $default_language = $language->slug;
      }
    }

    $lang_slug = $this->uri->segment(1);

    if(isset($lang_slug) && array_key_exists($lang_slug, $this->langs))
    {
      $set_language = $lang_slug;
    }
    else
    {
      $set_language = $default_language;
    }

    if(isset($set_language))
    {
      $this->load->library('session');
      $_SESSION['set_language'] = $set_language;
    }
  }

  protected function render($the_view = NULL, $template = 'master')
  {
    if($template == 'json' || $this->input->is_ajax_request())
    {
      header('Content-Type: application/json');
      echo json_encode($this->data);
    }
    elseif(is_null($template))
    {
      $this->load->view($the_view,$this->data);
    }
    else
    {
      $this->data['the_view_content'] = (is_null($the_view)) ? '' : $this->load->view($the_view, $this->data, TRUE);
      $this->load->view('templates/' . $template . '_view', $this->data);
    }
  }
}

If everything went ok, and we’ve already added at least two languages with one language being the default one in admin area, it should all work ok. Let’s test it by going to application/controllers/Welcome.php and echoing the set language:

defined('BASEPATH') OR exit('No direct script access allowed');

class Welcome extends Public_Controller
{

  function __construct()
  {
    parent::__construct();
  }

  public function index()
  {
    echo $_SESSION['set_language'];
    echo '<br />';
    print_r($this->langs);
  }
}

Now, if inside the url we pass the slug for the languages we’ve inserted in the admin area, the correct language will be passed to the session. Also, if for some reason in the url we write some language slug that we didn’t insert in the admin area, the default language will be used.

And that’s it. Or is it? What if we want to “personalize” the controller and method names to that the users will be accessing them in their native language. A french person wouldn’t like to have “category” inside the URL. He/she talks french, so he/she expects to visit “categorie” and not “category”. In the next tutorial we will try to do “language personalized” controllers and methods.

23 comments

  1. Hello how to make slug in multi languange codeignter

    this is my table

    id, idartikcle, slug, title, artikel, lang

    which id is autoincrement and idarticle is same here is simple example table

    1 | 1 | Makan | makan adalah bla bla | in
    2 | 1 |eat |eat is bla-bla and bla | en

    how to make it cause when in view i have call slug how to make it works

      1. Silly me, here is my question how can i make slug to be dynamic when user change the languange

        here is my view http://pastebin.com/aYNf9xPE

        the question is how can i make slug being dinamis cause when change languange i debugging slug still old slug before change to another lang ?

        Thanks a lot

        1. Hello, the way I was thinking when talking about a multilanguage site was this: every slug is “personal” to every translation. So, there’s actually no dynamic slugs. Every slug belongs to its own translation. On the other hand, from what I see in your pastebin, you use the id of the article in the link, so when you ask for that “artikel”, you can simply query for the id of the article plus the language slug, and this way you will receive the right translation. I sure hope this helped you.

  2. I am getting this error, Can You please help me out. I am new to codeigniter.

    A PHP Error was encountered

    Severity: Notice

    Message: Undefined property: Welcome::$langs

    Filename: controllers/Welcome.php

    Line Number: 26

    Backtrace:

    File: C:\wamp\www\icmai\application\controllers\Welcome.php
    Line: 26
    Function: _error_handler

    File: C:\wamp\www\icmai\index.php
    Line: 309
    Function: require_once

          1. Here it is,

            Welcome.php

            /*************************************

            session->set_language;
            echo ”;
            print_r($this->langs);
            }
            }
            **********************************/

            My_Controller.php
            /************************************
            data[‘page_title’] = ‘CI App’;
            $this->data[‘before_head’] = ”;
            $this->data[‘before_body’] =”;
            $this->load->model(‘language_model’);
            $languages = $this->language_model->get_all();
            if($languages !== FALSE)
            {
            foreach($languages as $language)
            {
            $this->langs[$language->slug] = $language->id;
            if($language->default == ‘1’) $default_language = $language->slug;
            }
            }

            $lang_slug = $this->uri->segment(1);

            if(isset($lang_slug) && array_key_exists($lang_slug, $this->langs))
            {
            $set_language = $lang_slug;
            }
            else
            {
            $set_language = $default_language;
            }

            if(isset($set_language))
            {
            $this->load->driver(‘session’);
            $_SESSION[‘set_language’] = $set_language;
            }
            }

            protected function render($the_view = NULL, $template = ‘master’)
            {
            if($template == ‘json’ || $this->input->is_ajax_request())
            {
            header(‘Content-Type: application/json’);
            echo json_encode($this->data);
            }
            else
            {
            if($template==’site_master’)
            {
            $this->data[‘the_view_content’] = (is_null($the_view)) ? ” : $this->load->view($the_view,$this->data, TRUE);;
            $this->load->view(‘public/templates/’.$template.’_view’, $this->data);
            }
            else
            {
            $this->data[‘the_view_content’] = (is_null($the_view)) ? ” : $this->load->view($the_view,$this->data, TRUE);;
            $this->load->view(‘admin/templates/’.$template.’_view’, $this->data);
            }
            }
            }
            }

            class Admin_Controller extends MY_Controller
            {

            function __construct()
            {
            parent::__construct();
            $this->load->library(‘ion_auth’);
            if (!$this->ion_auth->logged_in())
            {
            //redirect them to the login page
            redirect(‘admin/user/login’, ‘refresh’);
            }
            $this->data[‘current_user’] = $this->ion_auth->user()->row();
            $user = $this->ion_auth->user()->row();
            $this->data[‘user’] = $user;
            $this->data[‘current_user_menu’] = ”;
            if($this->ion_auth->in_group(‘admin’))
            {

            $this->data[‘page_title’] = ‘Admin CI App – Dashboard’;
            }
            else{
            $this->data[‘page_title’] = ‘General CI App – Dashboard’;
            }
            }

            protected function render($the_view = NULL, $template = ‘admin_master’)
            {
            parent::render($the_view, $template);
            }
            }

            class Public_Controller extends MY_Controller
            {

            function __construct()
            {
            parent::__construct();
            $this->data[‘page_title’] = ‘CI App – Public view’;
            }

            protected function render($the_view = NULL, $template = ‘site_master’)
            {
            parent::render($the_view, $template);
            }
            }
            ***************************************/

  3. Thank you so much for providing us an elaborated tutorial and I feel that, You made it so easy.
    I appreciate your Hard work.

    I know, I am not allowed to say this, however, I felt that, It will
    help Newbees like me.

    “Please create a Flowchart/Roadmap of the whole tutorial, so that we
    can easily understand or remind, What we developed and learned so far”.

    Like, What we are going to do in whole tutorial and what we learned so far.

    1. When you will have something like “http://yourwebsite.com/en/article-title-slug” the “en” part is the language slug.

  4. Thanks for feedback Adrian,
    I’m asking because using the code above I get the following error:
    Unable to load the requested language file: language/it/auth_lang.php

    One more question: what does mean the following row in routes file?:
    $route[‘^(\w{2})/(.*)$’] = ‘$2’;

    As usual, thanks a lot for your invaluable help

    1. That means that a route having two url segments, first containing two letters and second containing whatever characters you want, will call the controller that starts with whatever characters (that means it trims the first part of the url). It’s some sort of preg_match() where $2 means “the second found element”… Don’t start me about regex because I hate it.

  5. when i use your code im getting errors

    [code]
    A PHP Error was encountered
    Severity: Notice
    Message: Undefined property: Welcome::$db
    Filename: core/Model.php
    Line Number: 77
    Backtrace:
    File: C:\xampp\htdocs\codeIgniter\application\models\Language_model.php
    Line: 19
    Function: __get
    File: C:\xampp\htdocs\codeIgniter\application\core\MY_Controller.php
    Line: 17
    Function: get_all
    File: C:\xampp\htdocs\codeIgniter\application\core\MY_Controller.php
    Line: 79
    Function: __construct
    File: C:\xampp\htdocs\codeIgniter\application\controllers\Welcome.php
    Line: 9
    Function: __construct
    File: C:\xampp\htdocs\codeIgniter\index.php
    Line: 315
    Function: require_once

    Fatal error: Call to a member function order_by() on null in C:\xampp\htdocs\codeIgniter\application\models\Language_model.php on line 19
    A PHP Error was encountered

    Severity: Error

    Message: Call to a member function order_by() on null

    Filename: models/Language_model.php

    Line Number: 19

    Backtrace:
    [/code]

    but when i remove this code inside of class MY_Controller
    [code]
    protected $langs = array();

    $this->load->model(‘language_model’);
    $languages = $this->language_model->get_all();
    if ($languages !== FALSE) {
    foreach ($languages as $language) {
    $this->langs[$language->slug] = $language->id;
    if ($language->default == ‘1’)
    $default_language = $language->slug;
    }
    }

    $lang_slug = $this->uri->segment(1);

    if (isset($lang_slug) && array_key_exists($lang_slug, $this->langs)) {
    $set_language = $lang_slug;
    } else {
    $set_language = $default_language;
    }

    if (isset($set_language)) {
    $this->load->library(‘session’);
    $_SESSION[‘set_language’] = $set_language;
    }
    [/code]
    then i have no errors

    1. Don’t “use” my code. This is a tutorial. If you would have followed it from start to end, I guess you wouldn’t have had this problem.

  6. Hello,
    I dont get the first part when you say ‘Going to our application/development/routes.php,’. Do i have to make a new folder in applications and make a routes.php file or is it the /application/config/development/routes.php

Leave a Reply

Your email address will not be published. Required fields are marked *

No spam? * Time limit is exhausted. Please reload CAPTCHA.