Render DBjoin Label through JText ?

lcollong

FabriKant d'applications web
Hi,

For a CRM like app we decided to use DBjoin rather than regular dropdown/checkbox/radio.
We have a table "dictionary" containing all the values and labels for each dropdown.
So, for example, the choice for the element "sex" of the contacts table are made with a dbjoin element with a restriction on the Where clause (WHERE element="sex" AND published="1").
The corresponding rows in dictionary contains something like m-->Male and f-->Female
In the contacts table registred rows will contain either "m" or "f" and the rendering list/form/details will show the right labels.
Great

We want to support several languages. One way is to add a "lang" column in the dictionary and an additional conditions in the where clause (AND lang={lang}). I did not test recently but I think it works.

If you miss a translation the drop down will look broken. Also you have to maintain translations both in some .ini files and in this dictionary table.

Thus, the idea to use the JText to render the label. It works on the dictionary table itself as the "text" column is a regular field on which Fabrik is applying JText. But on the final dropdown, it shows the constant string rather than its translation.

It's probably "normal" as the label could be "please select", a DB column or some CONCAT result and may contains other things than text (HTML....)

I succeed in using the Jlayout overriding feature to force the text part to pass through Jtext. So, for example, in this file : plugins/fabrik_element/databasejoin/layouts/fabrik-element-databasejoin-form-front-end-select.php, I've added this code before the echo :
PHP:
//if ($d->id == "contacts___ref_sexe") {
    foreach ($d->options as $k => $o) {
        $d->options[$k]->text = JText::_($o->text);
    }
//}

Without the "if", it tries to translate all the form's DBjoin elements (most of them are regular data ones not to be translated). The "If" solution is an awfull way...

More, I'm not sure this translation should take place in the very last part of the "View" MVC model... And I'll have to override all parts of the Fabrik engine (filter, list, detail view...)

Would it be doable to add an option to the model to force the label part of the DBjoin to pass through JText before being rendered in whatever view ? Thus the displayed text would be translated through the standard J! functions which give the advantage to always show "something" (the constant itself or merely the native'app language label). Without changing the behavior of the element for non translatable data....

Laurent
 
What I have done:
in the dbjoin list I have multiple columns, one for each language
in the dbjoin element I use Concat label
IF('{shortlang}' = 'fr', {thistable}.treff_name_f, {thistable}.treff_name)

This has the advantage that you don't need to struggle with language strings and that the list can be modified/extended (e.g. frontend add) also by non-admins.
 
I don't see any compelling reason not to run the labels through JText. It's not much of an overhead. Just looking up an index in an array. And if a translation isn't found, the text is returned unchanged.

Try this. In plugins/fabrik_element/databasejoin/databasejoin.php, around line 733, in getOptions(), add the translation ...

Code:
        foreach ($aDdObjs as &$o)
        {
            // For values like '1"'
            // $$$ hugh - added second two params so we set double_encode false
            if ($this->getDisplayType() != 'radio' && $this->getDisplayType() != 'checkbox')
            {
                $o->text = htmlspecialchars($o->text, ENT_NOQUOTES, 'UTF-8', false);
            }

            // ADD THIS LINE
            $o->text = FText::_($o->text);
        }

Let me know. Should work. If so I'll add the change to github.

-- hugh
 
@troester :
Interesting alternative to go.
However, you have to add a column in your dictionary table and edit each of your DBjoin elements if you want to add a new language . Also, I have to admit that most of our app may have 2 or 3 languages and very occasionally the need to add a new one. But...
Also the concat become heavier as long as you add languages.
And finally, it does not separate the "core" from the translations as of the J! way to go

@Hugh:
On my test drive, it works perfectly for the editable form, the dropdown shows the translation.
But for the list view, the detail view and the filter, it shows the constant string instead of the translated terms
 
OK, around line 2120, in renderListData ...

Code:
        // ADD THIS foreach
        foreach ($data as $k => $label)
        {
                $data[$k] = FText::_($label);
        }

        // $$$ rob add links and icons done in parent::renderListData();
        return parent::renderListData($data, $thisRow, $opts);

... and around 1379 in render() ...

Code:
            // ADD THIS foreach
            foreach ($defaultLabels as $k => $label)
            {
                   $defaultLabels[$k] = FText::_($label);
            }

            $this->addReadOnlyLinks($defaultLabels, $targetIds);

-- hugh
 
I had to deal with $data not being an array....

PHP:
        // ADD THIS foreach (Hugh for apchea)
        if (is_array($data))
        {
            foreach ($data as $k => $label)
            {
                $data[$k] = FText::_($label);
            }       
        }
        else
        {
            $data = FText::_($data);           
        }
       
        // $$$ rob add links and icons done in parent::renderListData();
        return parent::renderListData($data, $thisRow, $opts);

Now everything seems to work as expected.... except filters ! :) (dropdown basic one in my case).
 
Ooops, I forgot it's actually going to be either a single string value, or a JSON array at that point.

So ...

Code:
        $data = FabrikWorker::JSONtoData($data, true);

        foreach ($data as $k => $label)
        {
                $data[$k] = FText::_($label);
        }

        $data = json_encode($data);

The JSONtoData() call will handle either single value or JSON.

OK, well, I'll get this stuff committed, then look at filters.

-- hugh
 
(probably not today, we're about to finally do the site migration, which will no doubt eat up the rest of the day)
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top