Jump to content

Multilanguage site


kurt.santo

Recommended Posts

Working on this multi-language site I created include files for nav bars and content areas (currently only English ones). Use the following code:

<?php$lang = (ereg('[a-z]{2}(\-[a-z]{2})?', $_GET['lang']) && is_file("terms-{$_GET['lang']}.htm") ? $_GET['lang'] : 'en');$content = 'terms-{$lang}.htm';?>

and include it via "<?php require_once $content;?>". Apache complains that there is not such file or directory. This makes sense as I did not pass any information from nav bar. I just opened the file. How can you do it that always assumes that it is the "en" version unless someone clicks onto the German flag? Or does my mistake lay somewhere else? Kurt

Link to comment
Share on other sites

The first line checks if $_GET['lang'] is two characters, possibly followed by a hyphen and two more characters, and that a file exists with that name. If both of those are true then it uses $_GET['lang'] as the value for $lang, or else it just uses 'en'. That will set the default. If you're getting an error print the filename you're trying to include and see what it says.

Link to comment
Share on other sites

Your second line uses single quotes. That's pretty much your only problem.Inside double quotes, the variable referenes ({$varname}) are resolved. Inside single quotes, they aren't. Simply replace

$content = 'terms-{$lang}.htm';

(which will ALWAYS resolve to 'terms-{$lang}.htm' - a file which obviously can never exist)with

$content = "terms-{$lang}.htm";

(which will resolve to either 'terms-en.htm' if $lang has it's default value, or another value at the place of "en", which is exactly what you want)

Link to comment
Share on other sites

Cheers, does the job for my English version:-) What would you advice in how to update best the include files as soon as someone clicks onto the German flag? In another thread I learned that you can update the content for a file through "languages.php?lang=en", but how would you best do this for four different include files for each page?Also, someone told me never to place include files into the web directory? Is this true and what does this mean exactly? Not sure what security thread it could be...Kurt

Link to comment
Share on other sites

What would you advice in how to update best the include files as soon as someone clicks onto the German flag?
You don't have to update anything. When they click a link it loads a new page, if the lang variable is on the querystring then it will use that or else it should look in the session. The line you have right now only checks in $_GET. That would mean that you would need to put the lang on each URL. It would be better to store it in the session and check in the session if $_GET is empty.$def_lang = 'en';$lang = (ereg('[a-z]{2}(\-[a-z]{2})?', $_GET['lang']) && is_file("terms-{$_GET['lang']}.htm") ? $_GET['lang'] : (isset($_SESSION['lang']) ? $_SESSION['lang'] : $def_lang));After that you would store $lang back into the session if it is something other then the default. Then each page can use $lang to include whatever it needs to include. There's nothing else to update, as long as all of the language-specific things use the $lang variable. Included files will have access to $lang, you won't need to check for it in every file.I don't really like using the words "never" and "always", it's perfectly fine to keep most include files wherever you want. On a shared host you may want to keep some sensitive files out of the web root.
Link to comment
Share on other sites

You don't have to update anything. When they click a link it loads a new page, if the lang variable is on the querystring then it will use that or else it should look in the session. The line you have right now only checks in $_GET. That would mean that you would need to put the lang on each URL. It would be better to store it in the session and check in the session if $_GET is empty.$def_lang = 'en';$lang = (ereg('[a-z]{2}(\-[a-z]{2})?', $_GET['lang']) && is_file("terms-{$_GET['lang']}.htm") ? $_GET['lang'] : (isset($_SESSION['lang']) ? $_SESSION['lang'] : $def_lang));After that you would store $lang back into the session if it is something other then the default. Then each page can use $lang to include whatever it needs to include. There's nothing else to update, as long as all of the language-specific things use the $lang variable. Included files will have access to $lang, you won't need to check for it in every file.I don't really like using the words "never" and "always", it's perfectly fine to keep most include files wherever you want. On a shared host you may want to keep some sensitive files out of the web root.
It would be great if you could further explain:I did the first version including a link as "<a href="?lang=de">german</a>", which works great. But as you said I also saw the limitation in having to add the querystring to all links in my nav includes. So, I would rather do as you adviced. Would I need to have a line as "$lang = (ereg('[a-z]{2}(\-[a-z]{2})?', $_GET['lang']) && is_file("terms-{$_GET['lang']}.htm") ? $_GET['lang'] : (isset($_SESSION['lang']) ? $_SESSION['lang'] : $def_lang));" for all of my includes (all language specific)? Then I get completely lost on the second bit with the storing of $lang back into session. I assume this is the way to let the user click through the German only version until he clicks onto the English flag again? If it is (this is what I am after as user very likely wants to browse the German section after clicking the German flag) could you let me know in how I would do that?Also, thanks for your advice concering the storage of include files...Kurt
Link to comment
Share on other sites

You can just add

?lang={$lang}

at every link you have. You don't have to do the language selection on each link. It's already done at the top.If you want to keep the URLs neat, and filled only on demand (i.e. when the user clicks on the language switch), then you must store the language preference in a persistent storage like a cookie or a session variable. I thought we already went thru that in the previous topic!To add to the above example:

$langCode = '[a-z]{2}(\-[a-z]{2})?';$lang = (ereg($langCode, $_GET['lang']) && is_file("terms-{$_GET['lang']}.htm") ? $_GET['lang'] : (ereg($langCode, $_COOKIE['lang']) && is_file("terms-{$_COOKIE['lang']}.htm") ? $_COOKIE['lang'] : 'en'));setcookie('lang',$lang);

