
Make product fields multi-language in PrestaShop and ThirtyBees
In this tutorial we will learn how to make product fields translatable in PrestaShop 1.6, and see how to apply the method to the “price per…” field.
Introduction
You might have come across the need to translate the price per unit field in your PrestaShop or Thirtybees, but crashed against the software’s limitation, as that’s a single language property. Any product field can be made multi-language with a simple modification, so let’s see how to do it using the Unity one as example in this tutorial!
Step 1 – Adding the new database column
In order to make the field translatable, we have to add it to the product_lang table in the database. Not only, but we also have to erase the same column in both the product and product_shop tables, to avoid conflicts when retrieving values from the database. Let’s add it first!
Using phpMyAdmin or Adminer, locate the *prefix*product_lang table in your database, and add a new column as VARCHAR, 24 characters long. Once done, it will look like this:
Next, let’s get rid of the leftovers: open the *prefix*product table and drop the unity column first, and then on the product_shop table.
We are done! We just broke the Product class though, and have to compensate by letting it know where to grab the new values from.
Step 2 – Editing the product class
We have a new column in the database, but at this point the Product class would still just ignore it. To have it lookup, and save into the correct table, we must tell it that the property we are wanting to translate is a multilanguage field. To do so, we must change its definition.
Open up Product.php, located in the classes/ folder.
Scroll down until you find the following line, part of the $definition property:
'unity' => ['type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isString'],
To make any field translatable, we can simply add ‘lang’ => true as follows
'unity' => ['type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isString', 'lang' => true],
Please notice that, as always, using an override is strongly recommended, instead of editing core files.
Step 3 – Editing the back office
The controller
This is the most complicated part, as we will have to edit both the admin controller for products, and the correct template. For our example, the template is prices.tpl, but it will be different if the field you want to translate is in another tab.
Let’s start with the controller. The prices template does not offer us any option for translating fields, and therefore misses the indispensable $languages variable.
Open up AdminProductsController, located in controllers/admin
We are interested in the method called initFormPrices, so once you find it you can simply clone that to an override, or continue editing the core.
Right after $data is assigned, at the very beginning of the function, but before $product = $obj, add the following
if (!$this->default_form_language) { $this->getLanguages(); } $data->assign(array( 'languages'=> $this->_languages, 'id_lang' => $this->context->language->id, 'default_form_language' => $this->default_form_language, ));
Explanation: Nothing too complex here, we are first checking if languages are loaded, and if not, assigning them to the controller. Then, we simply assign that class property to the template, along with a few other required ones. Please notice we do not use a common smarty assign, but the $data variable instead.
The template
Time to make our changes visible in the back office! For the unity field, let’s open up *admin folder*/themes/default/template/controllers/products/prices.tpl
Locate the input with id unity, which will look more or less like the following:
<input id="unity" name="unity" type="text" value="{$product->unity|htmlentitiesUTF8}" maxlength="255" onkeyup="if (isArrowKey(event)) return ;unitySecond();" onchange="unitySecond();"/>
Instead of this input, we will use a handy template PrestaShop makes available to us. Replace the above with the following code:
{include file="controllers/products/input_text_lang.tpl" languages=$languages input_class="{$class_input_ajax}{if !$product->id || Configuration::get('PS_FORCE_FRIENDLY_PRODUCT')}copy2friendlyUrl{/if} updateCurrentText" input_value=$product->unity input_name="unity"}
Save and refresh, and you will see the new field, translatable, appearing in the prices table of the back office. Time to test it, and see if it’s saving properly.
We can take an extra step and translate the preview below as well:
<span id="unity_second">{$product->unity}</span>
to
<span id="unity_second">{$product->unity.{$id_lang}}</span>
At this point we can go ahead and test the Front Office. If everything has been done correctly, as soon as you change language, the class should automatically pick the correct translation for the field. Neat!