How to handle translations, site w multiple languages

Many thanks @George - thatā€™s a great solution. I think this will be a very useful feature generally and works perfectly for language switching.

I was wondering about how to set defaults in case no cookies are set, at least for critical text - now itā€™s just a matter of setting a defaut in the normal way with the data formatter. For inner text, I was pleased to see dmx-html also works too.

4 Likes

Wappler Translation Tutorial

Took me hours to gather all informations of the 3 steps you mentionned but it was fun to learn many other things along the way. And I wanted to contribute to thank this amazing community.

So here is a quick tutorial (hopefully) from A to Z.
Iā€™m not really comfortable with Wappler terminology yet but the step by step approach should allow anyone to understand the workflow.

Step by step video :

Ressource :
SQL dump : https://www.dropbox.com/s/kb3i7oiwa1wb86y/translations.sql?dl=0

Any feedback/improvements are welcomed ! :slight_smile:

9 Likes

Thank you Jeoff, very well presented and I love the accent.

Hi,
Cannot make it work. Translations are properly loaded from the database, but data doesnā€™t to be stored in the array (after toKeyedObject) to be displayed after. Is there a way to control this array (if exists and what is in) with chrome debugger ?

1 Like

Usually, this is because the formatter script is not included in the code :

If you can send a screenshot or the actual page link, it will be easier to help you though ! :wink:

I have already added it with no success. But if i add it, do i need to add this script also as @george wrote previously ? Should we have both ?
image

No itā€™s not needed anymore as itā€™s shipped with the formatter script now.

Ok, thankā€™s for you help, i think i will have to start from scratch again.
Iā€™m still interested to know if there is a solution to control whatā€™s going on in the chrome debugger

@jeoff75, how do I convert an array into keyed object? I tried looking for this formatter, but no luck. Thanks.

Look at the source here :
https://login-boilerplate.usa-sandbox.space/app_create_user.php

Iā€™ll try to upload the project to git this week-end so that you can have a look from within wappler.

2 Likes

Thanks lot mate. I did watch the video you put together and figured it out, it was a lifesaver. The toKeyedObject is not available through the UI formatter, entered it manually, thanks again :+1:t4:

It is available in the formatter - not originally, but I think it was added quite a few versions ago:

image

Thanks @TomD

Not finding at my end on an array variable. I wonder what the difference, is your screenshot from a server action?

Also, would you know if Keyed Object just another term for Keyed Array aka Associate Arrays in javascript?

My screenshot was not from a server action. I think the difference is that I used a variable rather than an array component. This was the variable and value:
<dmx-value id="lang" dmx-bind:value="sc_lang.data.qry_lang.toKeyedObject('textkey', 'text')"></dmx-value>

image
The query returns an array of keys and text (translations). Eg this displays the translation for ā€˜termsā€™ (based on a cookie storing the selected language):
{{lang.value.terms}}

although I actually include a default: {{lang.value.terms.default("Terms")}} (in case the cookie is not set).

1 Like

Just implemented all of this, and it worked like a dream!

Many thanks to @jeoff75 for the great video and cool accent, @George for putting the toKeyedObject function into Wappler, and @TomD for the screen shot of how to access it!

@George, it would be great when something new is put in Wappler if posts like this one could be updated to note the changeā€¦ it looks like it could have saved @djeorges quite some hassle!

It took me ages to find the toKeyedObject conversion in the Wappler GUIā€¦ so here is what to do:

  1. When assigning to the variable ā€œlangā€ (as Georgeā€™s example):
  2. Click on dynamic value (lightning icon),
  3. Select Server Connect -> Data -> next icon below.
  4. Click on the magic wand next to the field text at the bottom right of the screen.
  5. Right click on the server connect ā€œburgerā€ icon
  6. Collections -> To Keyed Object
  7. Key: select your database field which is the index to your app text
  8. Value: select your database field which is the actual app text

My Implementation

A few points about how I implemented it that I hope will help those following this path:

  • My index is a number. Felt like it may be faster on indexing and saved me inventing yet another naming scheme. Numbers are 4 digit, in the form xyyz, where x is the area of the app (1=contacts, 2=orders, 3=finances, 4=products), yy is the specific field/view being described (01=first name, 02=last name), and z is the aspect to describe (0=item title/content, 1=description, 2=placeholder, 9=help text).
    So for example, help text for First Name field is 1019 and placeholder for Last Name field is 1022.

  • I use the 5 digit language codes, so en-GB, en-US, es-ES etc. It is important an american user sees the word ā€œcolorā€ rather than ā€œcolourā€ to feel really at home with the app.

  • Sometimes I wonā€™t have all the translations for every piece of text in the app, especially when translating en-US for example, so I have the idea of a fall-back languageā€¦ most commonly en-GB, but could be es-ES.

  • To implement the fall-back language, I access the complete text for the application (apptext) via a mySQL procedure get_apptext(language). When called, that finds all the apptext in that language and then then substitutes all that is missing from the fall back language.

  • I will have users who have ā€œis_language_editorā€ and ā€œedit_languageā€ fields. When both are enabled, there will be tiny button next to each piece of text which will enable a modal where they can go in and edit their language version for that piece of text.

  • The app will be developed in en-GB which I call the base language. I plan for each field in the database to have a modified_date field, and some system where the language editors can see when the en-GB modified date field for an apptext is later than that for their language, so they are highlighted to the need to update their content. Details of that to be worked out!

I hope all that helps!

Best wishes,
Antony.

1 Like

Well we try but sometimes we miss some topics as there are many.

You can actually post such tips directly as docs! Just make a post under the #docs category and it will be automatically included in our official docs.

You can also add it to the index by linking to it from an ā€œabout xxx category@ from the docs category that it fits.

We plan to restructure the docs categories and organization soon and any help will be greatly appreciated.

2 Likes

Hey @George, yes, I understand the challenge of trying to manage soooo many wonderful posts from that point of view! I guess it is upon all of us to try to update a post we know about when a new feature is added.

Iā€™m not so confident that my ramblings consitute a Wappler doc, but you are welcome to move it over there if you think it meets the grade!

Thanks for all your wonderful input,
Antony.

I have a new project that requires localization. I am fiddling with the i18next library.

So far so good. As I am just testing I switch languages clicking the form button.

My implementation relies on json files instead of querying the database I have files for each page and language. This means that it is blazing fast as you can see :slight_smile:

I still need to take a deeper look to check the implications as I might be losing some App Connect goodness like bindings and formatters that could come in handy.

You could potentially do something similar with the App connect json data source component and skip the database call. Although you would be missing on the translation goodies that come with this library like plurals, fallbacks and things of the sort.

1 Like