(If a 'lang' qeury string variable is available*, use that value. If not, check if a 'lang' cookie is available*, and if so, use that value. If not, use the default language. After the language selection, set a 'lang' cookie with the selected language as a value)*"available" in this case means "if it's a valid language code, and leads to an existing file".That's pretty much it. The next time the user asks for a page without having a query string variable, (s)he'll be using the last language (s)he selected, since that is stored in the cookie. The way the above is set, the cookie expires as soon as the browser closes. If you want, you can set a specific expiration time with the third argument.It's a similar deal with $_SESSION, but I'll leave justsomeguy to explain that, as I don't have any experience with sessions whatsoever.

Link to comment
Share on other sites

You can just add
?lang={$lang}

at every link you have. You don't have to do the language selection on each link. It's already done at the top.If you want to keep the URLs neat, and filled only on demand (i.e. when the user clicks on the language switch), then you must store the language preference in a persistent storage like a cookie or a session variable. I thought we already went thru that in the previous topic!To add to the above example:

$langCode = '[a-z]{2}(\-[a-z]{2})?';$lang = (ereg($langCode, $_GET['lang']) && is_file("terms-{$_GET['lang']}.htm") ? $_GET['lang'] : (ereg($langCode, $_COOKIE['lang']) && is_file("terms-{$_COOKIE['lang']}.htm") ? $_COOKIE['lang'] : 'en'));setcookie('lang',$lang);

(If a 'lang' qeury string variable is available*, use that value. If not, check if a 'lang' cookie is available*, and if so, use that value. If not, use the default language. After the language selection, set a 'lang' cookie with the selected language as a value)*"available" in this case means "if it's a valid language code, and leads to an existing file".That's pretty much it. The next time the user asks for a page without having a query string variable, (s)he'll be using the last language (s)he selected, since that is stored in the cookie. The way the above is set, the cookie expires as soon as the browser closes. If you want, you can set a specific expiration time with the third argument.It's a similar deal with $_SESSION, but I'll leave justsomeguy to explain that, as I don't have any experience with sessions whatsoever.

So not worry. All your explanations from your previous code have been digested and put to some good. I remember a cookie is based on the pc and the session is based on the user. I just struggle how to set $lang into the session (I prefer sessions, there might be some crazy Germans sharing their pcs with some English chaps;-)). Would I do this via sth like "setsession('lang',$lang);" or similar?Other related problem: Still not sure what to do with the title text. I would prefer to keep the url clean as long as no language selection is being made. Is there way to achieve this?Am really sorry to be again such a pain....Kurt
Link to comment
Share on other sites

The only links you need the ?lang= on are the links to switch languages. Every other page can get the language preference from the session (or cookie) that will default to whatever you want if there is none. You can check for the language and store in the session like this:

session_start();$def_lang = 'en';$lang = (ereg('[a-z]{2}(\-[a-z]{2})?', $_GET['lang']) && is_file("terms-{$_GET['lang']}.htm") ? $_GET['lang'] : (isset($_SESSION['lang']) ? $_SESSION['lang'] : $def_lang));$_SESSION['lang'] = $lang;

That $lang= line will set $lang to be the value in $_GET['lang'] if it's in the right format and a file exists with that name, or else it will use the session value if it has been set, or else it will use the default. The reason I left the ereg check off the session is because anything being stored in the session has already passed the test.You only need that code once on the page, you don't need it on every include file. If index.php includes header.php, content.php, footer.php etc you only need that code once on index.php, the other pages can just use the $lang variable to figure out which language to use. I've set up sites to do this same thing.

Link to comment
Share on other sites

The only links you need the ?lang= on are the links to switch languages. Every other page can get the language preference from the session (or cookie) that will default to whatever you want if there is none. You can check for the language and store in the session like this:
<?phpsession_start();$def_lang = 'en';$lang = (ereg('[a-z]{2}(\-[a-z]{2})?', $_GET['lang']) && is_file("includes/home-{$_GET['lang']}.htm") ? $_GET['lang'] : (isset($_SESSION['lang']) ? $_SESSION['lang'] : $def_lang));$_SESSION['lang'] = $lang;$globalNav = "includes/nav/globalNav-{$lang}.htm";$localNav = "includes/nav/helpNav-{$lang}.htm";$guidesNav = "includes/nav/guidesNav-{$lang}.htm";$furtherNav = "includes/nav/furtherNav-{$lang}.htm";$content = "includes/home-{$lang}.htm";?>

Why is that?Kurt

Link to comment
Share on other sites

session_start needs to go before any output, it sends a cookie. Make sure it appears before you send any output. The error message tells you the line where output was sent, you need to move session_start before that. The other code can go anywhere.

Link to comment
Share on other sites

session_start needs to go before any output, it sends a cookie. Make sure it appears before you send any output. The error message tells you the line where output was sent, you need to move session_start before that. The other code can go anywhere.
Cheers, that solved my problem. The DOCTYPE declaration was before and as soon as I moved after the whole php block at the top it started working:-)Again with regard to "$lang = (ereg('[a-z]{2}(\-[a-z]{2})?', $_GET['lang']) && is_file("includes/nav/globalNav-{$_GET['lang']}.htm") ? $_GET['lang'] : (isset($_SESSION['lang']) ? $_SESSION['lang'] : $def_lang));"...This line tests first if the lang is in correct format and if yes, then take whatever value is stored in the $lang variable of the globalNav-{$_GET['lang']}.htm. If there is nothing stored it take the default, which is english ($def_lang = 'en':). So, I got this one. But this also means that the globalNav file supplies us with a test that is applied to all other includes files? I think it is, but just checking...Kurt
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...