Make Fabrik multilingual with Fabrik itself

Feb 6, 2016
Make Fabrik multilingual with Fabrik itself

  • Multilingual data(top)

    The data in Fabrik lists can be made multilingual with (pre)filters. In each list we just must have at least one element that represents the language and that we could filter data with. When we want the Joomla multilingual site would make the work then at least one language element must represent language url code (like 'en', 'fr', 'fi', 'et', ...) and list prefilters should be set to "WHERE `your_language_element`= '{lang}' "

    Multilingual databasejoin element(top)

    Create special table for labels. It should be a child table at this one that the databasejoin element points to. So with a similar fk like your databasejoin element. It should also contain a language field (like described above). Fill it with data.
    Change your databasejoin element settings. Assuming all your label data is now in special table write in "..or concat label" box something like:
    Code (Text):
    (SELECT label_table.label from label_table WHERE label_table.fk_field = {thistable}.id AND label_table.language_field = '{lang}'),''
    In case your default language is not displayed in url you need after "AND" this code instead:
    IF('{lang}' = '', label_table.language_field = 'xx', label_table.language_field = '{lang}')
    replace xx with your default language code.​
    '

    Multilingual element labels(top)

    The labels could be displayed in different languages using Joomla language override function. It's done by language files yoursiteurl/language/overrides/xx-XX'.override.ini (instead xx-XX the needed language code like en-GB) where the syntax is like in all other language files -
    MY_LABEL_TEXT="My translated text"
    To manage these translations you can use Joomla builtin method (ready to use but lot of copypastes one by one) or build by yourself a special application with Fabrik (which is more userfriendly and semiautomatic).

    "Override" in Joomla language manager(top)


    Edit your element which has the label you wish to translate
    Copy its element label text and replace it with a language constant string. E.g. if your label text was 'This is my label text', replace that with 'FABRIK_LABEL_THIS_IS_MY_LABEL_TEXT'
    Save the element
    Go to Extensions->language
    Select overrides
    Press new
    In the "language constant" field enter 'FABRIK_LABEL_THIS_IS_MY_LABEL_TEXT' (without the quotes)
    Then in the enter the translation in "Text"
    Finally select the language and press save
    Create a new language override for each language you wish to translate.

    Create and use your own language override app with Fabrik(top)


    We can still take advantage of Fabrik even though Joomla's translation override strings are stored in a text file and not in a database table. Initally, we have to do some work directly in MySQL (i.e via phpmyadmin) and the rest in Joomla / Fabrik.
    Steps in MySQL(top)

    NOTE: Replace everywhere #_ with your real prefix.
    First create the table for the label translations. Let's say it's fabrik_labels
    Code (Text):
    CREATE TABLE IF NOT EXISTS `#__fabrik_labels` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `label` varchar(255) NOT NULL,
      `lang_code` varchar(10) NOT NULL,
      `override` varchar(255) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `label` (`label`,`lang_code`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
     
    Now you probably want to set up your database to automatically fill in the #__fabrik_labels table when a Fabrik meta object (e.g. an element) is updated or created. To do so create triggers in your database by running this SQL:

    Code (Text):

    CREATE TRIGGER `new_element_labels` AFTER INSERT ON `#__fabrik_elements`
    FOR EACH ROW INSERT IGNORE INTO `#__fabrik_labels`(`label`, `lang_code`)
    SELECT `#__fabrik_elements`.`label` ,  `#__languages`.`lang_code`
    FROM  `#__fabrik_elements` ,  `#__languages`
    WHERE `#__fabrik_elements`.`label` NOT LIKE '%{%'
    GROUP BY  `#__fabrik_elements`.`label` ,  `#__languages`.`lang_code`;

    CREATE TRIGGER `new_list_labels` AFTER INSERT ON `#__fabrik_lists`
    FOR EACH ROW INSERT IGNORE INTO `#__fabrik_labels`(`label`, `lang_code`)
    SELECT `#__fabrik_lists`.`label` ,  `#__languages`.`lang_code`
    FROM  `#__fabrik_lists` ,  `#__languages`
    WHERE `#__fabrik_lists`.`label` NOT LIKE '%{%'
    GROUP BY  `#__fabrik_lists`.`label` ,  `#__languages`.`lang_code`;

    CREATE TRIGGER `new_form_labels` AFTER INSERT ON `#__fabrik_forms`
    FOR EACH ROW INSERT IGNORE INTO `#__fabrik_labels`(`label`, `lang_code`)
    SELECT `#__fabrik_forms`.`label` ,  `#__languages`.`lang_code`
    FROM  `#__fabrik_forms` ,  `#__languages`
    WHERE `#__fabrik_forms`.`label` NOT LIKE '%{%'
    GROUP BY  `#__fabrik_forms`.`label` ,  `#__languages`.`lang_code`;

    CREATE TRIGGER `new_group_labels` AFTER INSERT ON `#__fabrik_groups`
    FOR EACH ROW INSERT IGNORE INTO `#__fabrik_labels`(`label`, `lang_code`)
    SELECT `#__fabrik_groups`.`label` ,  `#__languages`.`lang_code`
    FROM  `#__fabrik_groups` ,  `#__languages`
    WHERE `#__fabrik_groups`.`label` NOT LIKE '%{%'
    GROUP BY  `#__fabrik_groups`.`label` ,  `#__languages`.`lang_code`;
     
    These WHERE clauses are added to avoid submission of {placeholders} if any is used in labels; you can of course modify them or not use at all.
    Please ensure that all your labels are written as YOUR_LABEL_NAME or at least your_label_name. Messages in lowercase could be also translated, but in language.ini files they must be in uppercase and the following php code ensures that the label will be written in correct case.
    Only simple characters and _ are allowed (so never write i.e YÖÜR_FÕRM-LÄBÉL NAME_4). Instead numbers you can use letters, e.g replace 4 with IV.

    Steps in Joomla(top)


    1) create new Fabrik list+form on the #__fabrik_labels table
    2) in the list
    - add an inline plugin so that you can edit inline (from the list view) the element #__fabrik_labels___override
    - good idea would be to show filters at least for the language element! So you can make list to show only the needed rows.
    3) in the form
    - add a "php" plugin and set it to work on edit at the end of form submission (onAfterProcess)
    - add the following code to execute

    PHP:
    $lab = strtoupper('{#__fabrik_labels___label}');
    $ln = '{#__fabrik_labels___lang_code_raw}';
    $override = '{#__fabrik_labels___override}';
    $msg = $lab . '="' . $override . '"
     '
    ;
    $file = JPATH_SITE . '/language/overrides/' . $ln . '.override.ini';

    if (!file_exists($file))
    {
        fopen($file, 'x+');
    }

    $current = file($file);

    if($override != '' && !in_array($msg, $current))
    {
        foreach($current as $line)
        {
            $fmsg = explode('=', $line);
           
            if($fmsg[0] == $lab)
            {
                $newtext = str_replace($line, null, $current);
                file_put_contents($file, $newtext);
            }
        }
       
        file_put_contents($file, $msg, FILE_APPEND | LOCK_EX);
    }
     
    That means: the file in overrides folder has the name containing a language code (like en-GB). In case if it doesn't yet exist it should be created as a readable and writable one. If the field with override word is not empty and the file doesn't contain any line with this label and this override word, then the rest may happen:
    - if this label has an old translation (the label already exist) then we should delete this line first and put the rest back into file
    - anyway we put the new label and message pair at the very end of the file.​

    Multilingual tips and dropdown/radio/checkbox option labels(top)


    You can use also translation override function to translate such things like option labels in elements with multiple options like dropdown, radiobuttun or checkbox. Equally you can make tips multilingual. Both option labels and tips must then have needed format (OPTION_LABELS_AND_TIPS)
    You can principally use both Joomla language override form and the application built with Fabrik, but with one important difference: there is no automated way to write them into #__fabrik_labels table, you have to do it manually. If anyone have ideas how to involve the element params into this proposed automation, feel free to work it out!

    Alternate way - copying lists, forms and menu items(top)

    See - Multilingual forms
joit likes this.