Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP web app internationalization

I am building a php web app that requires internationalization. I have decided to use get-text for system related strings and perhaps some database tables for user generated content.

For example, a user might be able to post a blog post. He should be able to post different versions of that post in different languages. I can implement this by storing all the posts in the posts table with an extra column denoting the language.

The difficult bit is trying to internationalize system strings stored in the database.

For example, I have a table that stores privileges. Each privilege should have a string that describes what this privilege does.

At the moment, it is stored in a table like this:

app_privileges

  • id
  • privilege
  • Some other columns
  • Description

I plan to use an application like PoEdit to generate gettext files. It is able to search through all the php files to grab the strings. But in the cases like this where the string is stored in the database, it can be a fair bit of work to extract the string for transation. What are some tricks and solutions to handling this?

Finally, lets say I have some data types and forms that users can create and define in the app. For example, defining a "product type" for a shopping cart. This means that the product will have its own unique set of attributes and descriptions. These attributes will require translating along with the description.

The same case with forms. The user can create a form which might be stored in a set of tables. These forms then need to be translated.

What are some database models I can use to store translations for forms and product types?

Cheers :)

like image 939
F21 Avatar asked Nov 13 '22 19:11

F21


2 Answers

For strings that are more "system"-oriented, like :

  • buttons
  • feature names
  • privileges
  • etc

Gettext is good.

Privileges, for instance, are more "system"-oriented (users don't create privileges, rather admins grant them to users but don't create new types of privileges). So, your privileges table can have a column "privilege_name" which is never displayed and contains only gettext keys, for instance : "Privilege : User can edit posts in the specified forum".

Strings in your application should also not be the text that the user will see, but something more detailed like "Menu: Edit Preferences".

Those strings go through gettext (even for english or the site's "mother tongue") and get translated to the proper user-visible strings.

You should also use numbered sprintf-style arguments, ie not "Price of %s is %s" but "Price of %(1)s is %(2)s".

This has several advantages :

  • gettext provides very little context, and merges identical strings. A translator who sees "Button: Edit this post" will have a lot more help than a translator who sees "Edit". In some languages, a simple text "Edit" may translate into different words, or grammatical forms of the same verb, depending on what is "Edited".
  • you can change the English text at will without breaking gettext keys for other languages
  • numbered arguments handle languages with different ordering of subject/verb/etc

If you have text in images (like some buttons) you need to take care of this too. Gettext can translate filenames, too (images/buttons/en/submit.png => images/buttons/fr/valider.png although a simple regexp would be nice too) and don't forget the for blind people using screen readers.

For multilingual user-generated content (stored in tables), the usual relational approach is better.

Table posts( post_id ... ) Table posts_translated( post_id foreign key, language_id foreign key, title, text, etc )

This will allow you to use SQL for everything like showing the list of languages available for a post, allowing default languages, showing untranslated posts, fulltext search, etc.

like image 153
bobflux Avatar answered Nov 30 '22 23:11

bobflux


Tricky question.

In my experience, the translation process is really hard to manage - and you don't want to hold up the release of your app because the Uzbek translation for the "Create posts" privilege hasn't been approved yet.

I've never worked with gettext, but the .Net and Java equivalents require you to put a file on the web server with translations; this is often treated as a deployment, and at the very least must go through the version control routines - this can also be a bit of a pain...

If you can get away with it, I'd agree on a convention of TableName_ColumnName for your gettext keys, and store all the user-visible system messages in gettext files.

I would argue that localization of system messages is a front-end concern, and shouldn't be in the database. Where your business entities - posts, shopping items etc. - can be localized, that's a domain issue and should be reflected in your database schema.

like image 37
Neville Kuyt Avatar answered Nov 30 '22 23:11

Neville Kuyt