I have a multilanguage website (spanish, english, french) in PHP which main's language is english.
If $_SESSION['idm'] is set to 'en' it loads a file with the translations.
I want to set it up this way:
if the user language is spanish
www.mydomain.com and mydomain.com -> es.mydomain.com
www.mydomain.com/video.php?id=3 -> es.mydomain.com/video.php?id=3
if user language is french
www.mydomain.com and mydomain.com -> fr.mydomain.com
www.mydomain.com/video.php?id=3 -> fr.mydomain.com/video.php?id=3
if not any of the above
www.mydomain.com and mydomain.com -> en.mydomain.com
www.mydomain.com/video.php?id=3 -> en.mydomain.com/video.php?id=3
How do I do that, and, is this good SEO wise?
in PHP:
// check if the current domain is the generic one
$req_domain = $_SERVER['SERVER_NAME'];
if ($req_domain == 'www.mydomain.com' || $req_domain == 'mydomain.com') {
$subdomains = array ('fr' => 'fr.mydomain.com',
'es' => 'es.mydomain.com',
'en' => 'en.mydomain.com');
// get the language from the session variable (if set), or use default
$lang = 'en'; // default language
if ( isset($_SESSION['idm']) && isset($subdomains[$_SESSION['idm']]) )
$lang = $_SESSION['idm']; // selected language
// redirect while maintaining the complete request URI
header('Location: http://' . $domains[$lang] . $_SERVER['REQUEST_URI']);
exit;
}
It's better for SEO than your current session based method which hides the language variations from the search engines.
One slight alteration would be to keep the default language (en) on the main domain.
To make it work best:
Ensure on page links are relative so you don't cause redirects on every click.
Add hreflang meta data to the pages to indicate where the translations are.
Don't force people into a language. Make sure they can easily change.
Related
Here is what I'm trying to do:
Whatever page customer open script will redirect him to his preferred language read from $_SERVER["HTTP_ACCEPT_LANGUAGE"];
example:
Customer browser is set in Spanish. If he open page http://example.com/script-name.php?param1=aa¶m2=bb
than script will redirect him to http://example.com/es/script-name.php?param1=aa¶m2=bb
I have script which provide me with language of the browser $lang=substr(Get_Client_Prefered_Language(),0,2); that is sorted
Than I have script which reads the address
$location = '';
parse_str(html_entity_decode($_SERVER['QUERY_STRING']),$query_string);
if(isset($query_string['language'])) {$query_string['language'] = null;}
$new_query_string = !empty($query_string) ? http_build_query($query_string) : '';
if($new_query_string != ''){$location .= '?'.$new_query_string;}
and that provide me with new address:
$location="https://macrohosting.co.uk/".$lang.$_SERVER["SCRIPT_NAME"].$location;
and than I can use header('location: '.$location);
All works quite well but some of the pages I have already url rewrited.
And not sure how to adjust above script so when customer visit http://example.com/page1.htm than will be redirected for example to http://example.com/es/page1.htm
Without that modification customer is redirected to http://example.com/es/page_example.php?param=aa¶m=bb
there is no need for you to redirect user for each request . it's the worth way to handle the problem.
you can get user browser language in front controller (for example index.php file) and then generate links accordingly.
you are trying to hit your web server 2 times for each request?? it's not an option.
if you are using a php framework there should be a better way to handle the problem.
<?php
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
$link_to_about_us_page = "http:://domain.com/$lang/about";
and keep in mind that first parameter after domain in every request is language and according to that language you should fetch content from your storage and show data.(this part should be handled by your router)
and if language is not provided you redirect users to your default language .
for example
http://domain.com/contact
to
http://domain.com/en/contact
thats how drupal handle multilingual. there are multiple things that can affect content language (user browser| url | user ip | ...)
and you can arrange priorities.
So I'm building a small multilingual (French + English) website and there is a little bug. I would like to remove the "english default" language in the code, so if a user picks french on one page, any page he will select afterwards will be in french and not be "back" to english. Same if the user picks english in the first place. But since there will be more french users, I would like it to be the default language on the home page.
The content is in folder with prefixes: fr_language.php and en_language.php
The lang.php file here
Links for FR or EN
Français
English
And the navigation
<ul>
<li><?php echo $lang['home']; ?></li>
<li><?php echo $lang['services']; ?></li>
<li><?php echo $lang['aboutus']; ?></li>
<li><?php echo $lang['contact']; ?></li>
</ul>
Thanks for your help!
EDIT:
Ok great, with your help it's working! In my "nav.php" include, I wrote this. Perhaps it's possible to do a cleaner version, haha! Any ideas? Thanks again!
Consider using the following approach/method:
if(isset($_GET['lang']) && $_GET['lang'] == "fr"){
// do something
} else {
// do something else
}
You should also be made aware of (XSS) Cross-site scripting.
Here are a few links to read up on:
http://en.wikipedia.org/wiki/Cross-site_scripting
http://www.sitepoint.com/php-security-cross-site-scripting-attacks-xss/
http://www.smashingmagazine.com/2011/01/11/keeping-web-users-safe-by-sanitizing-input-data/
You can further your research by using "XSS injection php" as keywords in your favorite search engine.
you need to keep the state of the language somewhere.
you will either have to pass it around with each request by
url parameter: page.php?lang=en
path: yourpage.com/en/page.php
or use a cookie to store it. you will get the cookie value passed with each server request
you can read the cookie through the $_COOKIE var. you can set it either in javascript or php
Personally, I recommend an on click for your language selector that will create a new PHP session and store the language.
The benefit of doing it this way is that you don't always have to have your language appended to the end of your URL. This will only happen each time a session has to be created, (so if you don't set a timeout then only when the computer restarts). Once the page redirects from the page that sets the language it doesn't have to $_GET anymore, but rather just check for an active session.
You will have to redirect the user to the page that has your PHP script and then set the language based on the what is sent in the URL. You could however, redirect after the script finishes back to the page the user was on (and load their new selected language).
HTML:
Français
English
PHP:
// intitially set language by your selector
<?php
session_start();
$_SESSION['language'] = $_GET['lang'];
?>
Now you could place your getter code on any page that gets included on all your pages (like a header or base page):
// check for the language
<?php
session_start();
if (isset($_SESSION['language'])) {
// now change the language of the page based on what it is
if ($_SESSION['language'] == "en") {
// change page language to english
} else {
// change page language to french
}
}
?>
It looks like you are using you are using a function called get_lang_id() to pull from the cookie and use that to load the language file.
The get_lang_id() function is currently defaulting to English:
function get_lang_id()
{
return ( isset( $_COOKIE['lang'] ) &&
strlen( $_COOKIE['lang'] ) == 2 &&
is_language_supported( $_COOKIE['lang'] ) ) ?
htmlspecialchars($_COOKIE['lang']) : 'en';
}
If you change the 'en' at the end to 'fr', it will change the default language file to the French version. Clicking either link will set a cookie, which will skip using the default.
OBJECTIVE
I'm trying to accomplish an automatic redirect depending on the users language. I have a fully working code for that:
// List of available localized versions as 'lang code' => 'url' map
$sites = array(
"da" => "http://www.fredrixdesign.com/",
"en" => "http://en.fredrixdesign.com/"
);
// Get 2 char lang code
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
// Set default language if a `$lang` version of site is not available
if (!in_array($lang, array_keys($sites)))
$lang = 'en';
// Finally redirect to desired location
header('Location: ' . $sites[$lang]);
?>
This redirects the user to a Danish (da) version, which is the main/root website, if the user is Danish. If the user is German, English, Polish, etc. it redirects the user to a subdomain; en.fredrixdesign.com, which is an English version of the website.
But the problem occurs, when a Danish-user goes on my site. The code, located in the top of my header.php, keep getting executed, which means, it keeps creating the redirect, which finally forces the browser to create an error due to too many redirects. This makes sence.
QUESTION
My question is then; how would I go around modifying the above code, so it only executes the redirect once? If it just completed the redirect, it will simply continue to execute the site.
Well, I bet you can find a solution yourself if just think it over a bit.
All you need is to check if current domain meets desired language.
Just amend your array a bit
$sites = array(
"da" => "www.fredrixdesign.com",
"en" => "en.fredrixdesign.com"
);
and then add a condition for the redirect
if ($sites[$lang] != $_SERVER['HTTP_HOST']) {
header('Location: http://' . $sites[$lang] . '/');
exit;
}
that's all
You could set a cookie value, that tells you that you have already automatically redirected the user to a language-specific site. If that cookie exists, do not do the redirect again. You may also wish to consider the case where the user has cookies disabled.
You could do this with GeoIP + .htaccess, it's really easy to implement.
http://www.maxmind.com/app/mod_geoip
Something like this could do the trick (of course there are tons of heavy good solution but for two languages there is no harm to do simple things and improve later when needed):
function redirectIfUserIsNotOnTheGoodURLBasedOnHisLanguage()
{
// List of available localized versions as 'lang code' => 'url' map
$sites = array(
"da" => "http://www.fredrixdesign.com/",
"en" => "http://en.fredrixdesign.com/"
);
// Get 2 char lang code
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
// Set default language if a `$lang` version of site is not available
if (!in_array($lang, array_keys($sites)))
$lang = 'en';
if (($lang == 'da' && $_SERVER['SERVER_NAME'] == 'www.fredrixdesign.com') || // Danish people are on the right place
($lang == 'en' && $_SERVER['SERVER_NAME'] == 'en.fredrixdesign.com')) // Other people are on the right place
{
// no redirection
return;
}
// else redirect to desired location
header('Location: ' . $sites[$lang]);
exit(0);
}
redirectIfUserIsNotOnTheGoodURLBasedOnHisLanguage();
I'm developing a niche social networking site that is going multilingual. That means our current URL structure will soon need to start using translated words for slugs like the following:
www.example.com/home becomes www.example.com/inicio
www.example.com/profile becomes www.example.com/perfil
www.example.com/help becomes www.example.com/ayuda
And so on. My question is: what's the best way to support this in a PHP application? For incoming requests, I thought a dictionary like the following in my router.php file would suffice:
<?php
$request = explode("/", trim($_SERVER['REQUEST_URI'], "/"));
// Dictionaries of page slugs.
$slugs = array(
'es' => array(
'inicio' => 'home',
'perfil' => 'profile',
'ayuda' => 'help',
)
// additional languages can be added here
);
// Rewrite any incoming (foreign) requests
if ($host=="www.example.es") { // to be made programmatic
$lang = "es"; // pick up from locale constant rather being hard-coded
if (array_key_exists($request[0], $slugs[$lang])) {
$request[0] = $slugs[$lang][$request[0]];
}
}
...
Which basically takes URL segments and matches them against an English counter-part if it exists. If not, then it will proceed as normal and most likely cause a 404 as a controller doesn't exist for URL segment.
Although this words, I need it to be backwards-compatible too. For example, when building URLs in my application.
Naturally, as the application is only English at the moment these are just hard-coded. So say, when fetching a User object I do the following:
<?php
class User {
function __construct($id) {
// fetch user details
$this->profile_url = ROOT . "/profile/" . $this->username;
}
}
What is the best method to then replace instances of "/profile/" being hard-coded to getting the translated version, i.e. "/perfil/" in the Spanish site?
I could always be wrong, but here goes...
The standard way to achieve multilingual websites is to use i18n dictionary/template techniques in which you have a separate dictionary for each language, and in some cases different templates.
However, in such cases, I have never seen anybody change the language of their URL's. URL's map a request to files on the server disk (generally speaking), and there for shouldn't change based on language if you can avoid it.
It is common to prefix the 'path' section of your URL with the language you are requesting - ie:
http://foo.bar/en-us/foobar.html
To summarize:
I wouldn't worry about translating your URLs as it isn't a standard practice (atleast, not that I have seen). Simply prefix the URL 'path' with a language denotation such as in the URL above.
I have something similar in an application I'm developing.
Each page has a unique ID which is matched to a slug, page title, meta description and such for each language in a table.
As for the people saying it's not standard practice and not to bother with it I disagree as having nicely translated URLs can help your SEO in different languages.
Well, a common pattern I've seen for php is to create a php file for each language and initialize a large dictionary in which the keys are the same for all languages.
Have a session variable called language which can initially be 'en' for english (or whatever you prefer), and then include using command "include(language . '/main.php');" in which you have a folder called 'en' which contains all php files to include for translations. If main gets too large, you can subdivide and include whichever translation serves your needs (for example a /en/forum.php for forum translations and a /en/blob.php for front page translations).
It has the tremendous advantage of being flexible and allowing you to control the language simply by modifying one session variable. You can even do tricks like detect browser language settings and assign language according to that if it hasn't already been defined rather than simply making it english.
I was thinking about this, as I'm going down this path now. I was going to use a similar method, but not the same...
I was going to have language "include" files with all the strings of the site. So...
/languages/en.php
would have all the correct strings for the English language, and the other language files could be dropped in as new translations are done.
In the en.php file, I was going to put in fields like this
define('PageTitleWelcomeMessage', 'Welcome to Foo');
And then call that static variable anywhere in the site. The en language would be defined in their profile
I could then call that variable like so:
echo PageTitleWelcomeMessage;
My old web site has an index.html page … nothing strange! Everything is fine.
The new web site has an english and a french version, so the new index is index.php?lang=eng…. That makes sense.
I don’t like to make a front page that will say “english” or “french”. But that’s not good for ranking or seo.
So the question is: How do I manage to get a default index.php with request (?lang=eng) to become the front page?
domain.com/en/index.php
domain.com/fr/index.php
Use url rewriting with regular expressions (mod_rewrite, ISAPI, whatever) to handle requests to relevant pages so
domain.com/en/index.php REWRITE TO domain.com/index.php?lang=en
domain.com/fr/index.php REWRITE TO domain.com/index.php?lang=fr
This way your pages are two seperate pages to search engines but handled via one gateway in code. I'm not a regex expert but it would be a very simple regex I would imagine
I'm not sure I understand the question. It seems to have two parts:
How to provide a default language of English:
$lang = empty($_GET['lang']) ? "eng" : $_GET['lang'];
Do you also have a problem of where to put the English/Francais links so search engines don't ding you? I wasn't aware of this problem.
It might also help to let us know if you're using a CMS, and if so which one.
Unless I'm misunderstanding the question, in index.php, when you check the language, put something like this:
$lang = #$_GET['lang'];
if ( empty($lang) ) $lang = 'eng';
Just put an argument in the php code that says :
if (lang == "") // haven't done php in a while so the syntax is probably wrong
{
lang = "eng";
}
In other words, if there isn't an argument on the lang variable, you can just set it to be eng automatically, and so the first page will default to English every time, unless told otherwise.
Just make the default english and offer an option on the index page to change to french? This, of course, depends on what language most of the visitors speak, which isn't all that hard to figure out with visitor logs.
I would use a neutral URL for entry, such as:
http://example.com/foo/bar
On this page I would do some language negotiation or simply ask the user for the prefered language. Then I can redirect to the language specific URL:
http://example.com/en/foo/bar
what do you think about that solution
<?php
$lang = $_GET['lang'];
if ( empty($lang) ) $lang = 'fra';
header( 'Location: http://acecrodeo.com/new/01-acec.php?lang='.$lang) ;
?>