SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 48
  1. #1
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    38
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Coding a Bi-Lingual Site: Best Practice?

    Hello everyone,

    I have designed a couple of bi-lingual sites (English and Arabic), and realised that there are a number of ways to implement this feature. However, I'm not sure if there are better ways than what I have come across, and what other PHP programmers would recommend out of their experience.

    The different ways I've realised are:

    1) Separate files for each language: I don't know if this should be part of the list because of its primitiveness, but this was the first method I used. I had a separate file for each page on the site, with the added "_ar" in the file names for the Arabic pages.

    2) Ternary operator for each block of text: I used a GET variable to indicate the language of the page, and the ternary operator chose the relevant text to display, based on the language. The upside was that I was editing a single file for each page, as opposed to two. Also, I could determine where the text to edit would be in the code (more on that later).

    3) A set of 2-element arrays with the text to include: At the beginning of the file, I list a number of 2-element arrays that hold the text to display in the page. The GET language variable determines which array element to use throughout the script.

    For example:

    <?php

    $header = array('EnglishHeader', 'ArabicHeader');
    $description = array('EnglishDescription','ArabicDescription');

    $lang = $_GET[$lang]; // $var is set to 1, for Arabic

    ?>
    <h1><?php echo $header; ?></h1>

    4) Use a database to store the text for each language: Although I haven't implemented this on any of my sites, it is used where I work for the website (using Oracle). The problem I have with this method is that it's difficult to edit the text when it's not in the page file, and would have to access the database table every time I want to edit the text on the page.

    If anyone has any tips on this issue, I'd appreciate the help. Also (although this doesn't belong in the PHP forum), if you have any tips on how to store bi-lingual text in the database (e.g. a row for each language, or a field for each language), then I'd be very grateful.

    All the best,
    Haider

  2. #2
    SitePoint Addict
    Join Date
    Sep 2005
    Posts
    335
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm interested in knowing why using a database to store the text for each language doesn't work for you. So many programs use this as the way they store text regardless of whether or not there are multiple languages. I think if you had the right editing tools to manage the text you might find this to be a great way to handle your project. Maybe find a wysiwyg online editor and design a form with an editor for each language field.

    I've used separate language files to manage that but this really only works well for small snippets of text, not for articles, etc.

    Good luck with your project.
    PHP Shopping Cart Software Easy Ecommerce Shopping Cart Script.
    PHP Super Cart is 100% template driven.

  3. #3
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Try a search in the PAD (PHP Application Design) forum for the terms:

    mutli language

    It throws up a good number of discussions.

  4. #4
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    38
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    jondolar, the issue I have with using a database is that I will continually have to access the database to edit the text on the page. I would prefer having the actual text to edit within the PHP file, so I can clearly see which text to edit.

    Besides, using a database raises the question of how to store the data in the database :-S

    I'll take your question to mean you endorse the database solution, so I'll definitely give this extra thought :-D.. thank you for your response...

    Cups, I did a site-wide search on "lingual" but didn't think of using "language" instead (not on its own, of course!).. so thanks for the tip...

    All the best,
    Haider

  5. #5
    Always learning viveknarula's Avatar
    Join Date
    Mar 2006
    Location
    INDIA
    Posts
    418
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Arrow

    Quote Originally Posted by Cups View Post
    Try a search in the PAD (PHP Application Design) forum for the terms:

    mutli language

    It throws up a good number of discussions.
    I have tried but it return nothing

  6. #6
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    38
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There won't be any results if you copy-pasted what Cups wrote, cos there's a typo in it (which I didn't even realise!)

    It should be: Multi and not mutli...

    I found results (many, actually) with "multiple languages"..

    Good luck, viveknarula!

  7. #7
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Naseej-Designer View Post
    jondolar, the issue I have with using a database is that I will continually have to access the database to edit the text on the page
    It much easier to do it with a database. It just means opening the table in Excel and editing a few cells when you want to update.

  8. #8
    Follow Me On Twitter: @djg gold trophysilver trophybronze trophy Dan Grossman's Avatar
    Join Date
    Aug 2000
    Location
    Philadephia, PA
    Posts
    20,578
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

  9. #9
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dan Grossman View Post
    That's exactly what I mean. A database is so much simpler.

  10. #10
    SitePoint Enthusiast Codebox's Avatar
    Join Date
    Jan 2004
    Posts
    78
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I worked for a giant electronic device seller's website and they used XML files for each language. Each xml file was like this:

    Code:
    <content>
       <about>
       text in a particular language
       </about>
       <contact>
       contact info in tha language
       </contact>
    </content>
    this is not the exact thing but i hope you get the idea.
    Then there was simple an xml parser in php which was doing the job of reading from the xml file for the selected language.

    This way, you have one main file and external language files which can be easily edited.

  11. #11
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Codebox View Post
    I worked for a giant electronic device seller's website
    Well I run a translation bureau and we have translated hundreds of bilingual sites and they are always a table. Doing this with XML files is crazy. Although it is possible to use Trados Tag Editor to facilitate translation of XML files it is still tidious and most serious translation agencies would reject such a job.

  12. #12
    Web developer chrisranjana's Avatar
    Join Date
    Jan 2001
    Location
    chennai , tamil nadu , India
    Posts
    710
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could store Arabic in Mysql but some special considerations need to be taken care of like

    http://forums.mysql.com/read.php?107...7138#msg-37138
    Chris, Programmer/Developer,
    Laravel Php Developers, Ruby on Rails programmers,
    Moodle, Opencart, Magento, Geodesic Classifieds/Auctions,
    www.chrisranjana.com

  13. #13
    SitePoint Enthusiast Codebox's Avatar
    Join Date
    Jan 2004
    Posts
    78
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok it might be crazy, but its a way.. good or bad.. we had to do it as this is what the company asked for..

  14. #14
    Non-Member Musicbox's Avatar
    Join Date
    Nov 2004
    Location
    india
    Posts
    1,331
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    you can use google translator to translate webpages and copy paste language.

  15. #15
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Musicbox View Post
    you can use google translator to translate webpages and copy paste language.
    Not if you want a serious professional translation.

  16. #16
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    38
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you all for the replies.

    The actual translation isn't a problem. This I will do manually since, as bokehman pointed out, automatic translations aren't professional (in fact, they can be quite entertaining, especially when people's names are translated..).

    Dan, thanks for the link. I'm looking into Symfony to see how it can be used...

    chrisranjana, I haven't had problems using Arabic in databases (yet!), but I've taken note of the MySQL forum thread, as I may face issues with searching for Arabic text. So many thanks for the link!

    Bokehman, pardon my ignorance, but when you say that it's as easy as opening an Excel file and editing it, that I should store the table data in a spreadsheet, then populate the table. Then, whenever I wish to edit the database table, that I make the edition in the spreadsheet, and populate the table again?

    It now seems that the database option is the most favoured. I'll look into database design now, to see the best way to structure the data...

    If anyone has any tips in this regard, feel free to contribute

  17. #17
    SitePoint Member
    Join Date
    Dec 2005
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've used the following methods to build a bilingual (or more) website:

    1. Save all phrases into a table called "phrases"
    It's just a simple table with the following cols: "phrase_id", "phrase_category", "phrase_name", "phrase_en", "phrase_?", "phrase_?". The script will access to all phrases through the phrase-name (which have to be unique), which have to be a simple, understandable code for the selected phrase in english.

    2. Categorize all phrases with another table (e.g. "phrase_categories")
    Another table with the following cols: "pcategory_id", "pcategory_name" - pretty simple, isn't it? The name-field have the same conditions than the name-field in the phrase-table (unique, english, short).

    3. Cache all phrases into files
    I used a cms (where I could edit & manage the phrases), so this was very easy to implement - if you code without an user-interface it might be a little bit annoying. My directories looked like this:

    - lang
    - - en
    - - - category-name.php
    - - - category-name2.php
    - - ?
    - - - category-name.php
    - - - category-name2.php

    As you can see, the phrases are categorized by the name of the language (using the iso-code) and the phrases categories (using the name-field of the categories). In all these files I simply used an array called $lang with the phrase-name as key and the translation of the phrase in the selected language as value.

    4. Load all required language-files
    I simply defined an array with all required phrase-categories at the beginning of every file I'm using, before I included my "main-file" (which executes some standard-actions, like login-check, etc.). In this main-file I loaded all required phrase-files (with a global phrase-file for everywhere-used-phrases, like the page's-title).

    5. Further implementation into your project
    In my case I had access to the phrases through the $lang-array, but also included the phrases into my template-engine (parsing all variables with a special syntax and load - if available - the fitting phrase).

    6. Bilingual content
    As you may image, I havn't saved the "real" content of my webpage into these phrases - just simple phrases of the user-interface. To translate the real contents of the cms (like articles) i've completly seperate the contents of these two languages, which is not in all cases the best solution. I simply added a column "lang" to all database-tables where it was necessary, which contains the language-code, and thus the language, so I can just load the contents of the selected language from the database.
    As example, if you want to translate an article, you'll have to create two articles, one with the language-code of "language 1" and the other one with the code of "language 2".
    As said before, this might not be the best solution in all cases, because it creates completly seperated pages (like installing two versions of an alingual-cms) - but in my case it fits brilliant into the concept.


    I hope these details were usefull for somebody - I don't know if it's the best solution, but I was completly satisfied, so was the customer.

    Floriam

  18. #18
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Naseej-Designer View Post
    Bokehman, pardon my ignorance, but when you say that it's as easy as opening an Excel file and editing it
    That's exactly what I'm saying; you can just dump the table as .CSV or some other universal format that can be easily worked on in excel or other spreadsheet client. My personal preference is tab delimited but I work in whatever my clients send me.

    The other thing to remember is that certain texts can be shared between pages so don't make your DB referencing page specific.

  19. #19
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I think the best way is to have 2 folders, one "en" and one "ar".

    Then, make files with only the content inside, and call the arabic files exactly the same as the english names (e.g. members.php has the same name in each file). Then, simply require the files
    PHP Code:
    <?
    switch($_GET['lang']){
       case 
    "ar":
            
    path="/ar/";
       break;
       case 
    "en":
            
    path="/en/";
       break;
       default:
            
    path="/en/";
       break;
    }
    ?>
    <div id="content">
    <?
    require($path."content.php");
    ?>
    </div>
    Something like that.

    Or you could store the different bits of content in arrays:
    PHP Code:
    <?
    $lan 
    = array();
    $l $_GET['lang'];
    $lan['en'] = "Hello, welcome";  //english
    $lan['cy'] = "Bore da, Croeso"//welsh (don't know arabic)
    ?>
    <div><? echo $lan[$lang]; ?></div>
    But i would go for the first one.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  20. #20
    SitePoint Enthusiast
    Join Date
    Jul 2006
    Posts
    38
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Floriam, thank you for your detailed reply.

    You and Bokehman raised a very important point about not making the text (or phrases) page specific. I was thinking of including a column that indicates which page the text belonged to! Having a phrase_category table might be a good idea, or maybe just specify the required phrases within the PHP itself.

    Bokehman, once again, thanks for this great tip! It sure makes working with databases more friendly!

    Arkinstall, thanks for the code snippets. They helped me visualize how to use the separate folders solution. The databases solution seems a bit cleaner, cos it wouldn't require using a series of require() commands...

    I appreciate all the help you guys have offered!

  21. #21
    SitePoint Enthusiast
    Join Date
    Jul 2005
    Location
    Norway
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I suggest the following approach:

    Whenever you echo something, do like this:

    echo tr("text to be displayed");

    The tr function needs to do the following:
    - It needs to know what language is selected, either via GET or SESSION etc.
    - Then it looks up the correct translation in the database
    - If the "text to be displayed" is not found, then it is inserted into the database, and the default text is shown.

    The table in the database would be like this:
    Code:
    CREATE TABLE translation (
      phrase_main VARCHAR(255),
      phrase_translated VARCHAR(255),
      phrase_language INT(3),
      PRIMARY KEY (phrase_main, phrase_language)
    );
    
    CREATE TABLE languages (
      id INT(3) PRIMARY KEY AUTO_INCREMENT,
      language VARCHAR(10) NOT NULL DEFAULT ''
    );
    Finally you need to have a translation interface in your application so that every phrase can be translated into a number of different languages.

    I don't think this approach is good for larger amounts of text, only for applications where words or a small amount of text is displayed.

  22. #22
    SitePoint Guru Majglow's Avatar
    Join Date
    Aug 1999
    Location
    B-Town
    Posts
    645
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Or instead of reinventing the wheel, you could use http://us3.php.net/gettext
    Ohai!

  23. #23
    Worship the Krome kromey's Avatar
    Join Date
    Sep 2006
    Location
    Fairbanks, AK
    Posts
    1,621
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'll throw in my two cents on this issue. I haven't gotten to implementing anything yet, but I'm putting the final touches on the application design for a multi-lingual web site myself. I opted for the database solution, and used a database design like so:

    Each phrase to be used is given a unique name, e.g. the greeting echoed to a user upon login might be called "login_greeting". Each language is then given its own table (although I'm toying with the idea of changing that up to give each language a column in a single table). For example, the following might be the rows from the tables English, French, and German:

    en:
    'login_greeting', 'Welcome, %1!'

    fr:
    'login_greeting', 'Bienvenue, %1!'

    de:
    'login_greeting', 'Gutentaag, %1!' -- spelling's probably way off, my German is terrible

    Pulling the phrases from the database are then a matter of simply querying the proper table. My design calls for copying the English table (including data) into each new table, so any phrases that have not yet been translated would display in English. This of course makes the translator's interface slightly more difficult to find untranslated phrases, which is why I'm thinking I may switch to a single table with a column for each language. My thoughts for the multiple-table solution were because I was afraid of the consequences of having too many columns in a table; now that I know more about databases, I know those concerns were unfounded. Under this new design, the above example would instead look like this:

    phrases:
    phrase_name | en | fr | de | jp
    'login_greeting' | 'Welcome, %1!' | 'Bienvenue, %1!' | 'Gutentaag, %1!' | NULL

    Note the NULL value in the column for Japanese; this can immediately send up a red flag for my Japanese translator that this phrase still needs to be translated.
    PHP questions? RTFM
    MySQL questions? RTFM

  24. #24
    Keep it simple, stupid! bokehman's Avatar
    Join Date
    Jul 2005
    Posts
    1,935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kromey View Post
    Each language is then given its own table
    I've never seen that design on a corperate website. Normally each column is a language and each row is a phrase.

  25. #25
    Follow Me On Twitter: @djg gold trophysilver trophybronze trophy Dan Grossman's Avatar
    Join Date
    Aug 2000
    Location
    Philadephia, PA
    Posts
    20,578
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    A couple of the designs presented here have been either redundant or not extensible, when a design which could be extended to infinite locales can be accomplished at no extra cost. Simply have one table as follows:

    Code:
    phrase_cd: a string representing the phrase, such as 'login_greeting'
    country_cd: a 2-digit country code, can be empty
    language_cd: a 2-digit language code
    phrase_text: the translated text
    This design is sufficient for internationalization in infinite locales and for falling back multiple levels when the most specific translation isn't available. Simply enter the text in your primary language for every phrase needed by the application (for example, if your primary language is English, have every phrase entered with "en" for the language and no country). Then, add more specific translations as are available or as they are written.

    When you write your application, you write it using the phrase codes. Your lookup to replace those phrase codes with their corresponding text can be done in two ways:
    1) Construct a database query which returns the most specific translation available -- one which matches both the country and language of the user, or if that's not available, one which matches the language of the user, or if that's not available, the english translation.
    2) Retrieve all rows from the database for the given phrase code, and print the one which is most specific to the user as above, using application logic instead of database logic.

    Either way you have all the information you need, there is never an instance where no text is displayed, you can extend the application to support infinite locales, and you can be as granular as you wish with the variations between various countries that speak the same language.

    This is how I've seen corporations do it (I worked on software for DuPont which is used in 54 different regions), I've never seen it done with separate tables OR separate columns for each language. The phrase table i worked with had over 500,000 entries and adding a column to that to add a new region would be quite impractical, both because it'd take forever to rebuild the table with possible data corruption, and because all software that used the table would have to be re-bound against the new schema.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •