Step 7 – Using the language files for a multi-language site in CodeIgniter

Well, it seems I left this tutorial series hanging for a long time. But that only happens because I am in an inspiration hiatus: I simply don’t know what other subject to talk about.

And yet, there are some smart people who really want to learn, and find the time (and courage, I might add) to put a question in the comments section of my tutorials. One such question showed me that I didn’t cover all aspects of a multi-language site. Federico wrote: “Sorry Adrian, I still cannot understand if and how this great Language system can use default CI3 Language system. I mean… to load languages files… what I have to do?… Thanks“. That is a really good question. If we have a multi-language site and a framework that allows the use of language files, when and how do we work with these?

First things first: Why do we need language files?

Considering we are making a multi-language site, we also need to work on a design that is… well… multi-language. What I mean by this is that you don’t have to create a separate page template for every language that you have in your site. That would be dumb. So, we only need to create a template that accesses some strings in different languages according to the language selected by the users of your site.

Getting to work

Considering you’ve followed all the steps before this one, it’s easy to access what language we are using, by simply calling the variable $this->data[‘current_lang’]. We’ve defined this variable inside the MY_Controller. This variable is actually an array which contains everything we need to know about the selected language.

So how do we use this?

Considering that by typing the website address, people will be directed to the Welcome controller, we will create/edit that Welcome controller:

 

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Welcome extends Public_Controller
{
  function __construct()
  {
    parent::__construct();
  }

  public function index()
  {
    $this->render('public/homepage_view');
  }
}

As you can see, the Welcome controller extends the Public_Controller. If you missed it, here is the Public_Controller class (which is defined inside the MY_Controller.php file):

 

class Public_Controller extends MY_Controller
{
  function __construct()
  {
    parent::__construct();
    protected function render($the_view = NULL, $template = 'public_master')
    {
      $this->load->library('menus');
      $this->data['top_menu'] = $this->menus->get_menu('top-menu',$this->current_lang,'bootstrap_menu');
      parent::render($the_view, $template);
    }
}

Now let’s look at the view, which we will create inside application/views/public/homepage_view.php

<?php defined('BASEPATH') OR exit('No direct script access allowed');?>
<div class="container" style="margin-top: 60px;">
<?php
  echo '<br />'.$current_lang['slug'];
  echo '<br />hello';
  echo '<pre>';
  print_r($langs);
  echo '</pre>';
?>
</div>

Also, in case you missed this, the render() method is actually calling a master template, which in turn calls the header, the footer and the content files. If you really need an up-to-date application I would rather send you to my Github repository, as this is not really a scope of this tutorial, but the result of previous tutorials: https://github.com/avenirer/CodeIgniter-multilanguage-site. As you may see, there are also some things in there that we’ve not covered in our series like website status and banned ips, but this is the stage at which the site is… Don’t worry, nothing big is going on, but you can use the repository as base for your multilanguage site.

The template views

OK. Let’s assume the same homepage_view.php will be rendered in all languages. How would we go about when we have text inside the templates?

We first need to create our language files. So, let’s start by creating the english language file. We will save a file named interface_lang.php (or whatever name you like) inside application/language/english directory (you must create the english directory):

The basic format of the language file would be:

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

Now let’s add our first string. How about an welcome text? We will save the welcome text as ane element inside a $lang array:

 

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

$lang['homepage_welcome'] = 'Welcome to our website. We sure hope you will like what you will find in here.';

Simple enough… Now, we only have to use this file inside our template pages. First of all, how do we call the language file? The fastest way would be to call them inside the controllers, but then you would have to call this file in every controller. So why not call the language file inside the Public_Controller (or even the MY_Controller if you plan to also make the administration area multi-language):

class Public_Controller extends MY_Controller
{
  function __construct()
  {
    parent::__construct();
    $language = $this->data['current_language'];
    $idiom = $language['language_directory'];
    $this->load->language('interface_lang',$idiom);
  }

  protected function render($the_view = NULL, $template = 'public_master')
  {
    $this->load->library('menus');
    $this->data['top_menu'] = $this->menus->get_menu('top-menu',$this->current_lang,'bootstrap_menu');
    parent::render($the_view, $template);
  }
}

As you can see from the lines …., we’ve took the language directory name from the $this->data[‘current_lang’] variable, and we simply used $this->load->language() method to call the language file we need.

Now all we need to do is go to our homepage_view.php file and use the key for the particular string we need to get:

<?php defined('BASEPATH') OR exit('No direct script access allowed');?>
<div class="container" style="margin-top: 60px;">
<?php
echo $this->lang->line('homepage_welcome');
?>
</div>

Now, if you created another language, like italian, for your multi-language website, you have to also create a language file for your templates inside the application/language/italian directory which will be named the same – interface_lang.php. And in there you only have to change the values of the keys you’ve defined:

 

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

$lang['homepage_welcome'] = 'benvenuti a tutti';

This way, whenever you switch languages, the templates will also serve the strings in your selected languages. Questions? Use the comment section. Thank you Federico for your comment. Hope this helped you.

6 comments

  1. Sorry for second post…I think I have to explain better my question.
    The problem is:
    – admin set a default language in languages DB table using Admin function
    – user visiting for the first time the web site get all text in default language
    – in the web site there is an IT or EN link (so the URL slug will change according to this) that user can click to switch languages to desired text.
    Thanks again

    1. You could create a field named “language” in the users table, and in MY_Controller, instead of asking what default language is set, you should ask what language the user has set. Only after asking that, if the user is not logged in, you should serve the default language.

  2. HI Adrian,
    it’s a good idea for sure to add the language field into the user table, but sometimes a user doesn’t need to register into the web site, so he could just set his own preferred language.
    I thought to store the selection into the session variable to avoid registration user to keep preferred language.
    About using multiple databases into a project could be discussed in other tutorial.

    1. Well… If you want to set a preferred language for users that are not logged in, you should use cookies that remain after the browser is closed. A session variable is available only until the user closes the browser (that is what we call “a session”). For that, if you are as lazy as I am, CI also has a cookie helper (http://www.codeigniter.com/user_guide/helpers/cookie_helper.html).

      Regarding the “multiple databases”, I already have a tutorial that, even if it is a bit older, it’s still usable with CI3 (…I guess…): http://avenir.ro/codeigniter-connect-two-different-databases/

      Also, the MY_Model that I’ve created allows for multiple databases (…never tested it thoroughly, but it is there and it is explained in the user manual on the Github repo).

  3. First of all thanks for your wonderful articals. but I have a question how to setup multilanguage for administrator panel ? how to set routes etc. plz reply me if possible.

Leave a Reply

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

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