Multilingual ExpressionEngine® (ver 2), Part 3

In the third and final episode of this series we are going to take a quick look at how to customize ExpressionEngine’s control panel to make things easier for your client in managing a multilingual site’s content.

As stated in the previous article, there are pre-built multilingual add-on framework solutions for ExpressionEngine such as Publisher or Transcribe, but the focus on these articles has been the “do-it-yourself” approach. So we’ll round out the series by focusing on one of the more overlooked yet very important aspects of an EE build. Preparing the control panel (CP) for your client.

This is something we should be doing for normal ExpressionEngine sites as well, however with a multilingual build, we need to take things a little further.

Who will be doing the translating?

As with any web development project, the more you know about how it will fit into your client’s business and workflow is very important. In the case of multilingual sites even more so. Content is king, and if the way of inputting multilingual content in the CMS is cumbersome, chances are the primary language content will get updated more often while the other language content gets stale.

We need to know if the person(s) updating the content themselves are multilingual, or if they will be giving access to translators to do the job. This will help us determine if we need to create separate member groups for each language to customize the CP to make it easier for them.

Control Panel Language and Modules

ExpressionEngine comes with English as the default language for the control panel, however language packs are available from the EllisLab’s GitHub repository which you can download and install. The process is fairly simple, just unzip the language pack and place the folder with the language name within the system/expressionengine/languages folder.

There’s just one catch, you will also need to download language packs for any of the modules you will be giving them access to as well. These need to be downloaded and installed in a similar fashion to the main CP language files, however they should go in the system/expressionengine/third_party/module-name-here/language directory.

The problem is not that many add-ons will include language packs or have them readily available, so you may need to either get someone to do the translations for you, or do them yourself. Keep this in mind when planning the project timeframe and budget.

The files themselves are basically just PHP files with an array including all the necessary static texts and phrases used within the module.

Now when adding a new site administrator member, you will be able to select the language within the members localisation settings.

Customising the Control Panel Menu with Zoo Flexible Admin

I have found Zoo Flexible Admin to be a great add-on for customising the control panel menu for multilingual builds. The module screen is very intuitive and creating a customized menu is just a matter of creating a folder hierarchy in the right pane, and then dragging the different channel publish and edit entry links to their appropriate places.

In the first article of the series we discussed how content can be translated into either a one-to-one or one-to-none method. How we have setup our channels to accommodate for this will now affect how we should customize the control panel menu. Like any ExpressionEngine project we will have different channels for each type of content. The example below is from a holiday home rental service with homes located in different regions of Spain. The top-level links coordinate with the channels of the build, except for the “System” one at the end (more on that later). However they mix both types of translated content.

One-to-One Channel Content

For these type of translations, considering that the content itself resides within the same channel entry, the logical approach is to supply them with menu links that go straight to that channel. I tend to include two links, one to the content edit screen and one to the create content form.

One-to-None Channel Content

For these types of translations we are using separate channels for each language and as such, we need to take a different approach. We need to go one more level deep before including the menu links for the content edit screen and group them together in a submenu item for each language.

Static Content and Other Modules

In the second article of this series we discussed how to manage micro-copy in multiple languages using third-party add-ons like Low Variables, Biber, and Republic Variables. Here I tend to group these together under one “System” drop down in the menu, along with any other non-language dependant data like the file manager. You can also include horizontal lines in Zoo Flexible Admin which will allow you to visually group and separate items as well.

So now that we have our customized control panel menu, we just need to assign it to the correct member group. If we need to have the control panel menu in another language for a specific group of translators, we will need to repeat the process and assign it to that group. Like I said earlier, with multilingual builds you always need to got two or three steps further, so be sure it’s in your budget.

Customising Entry Forms

So now that we have the menu part done it’s time to start looking at how we are going to organize the channel entry forms to make things easier to understand on the input end.

For one-to-none translations we don’t have to do much here since each entry is going into it’s own language channel. You can enhance form a bit by including some instructions in the field descriptions, but in this case it’s pretty much straight forward.

On the other hand our one-to-one translations will includes fields for each language, so in order to keep things tidy and easier to understand for the client, we’ll need to visually separate these fields. I find the easiest way of doing this in ExpressionEngine is by taking advantage of custom tabs.

As you can see from the above image, we are keeping the non-multilingual content within the “Publish” tab, that is anything that is not language dependant. For the language dependant fields, we are using the tabs to group them together by language. This makes it easier for the content administrator to jump straight to what they want to edit without having to scroll through a huge channel entry form, and it also makes things less error prone. Also note that we are still labelling the fields with their corresponding language. This makes it easier for us when we are customising the fields and is a helpful reminder for the content editor.

Global Variables

If we are using any modules like Low Variables or Republic Variables to handle multilingual static texts and micro-copy, and you probably are, we can either create groups within them for each language, or we can create more general content type groups and then include the different language fields within the same group. Whichever way you choose will depend on the amount of fields each will contain or what makes most sense based on the content.


I hope you have enjoyed this mini-series on multilingual ExpressionEngine builds. (Look back to artilces 1 & 2.)We’ve covered quite a bit and I hope it’s been useful to anyone out there taking their first steps into building multilingual builds or even experienced developers looking for a different angle. Best of luck and, ¡Hasta Luego!