Multiple culture on a web site

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
olog-hai
Forum Commoner
Posts: 34
Joined: Thu May 31, 2007 8:47 am
Location: Québec city, QC, Canada

Multiple culture on a web site

Post by olog-hai »

Hi folks,

I want to know the best way to manage many languages on web site ?

#1: Via file: each fil are named with the culture name: ex: fr-ca.inc, en-us.inc. And we include this file with php file.

#2 Via DB: instead to include file, we make a call via stored procedure to get the traduction.

#3 other way ?

which is the fastest way ? My first goal is light-weight on the network

thanks for your help.
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

For a website? You'd just have a separate section.

en-us.yourname.com
en.yourname.com
fr.yourname.com
es.yourname.com


For an application, you'd have constants set by language

Code: Select all

if($language == 'en')
{
    define("HELLO", "Hello World");
}
else if($language == 'es')
{
    define("HELLO", "Hola Mundo");
}

echo HELLO;
User avatar
olog-hai
Forum Commoner
Posts: 34
Joined: Thu May 31, 2007 8:47 am
Location: Québec city, QC, Canada

Post by olog-hai »

Hi,

All text in my whole site is stored in file that i include in my php file, and depend on the language selected in their profile i display the good text.

I think that If i store the text in a table and access it with a stored procedure will be faster, i just want someone that confirm my thought. :)

and is exist another way to manage this ?

thanks for your time.
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

I'd stick with include(). If MySQL doesn't need to be involved, then don't involve it.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

It's difficult to define "fast" in web applications until you implement two options and benchmark both. Language support is generally available from any number of sources. Constants are generally not recommended since they are global data and lead to coupling (makes it difficult to try other options later). Suggested sources are the database, gettext file, or the 3 or more variants of XML formats like XLIFF. The speed of either one should be benchmarked for your system since file speed over database speed is easy to get wrong given how recent MySQL version utilise more efficient internal caching.

In general, PHP files are losing popularity. They are programming language specific, not as fast as you might think (requires generating an entire array/set of constants at runtime which is costly without an opcode cache) and does not facilitate efficient searching which is faster in XML and gettext formats (a bit like lazy loading).

I'd invest some time into researching an existing object-oriented solution like Zend Framework's Zend_Translate where you can swap backend storage methods without changing the code...
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

I would avoid using subdomains for l10n / i18n.

What about using a l10n() function that translates it's argument to another language/format based on it's md5?

Code: Select all

l10n_set_loc('fr_CA');
l10n('hello'); // echoes "bonjour"
l10n_set_loc('en_US');
l10n('hello'); // echoes "howdy"
The function would consult a database of translations for a fr_CA entry for md5('hello'); That way you could keep a control panel of translations, optionally automating it with google language tools or the like.

Thoughts people?
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

In the case of translating an entire website, is that such a good idea?

Unless, of course, he's programming his own translator. That'd be interesting code to look at. Maybe.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

I foresee it living mostly in the template layer.. translating small-to-medium sized blocks of text.

I've been meaning to implement something like this myself for a while, but time < ambition at the mo'.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

A quick note: the proper term for this sort of thing is called "localization", a specific "language" with cultural things associated with it is a "locale". That will help you on your Google searching.

If you really need speed, memcached is the way to go. Otherwise, PHP files should be sufficiently fast and flexible.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

another note (I find it interesting, anyway):

"l10n" and "i18n" are abbreviations for "localization" and "internationalization", respectively. the terms are the first and last letters of each word, with the number of missing letters sandwiched in between. The more you know....

While they have subtle differences, "l10n" is often what people mean when talking about this concept, even though the terms seem to be interchanged somewhat freely in general use.
User avatar
kyberfabrikken
Forum Commoner
Posts: 84
Joined: Tue Jul 20, 2004 10:27 am

Post by kyberfabrikken »

Kieran Huggins wrote:

Code: Select all

l10n_set_loc('fr_CA');
l10n('hello'); // echoes "bonjour"
l10n_set_loc('en_US');
l10n('hello'); // echoes "howdy"
gettext?
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

8O
wow.. serves me right for not searching first, though I can see where the gettext functions are sort of lacking, they'd work very well for simple translations.

I'd like to see a replacement that uses a database, has auto-translation, an interface for human translations, etc... but I don't think I'm the one to write it.
User avatar
inghamn
Forum Contributor
Posts: 174
Joined: Mon Apr 16, 2007 10:33 am
Location: Bloomington, IN, USA

Post by inghamn »

For what it's worth, in our Content Manager we've implemented localization using the database to store meta-data about Documents. The actual content of the Document is stored in files on the server.

This lets us do two things: We can localize the content without needing to create multiple Documents; and we can put the content under revision control, using Subversion. So now, we have versioned, localized content.

Code: Select all

create table documents (
  id int unsigned not null primary key auto_increment,
  title varchar(128) not null,
  created timestamp not null default 0,
  createdBy int unsigned not null,
  modified timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  modifiedBy int unsigned not null,
  publishDate date not null,
  retireDate date,
  foreign key (createdBy) references users(id),
  foreign key (modifiedBy) references users(id)
) engine=InnoDB;
Then, the content of the documents is stored in a directory structure based on the created date of the Document.

/documents/$year/$month/$id.$lang

$lang is the user's current language code (en,fr,es, etc.)

viewDocument.php includes the appropriate lang file based on $_SESSION['lang']

All that's left if the actual Content Negotiation, done in bootstrap, or whatever configuration script you've got:

Code: Select all

/**
 * Language Negotiation
 * Order of precedence: GET,SESSION, HTTP_ACCEPT_LANGUAGE, en
 */
define('DEFAULT_LANGUAGE','en');
if (isset($_GET['lang']))
{
	$_SESSION['LANGUAGE'] = strtolower(substr($_GET['lang'],0,2));
}
if (!isset($_SESSION['LANGUAGE']))
{
	if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
	{
		$_SESSION['LANGUAGE'] = strtolower(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'],0,2));
	}
	else { $_SESSION['LANGUAGE'] = DEFAULT_LANGUAGE; }
}
Post Reply