Categories in different languages (PHP) - php

Trying to work this out, but I don't know what's the best practice for this kind of things.
I'm working on a website using 3 languages: English, French & Dutch. There are categories on the website and the category names are different for the 3 languages.
For example:
Stars -> English
Sterren -> Dutch
Stars -> French
So I was thinking about adding them to the database. It's also easier for me to add more categories later if needed.
Now I'm facing the problem how to do this. My solution is:
**Cat_lang (category languages)**
cat_lang_id
language
**Categories**
categories_id
cat_lang_id
cat_title
Using cat_lang_id I can link both tables to get the language I need.
Is this the best solution for this problem?
Thanks in advance.

So that you can expand your website more easily in the future, I dont recommend having a cat_lang table. Stick with a languages table that contains language_id and language_name, and have your categories table point to it. Doing it that way allows you to have other entity types in your database (e.g. articles) that also contain multiple languages.

This is a flexible and reasonable solution. You see the same type of design in large scale ERP systems that have to handle dozens of languages and the possibility of more being added at any time.

If I were doing a website in multiple languages, I would use Zend_Translate to do the translations. Basically, you create a Zend_Translate object which reads in data files. Then you make calls on that object to translate() giving it the english version and it will give the translation in the correct language. Zend_Translate will scan your source and find all references to requested translations which will make files that can be translated by hand.
You are going to have much more than just the category names to translate, so I would recommend an approach like this where you just read in the translate file.

If you don't plan for a massive scale website and that you don't plan to increase to 100 languages, you can do a simpler and 'less nice' solution that is to have only 1 table of categories, where you hard code the language code in the category_name, for instance:
**Categories**
categories_id
cat_title_fr
cat_title_en
cat_title_de
Then in your code you set a $language_code variable at the beginning of each page using an include, you can even analyze the domain name in the $_SERVER variables to asign the correct language an by default choose the one you like (if you leave the variable empty your queries will return no text).
and you generate your queries like this:
mysql_query("SELECT cat_title_".$lang." FROM categories;");
Yeah it is dirty because you hard code the language in your DB structure, but if you have the exact same categories in each language with just a translation of the name, it is simple to implement.
Besides to add a language you just need to add a field in your table with the new translation, for instance spanish would be
cat_title_es

Related

CakePHP multi languages = multi databases?

We're busy with a CakePHP project which needs to support multi languages. But there is one problem.... There are pages which are NOT supported for other languages. So there are Spanish pages which need to be hidden for the Italian version of the website. What is the better solution for this in CakePHP?
We can switch databases as soon as you switch languages, but the problem is that we will miss important data as users and such if we'll do that. And it may be overload to search a database with Spanish, Italian, German, English, Netherlands and Swedish posts, only for the Spanish posts. Or maybe it's not a problem if we index the language column... but I don't know.
So does anyone knows the better solution?
Definitely NOT multiple databases IMO. Instead, try to just keep your record separate from it's contents.
Example:
articles table contains non-language-specific data like article id, created date, modified date...etc
article_contents contains language-specific data like title, subtitle, content, authors...etc as well as an article_id field and a language field.
Then, if you're on the Italian site, you can pull with an INNER JOIN to the contents where it matches the language you want.
Or there are many ways depending on your setup on how you should pull data, but hopefully the idea for separation of generic data vs language-specific data helps.
instead of
echo 'Localization';
do
echo __('Localization');
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html

How to efficiently translate website content with php, keeping it SEO friendly?

This is the scenario:
I have a website that I'll translate and eventually apply a good SEO on it.
Which method is best for translate the content (menu links, about 10 articles, alt tags, title tags, meta tags, html lang, etc) while being easely indexed by Google, Bing, Yandex and other search engines?
My first idea is to use a translate php function that consists of arrays made by myself (I have a prototyope of it already) that takes the content and displays it in the user's language.
Is this the right path? the problem here is that I wanted to be sure to have a dynamic system that allows me to add a new language in the future.
Maybe MySql is the right choice?
The website doesn't use a cms, I made it by myself with php though I have no problem to rely on MySql if I need to.
Thank you in advance :)
You've basically got 3 choices and there are pros and cons to each:
1: as Dainis Abols suggests, chuck it in the database - depending on how your server is set up this could be the slowest, most system heavy route (it's all relative though, it's unlikely to make any difference unless you're getting millions of view an hour).
2: use PHP library files; I tend to use library files for small, single items like field labels (forename, surname etc) and store larger things like CMS-managed HTML in the database... this reduces the database calls but adds a small overhead for each dictionary you load into a script <?php $this->page->dictionary->product = Dictionary::load("product"); ?> sort of thing.
3: finally, I personally think it's worth taking a look at PHP's implementation of gettext though you'll need something like poedit to maintain the PO (compressed translation files). This gives you the ability to very rapidly maintain translations as you just enter the text in your PHP document by wrapping it in a simple underscore function:
e.g. <?= _("Hello World"); ?>
You then maintain the translations in compressed PO files - it's very efficient (potentially faster than doing it with native PHP files) however it does have some drawbacks when it comes to the nuances of natural language.
As an example, if you have a field label "title" <?= _("Title"); ?> then all instances of _("Title") will be translated in the same way.
This means you can't use "Title" as both a form label for a person's title and as the title of a book; for instance, in German, you may want to use Anrede for one "Title" and Titel for the other.
Although, to really use gettext you'd probably need to be running your own server - it can require an Apache reboot when you change the PO files :\
As for Search Engines they read the output from your code so it doesn't really make a lot of difference which method you use to perform the translations but ideally you may want to keep the URLs RESTful so whether you're including PHP dictionaries, calling the database or using gettext (or changing your mind from one to another later), you'll be able to map the language to the URL with something like http://www.mysite.com/en_gb/widgets so you can change how the program works without changing the URLs.
Store all texts inside a db and apply another field for language:
+----+---------+---------+
| id | text_en | text_de |
+----+---------+---------+
| 1 | English | Deutch |
+----+---------+---------+
Now, when user switches languages, just use the field for that language:
$lang = 'en';
$query = "SELECT text_".$lang." FROM texts WHERE id = 1";
Something like that. So, all your client side texts will be stored inside the db at all times. So your output will be like:
<div id="header"><?=get_db_text_for_id(1)?></div>
Of course, you need precautions and some more field, but thats the general idea.

Best way to translate database driven content

I've been struggling with this for a while now. One my CMS' is ready to be extended with a translation module. I've been thinking of different methods but haven't figured out what is the best way so far.
Basically I have a CMS which uses a template system to parse all data from a database to the screen. I've come so far to "split up" my templates in different folders to be able to translate things that are "static" like images with text, footer links, etc.
However, there are many modules (pages, news, products) that have multiple fields that require a database driven method to be translated. I started off with a "languages" table which describes languages (id, iso_code, name). That's as far as I've come.. since there were a couple of projects that had to be done I haven't spend any more time to this subject thus far.
My first thought ("the quick fix") was to add multiple fields inside the tables (such as "title_nl", "title_en"), but this actually makes the database more crowded than is needed in my opinion.
My second thought was to create a table, "news_translations" for example. Which contained the language iso code, a news_id, the fields that require translation. Obviously a news_id connects the translation to it's original and the language iso code is used to get the right language from the database. Then in my front-end code I would first check if the default language is selected (=> select from the "news" table) or a translation (=> check inside translations table). If the 2nd case does not return any results a message is display "Sorry, no translation available" and the default is shown (or an error message, what fits the client best..).
But then there's a 3rd option.. my websites all use search engine friendly links (www.domain.com/pagename/ or www.domain.com/news/1-news-item-here.html). It would be far better if I had the ability to also "override" the SEF URL in my translations table. But I guess in this case I would always need 1 extra query to the translations table (since we first want to check for a translated page)... guess it's not such a big deal, but it's worth considering I guess.
In the end I guess by describing my options number 3 is what I need. But I'd like to have some other opinions on the subject as well! This is what I am trying to achieve:
Create a CMS system with multi language support
No language files (obviously this is why I use templates)
Being able to translate an original page/newsitem/product
Optionally: to change the SEF URL according to the language
I think option 3 has all this.. so the steps to create this solution is:
Create a _translation table for each item (or perhaps even in the
original by adding 2 new fields 'translation_to' (containing the
PrimaryKey) and 'translation_is' (containing ISO code) - however..
in that case all fields would need to be edited (which is not always
necessary.. plus by creating a 2nd table I keep the originals
divided with their translations, right?)
If the default language is NOT chosen first query the translations table to find a translation, if one is found display the
translation. Otherwise notify/error the user and/or display the
original text (based on the SEF URL... if the SEF is not found
within the translations or original table, then obviously display an
error only).
Any suggestions? :-)
Thanks for thinking along!
I would like to see what your table structure looks like. Probably the best thing you can do is generate two seperate new tables named something like "CONTENT_MULTI_LANG" & "SITE_LOCALES".
Then in the code that prints out your content do an initial check for a language flag. I'd create two separate classes for loading static content, something like "Content_LoadStandard" and "Content_LoadMultiLang". So then your conditional will look like this.
if ($this->site_locale == 'standard'){
$contentLoader = new Content_LoadStandard();
} else {
$contentLoader = new Content_LoadMultiLang($this->site_locale);
}
$content->blah($cheese);
Your "CONTENT_MULTI_LANG" table should be a narrowed down version of your standard CMS object table, only containing the relevant content field(s) that need to be in alternative languages.
// PSEUDO SQL
CREATE TABLE `LOCALE` (
`id` int(11),
`locale` varchar(16), // name of locale (language)
... // any other fields
)
CREATE TABLE `CONTENT_MULTI_LANG` (
`id` int(11),
`pcid` int(11), // parent content id
`lid` medint(), // locale id
`content` {$type}, // whatever type you use (varchar, text, bin, etc)
... // any other fields
)
In your Content_LoadMultiLang class, create methods to query alternate content using a join.
TIP: Might be a good idea to establish relationships in your table to do cascading deletes on content rows, that way if you delete content in standard your multi lingual version(s) will also be deleted.
From what I've seen from Drupal, option three is how they handle it, with a couple of tweaks. They keep it all in one table and a field called language. Then there is a separate table that maps which items are connected.
This way is primary language agnostic, meaning the content can be created in any language without requiring a translation in any other.

translating a website in php or mysql?

i need to translate my site in multiple languages. i was thinking to use a database called language and put the translation there.
database : translation
tables: language
column: id, english, french, german, italian, spanish
or i was thinking about a php solution like:
english.php
french.php
german.php
italian.php
spanish.php
so you simply include the file you need.
now, i can see pros and cons for both, what i want to know is what is consider the standard in the industry to do something like this?
You can use gettext, this function is proposed for this feature, not a "standard" but fast enough.
The second options in the use of a PHP file with a big array (really big, for each string), this is the most common solution.
To the database content (the big problem here, don't forget), if all your content must have the translation, one column for each language, otherwise use a flag of language for each line on database.
There is no industry standard. I have seen (and implemented) solutions using flat files, XML, PHP code, a database, and gettext files to store the localized strings. It's a matter of what is more suitable for you.
My go-to method for PHP is simply files containing arrays of strings, for example
en.php
return array (
'How are you?' => 'How are you?',
'Goodbye' => 'Goodbye',
);
de.php
return array (
'How are you?' => 'Wie gehts?',
'Goodbye' => 'Auf wiedersehen',
);
This can be integrated into an application with reasonable granularity (there can be many such files, e.g. one for each component) and control (you can easily fall back to any other language if you don't find a string) and it is also very convenient to modify without need for special tools.
My favorite PHP framework (Yii) and a giant open source project I have worked on (Moodle) also use this approach.
Noone of the two solutions seems great to me. You should think in the long run when you think a solution.
What if you choose to translate your website in other languages different from those you thought as russian or chinese? In the first case you have to add more and more columns, in the second you've to create more and more file. Another cons is what if you translate a page in italian and spanish but not yet in french?
I think that a good thing is to have a database based solution and a main language. Now you can do something like this:
Create a table 'page' (id, title, ...) where you'll store the page in the main language and where you'll have the info of the translated page too
Create a table 'translation' (idsource, idtranslation, language)
Everytime check the available translations and give those to the users
In database localization you have four main strategies. Each has particular advantages and disadvantages. For the long term I would definitely recommend cloning. You can see the four methods at the link below:
http://www.sisulizer.com/localization/software/server-desktop-database.shtml
There are two main ideas you want to be sure to be implementing. The first, be sure you are integrating some form of translation memory. Your language vendor should be instructing you on how to do this and probably doing it for you.
The second, for each additional language you target, your data will get at least 2x more complex. Keep this in mind as you move forward. Not only your data, but your file sets, management, etc.
Hope that helps. Let me know if you have further questions.
Russell

PHP Localization and dynamic data

So I need to make a site available in different languages. Using PHP 5.x and MySQL 5.x. I believe I will be using gettext which seems fine for static text throughout the site but what about dynamic data that is stored in the db? Im referring to things like stories, events business listings etc. How do I get those to display in a different language? My initial thought was in the backend have them be able to enter multiple versions of a story, event or listing, one for each language they want to use on the site. But there could be thousands of entries times how many languages they want to show. Is there a better solution/idea that someone can point me to?
Also another issue I was thinking is currently the site allows you to search events/stories/listings, how would that work in different languages? Im assuming if someone selected the site to show in spanish they are going to use spanish words to search the site, but if the information in the db is in english I dont know that would work. Any suggestions on that?
If you want the stories to be correct in all languages, then you need them stored in all languages and provide the backend to do the translations or enter the stories on different languages as you initially thought.
If you don't like that, you might add the google translate element in your pages, to provide automatic (not correct) translation.
For the search question, I would only search for the keywords in the fields of the database in the same language as the user. If Joe is visiting your page in English, only look for the search terms in title_en, content_en, description_en fields of your database (or the ones with language='en' if you have one row per article and translation in the database, instead of one row per article (with all translations inside)). Obviously, this does only work if you put all the translations on the database.
The best solution I have seen described is this.
As i18n CMS sites as you describe are in a constant state of flux, with new articles being added, some of which have had translations, in some languages.
If an article in a chosen language has not yet been translated then show a default language (English?).
Then pick any ideas which appeal to your case:
a) If showing a default article in English also throw onto the page an input box and invite your audience to translate it for you.
b) If showing a default article in English also put on the page an offer to send the content to google translate as well as doing a) above
c) put a bounty on the translation and optionaly do a) and/or b) above.

Categories