Latest posts

EE2 language switcher extension

We’re in the process of building a multi-lingual online magazine site powered by ExpressionEngine and over last weekend I searched around for an add-on that I could use to implement the language switching part.

After a quick search on Devot-ee I found a couple of potential candidates but in the end decided to roll my own. While it may be quite specific to our own needs, I thought I’d stick it up on Github and write it up here.

Requirements

I’m definitely not in the same class as our developers but I can find my way around creating basic extensions and plugins for ExpressionEngine. My first job was to outline my requirements. A bulleted list on my notebook looked a little something like this:

  • Site owners should be able to set a default language.
  • The extension must limit the allowed languages to a list set by the site owners.
  • Users must be able to select a preferred language that will be honoured on future visits.
  • Template developers should have a template tag to use that outputs the default or user selected language so that the correct content can be conditionally displayed.

That’s pretty much it really. As I say, you can find the extension on Github and it should be self-explanitory. Here’s a quick walk-through anyway though:

Site owners should be able to set a default language

The first thing we do is create a global variable in index.php which stores the default language for the site.

1
2
 $global_vars = array();
 $global_vars['default_language'] = "de";

That’s one requirement down.

We activate the extension by inserting a query with the hook we’ll be using (in our case sessions_end and the name of the class method we’ll be writing that we’d like called. Again in our case we’ve called this ‘sessions_end’ but we could have called it anything we liked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 public function activate_extension()
 {
 $default_settings = serialize( $this->default_settings() );

 $this->EE->db->insert(
	'extensions',
	array(
		'class' => __CLASS__,
		'method' => 'sessions_end',
		'hook' => 'sessions_end',
		'settings' => $default_settings,
		'priority' => 10,
		'version' => $this->version,
		'enabled' => 'y'
	)
);
  }

The extension must limit the allowed languages to a list set by the site owners

We give the extension the ability have settings. We want a settings form with just one field giving the site owners the ability to enter the allowed languages.

1
2
3
4
5
6
7
8
 public function settings()
 {
 $settings = array();

 $settings['allowed_languages'] = '';

 return $settings;
 }
These allowed languages should be entered as a piped list of two character country codes, i.e. en de fr. That kind of thing.

We now create a private function within our extension class that allows us to check whether the inputs (either from the user or a set cookie) match one of the allowed languages.

1
2
3
4
5
6
7
8
9
 private function is_allowed_language($value)
 {
 $langs = explode("|", $this->settings['allowed_languages']);

 if(in_array($value, $langs))
 {
return TRUE;
 }
 }

That’s another requirement done.

So now we’re all set to write the actual method that will be called by the extension hook we’ve specified. This starts off with:

1
2
3
4
 public function sessions_end()
 {
 $user_language = ( $this->EE->config->_global_vars['default_language'] != "" ) ?
 $this->EE->config->_global_vars['default_language'] : "en";

Here we’re setting the value of a $user_language variable to equal that of the global variable we defined in index.php. It there isn’t one we’re going to default to English.

Users must be able to select a preferred language that will be honoured on future visits

Next we check to see if there’s a cookie on the user’s machine called ‘user_language’, and if there is, we also check whether it’s value is one of our allowed languages. This cookie is set later on in this method when a user selects a preferred language.

If the cookie does exist we set it’s value as the new value of our $user_language variable.

1
2
3
4
5
 if ( $this->EE->input->cookie('user_language') AND $this-
 >is_allowed_language($this->EE->input->cookie('user_language')) ) {

 $user_language = $this->EE->input->cookie('user_language');
 }

pWe now do another check to see whether the user has chosen to select a preferred language. When they do this a $_GET variable called ‘lang’ is added to the site’s URL with the chosen language as it’s value.

So we check to see if this $_GET variable exists, and again check to see if it’s value is in our allowed languages list. If it is we set it as the new value of our $user_language variable. At this point we also create a cookie called ‘user_language’ and set it’s value to using the same $user_language variable.

So now the user can select a preferred language by either clicking a link or using a form select that would result in a $_GET variable being added to the URL. Their selection is stored as a cookie meaning the can revisit the site later and their preferred language choice will be used by default next time. Another requirement done.

All that’s left to do is create a global variable that can be used within your templates to conditionally display the correct content.

1
 $this->EE->config->_global_vars['user_language'] = $user_language;

Template developers should have a template tag to use that outputs the default or user selected language

Add the template tag {user_language} to any of your templates and you should see the correct country code outputted. Add a $_GET variable called ‘lang’ with a value that’s been includes in your allowed languages setting and you should see the value of {user_language} change.

Close and restart your session on the site and you should also see your chosen language honoured (by way of the cookie) rather than the default language set in index.php.

You can change any of the variable names to suit your needs. We’re using Newism’s “nsm.multi_language.ee_addon”:https://github.com/newism/nsm.multi_language.ee_addon/ to actually store some of the translations. That add-on requires a global variable called ‘nsm_lang’. Rather than using that as our template tag we’ve simply added a further line to our extension.

1
 $this->EE->config->_global_vars['nsm_lang'] = $user_language;

And that’s it.

Erskine Design
Published in: