Jump to content

Ideas toward my language selection php code please?


Bottyz

Recommended Posts

Hi all,

 

I have been considering different ways of making a language selection script or snippet that would work with my site. And am just a little bit stuck with one part.

 

The scenario:

 

I have a site which uses a global php navigation file, which is included into each page using the 'include()' function. The languages selection div (with flag icons), is stored within this file. For this example, I have the english and french languages to select from....

 

When a user visits the website the pages are all in english as default. But when they click on the french flag I want the user to then be sent to a duplicated page (same as the current page, wherever they are) with the french text. I plan on duplicating all of the pages i want available in the alternate language and instead of being just index.php or contactus.php I'll rename them with '_fr' such as index_fr.php and contactus_fr.php

 

What i'm stuck with is making the script pick up the current page and then add the _fr part to the middle of the href link.  :shrug:

 

I know you can pick up the current page using:

substr(strrchr($_SERVER['PHP_SELF'], "/"), 1);

but how to I change it so that it would make this add the _fr?  :confused:

 

As always, any help would be great!!

 

Cheers all.

Link to comment
Share on other sites

Rather than having separate pages for each languages, you're better off storing the translations in an include (or many depending on the size of your site), and calling these from the index page.

 

So for example, you could have the following files:

 

/lang/en/index.php

<?php 
define('WELCOME_MESSAGE', 'Hello!');
?>

 

/lang/fr/index.php

<?php 
define('WELCOME_MESSAGE', 'Bonjour!');
?>

 

Then your index.php in the root would look something like this (well, it'll look a bit more texty than this, but you should get the idea):

<?php
include '/lang/' . $language . '/index.php';
?>
<html>
<body>
<div><?php echo( WELCOME_MESSAGE ); ?></div>
</body>
</html>

 

The reason to do it like this is to keep your structure and data separate - if you have multiple files for each language, then if you change the html you have to maintain the files for every language. This method is far easier to maintain, and more reliable.

Link to comment
Share on other sites

I'd definitely take an approach along the lines of spambadger's suggestion, but there's many ways of doing it. Think about when you make a structural change  to the HTML and have to make the same updates multiple times; could become a very tedious task if you decide to add even more languages later.

 

For future reference by the way, instead of:

 

substr(strrchr($_SERVER['PHP_SELF'], "/"), 1);

You can just use basename on $_SEVER['PHP_SELF'].

Link to comment
Share on other sites

Rather than having separate pages for each languages, you're better off storing the translations in an include (or many depending on the size of your site), and calling these from the index page.

 

So for example, you could have the following files:

 

/lang/en/index.php

<?php 
define('WELCOME_MESSAGE', 'Hello!');
?>

 

/lang/fr/index.php

<?php 
define('WELCOME_MESSAGE', 'Bonjour!');
?>

 

Then your index.php in the root would look something like this (well, it'll look a bit more texty than this, but you should get the idea):

<?php
include '/lang/' . $language . '/index.php';
?>
<html>
<body>
<div><?php echo( WELCOME_MESSAGE ); ?></div>
</body>
</html>

 

The reason to do it like this is to keep your structure and data separate - if you have multiple files for each language, then if you change the html you have to maintain the files for every language. This method is far easier to maintain, and more reliable.

 

Thats a much better idea I agree. Thanks!

 

One question... What would code would I need to put in the language selection link? And would this still work with the search engines? I mean with the text not actually within the page itself?

 

Cheers Guys!! :)

Link to comment
Share on other sites

 

So there could be problems using the suggestion above? SEO is quite important for the site i'm maintaining. So does this mean my original idea would cause the least problems but would be more of a tedious job to maintain? I don't really wanna go down the route of having multiple urls (fr.website.com and so on) for each language.

 

So the question remains... any ideas on making the

basename($_SERVER['PHP_SELF'])

add the _FR?

Link to comment
Share on other sites

No it's not a problem, if you do it right.

 

You also don't need to have multiple pages, you could for example use mod_rewrite to turn a request like /en/page_name.php into page_name.php?lang=en.

Link to comment
Share on other sites

Right, ok. I think I understand a bit more.

 

So if I were to use the defines file suggestion and the following code:

 

if (isset($lang)) {
include('/lang/' . $lang . '/index.php');
} else {
        // default to english
$lang = 'en';
include('/lang/' . $lang . '/index.php');
}

 

at the beginning of every page, along with the language selection links that use the following:

 

index.php?lang=en

 

it should work?

Link to comment
Share on other sites

I don't know if I'll be any help here, but I can tell you how I'm coding a current pet project with multilingual support. It's basically the same idea as above, but instead of using the define construct, I'm using arrays.

 

For each class that I load, it has three folders associated with it.

i.e

$class/$classfile.class.php; //the class file itself, which includes the following files.
$class/lang/$locale.php; //if it's english $locale would be en
$class/html/index.html.php; //this includes blocks and maybe a few other files for templating.
$class/lib/$extra.class.php; //any extra libraries or classes I might need.

 

I'm not sure if that's exactly a good way to be doing things, as I am still kind of new to laying out directory structures and classes and all that. in my locale files, I have arrays set up like below:

$aPhrases = array('some_phrase' => 'Some phrase here!',
                              'another_phrase' => 'This is another phrase);

and I just call them all together in the constructing of the blocks and pages to be cached later on.

 

Link to comment
Share on other sites

A 'search engine friendly' URL (i.e. /en/index.php) would be better, but yeah pretty much.

 

Your code's on the right track, but you leave your file system a little vulnerable. You need to check that the entered language is actually valid:

 

$valid_langs = array('en', 'fr');

if (isset($lang) && in_array($lang, $valid_langs))
{
    // ...

 

You'll probably want to store that array within the global file you mentioned before. I'm also assuming you're going to declare $lang else-where in the code (and not rely on register globals)?

Link to comment
Share on other sites

Yes, I'll be defining it elsewhere in code and not using register globals. I regular php.net in spare time for reading material. :)

In fact, I have it disabled in my php.ini file.

 

Anyhow, thanks for the tip on the search engine friendly urls, I will definitely implement that idea!

Link to comment
Share on other sites

Ok a bit closer still :) Thanks for the suggestion guys.

 

Hows this look?

 

session_start();

// language code
$valid_langs = array('en', 'fr');

if (isset($_SESSION['lang']) && in_array($_SESSION['lang'], $valid_langs)) {
include('/lang/' . $lang . '/index.php'); 
} else {
$_SESSION['lang'] = 'en';
include('/lang/' . $lang . '/index.php'); 
}

 

I've switched to session variables so that the current language can be kept... Not sure if there is a better method than that?

 

Now, for the language links, how could i make them so that they point to the page they are currently on but with the correct language directory selected? Could i do the following?

 

<a href="<?php $_SESSION['lang'] = 'fr'; header("Location: basename($_SERVER['PHP_SELF'])"); ?>">French</a>

 

Would that work? I'm not that polished on php code and whats allowed from within hrefs!

 

The above would set the session variable and reload the page, thus loading the alternative language. This would also allow me to keep my urls the same for all the languages... for example, www.website.com/index.php would stay the same for every language but load the english as default.

Link to comment
Share on other sites

You don't want to primarily use a session variable. Remember that you need to be passing this parameter *every time* in order for search engines to know the difference, which means you should always have $_GET['lang'] available. Plus if the user changes the language you want it to instantly update. In the situation where it's not passed (for whatever reason) then you can use the session variable, just to ensure the user doesn't suddenly get a different language..

 

Try something like:

 

if (!empty($_GET['lang']))
{
    // primarily look for the lang parameter
    $lang = $_GET['lang'];
}
elseif (!empty($_SESSION['lang']))
{
    // if not look for the session lang
    $lang = $_SESSION['lang'];
}

// check if $lang is set and valid
if (isset($lang) && in_array($lang, $valid_langs))
{
    require '/lang/' . $lang . '/index.php';

    // set session lang for later
    $_SESSION['lang'] = $lang;
}
else
{
    // else use default
    require '/lang/en/index.php';
}

Link to comment
Share on other sites

To make things easier you may also want to define a kind of "HREF_BASE" constant within your global file, so that at the start of links you can use it without having to worry about the structure of the lang param. So for example:

 

define('HREF_BASE', 'path/to/site/' . $lang);

 

You could then use that within your links like:

 

<a href="<?php echo HREF_BASE; ?>/my_file.php?normal=parameters">...</a>

 

The output of the href being: path/to/site/en/my_file.php?normal=parameters -- this is assuming you're going to use mod_rewrite to create the search engine friendly URLs?

Link to comment
Share on other sites

To make things easier you may also want to define a kind of "HREF_BASE" constant within your global file, so that at the start of links you can use it without having to worry about the structure of the lang param. So for example:

 

define('HREF_BASE', 'path/to/site/' . $lang);

 

You could then use that within your links like:

 

<a href="<?php echo HREF_BASE; ?>/my_file.php?normal=parameters">...</a>

 

The output of the href being: path/to/site/en/my_file.php?normal=parameters -- this is assuming you're going to use mod_rewrite to create the search engine friendly URLs?

 

OK, i'm a bit lost now.

 

I can't see how:

<a href="<?php echo HREF_BASE; ?>/my_file.php?normal=parameters">...</a>

 

will direct the user to the current page in another language? This language selection is loaded by every page exactly the same so i can't set the constant my_file.php or index.php, etc otherwise it will redirect to just index.php for example. For the user to stay on the current page i'd have to use the basename() along with lang?=en would i not?

 

I'm not sure how this would work :S

 

Link to comment
Share on other sites

Sorry, I thought you meant for regular links. Thinking about it then, you may want 2 constants:

 

define('HREF_BASE', '/path');
define('LANG_BASE', HREF_BASE . '/' . $lang);

 

HREF_BASE containing the path to your site with no language specification. LANG_BASE would be what you could use for normal links. Then to switch the language, you could use a function like below to return the current URL with the modified language param:

 

function switchLangHref($lang)
{
    $href = HREF_BASE . '/' . $lang . '/' . basename($_SERVER['PHP_SELF']);

    if (!empty($_SERVER['QUERY_STRING']))
    {
        $href .= '?' . $_SERVER['QUERY_STRING'];
    }

    return $href;
}

 

So you'd call it like:

 

<a href="<?php echo switchLangHref('fr'); ?>">Switch to French</a>

 

 

I weren't implying you should do it this way, it's just with you already using constants for the language files, I figured this is probably the most fitting. There's loads of different ways this can be done...

Link to comment
Share on other sites

Ok then,

 

So using a similar code to the one you supplied above:

 

<?php
define('LANG_BASE', '/' . $lang);
define('THIS_FILE', 'http://www.website.com/' . basename($_SERVER['PHP_SELF']));

function switchLangHref($lang)
{
    $href = '/' . $lang . '/' . basename($_SERVER['PHP_SELF']);

    if (!empty($_SERVER['QUERY_STRING']))
    {
        $href .= '?' . $_SERVER['QUERY_STRING'];
    }

    return $href;
}
?>
<div id="language">
Select Language: 
<a href="<?php echo THIS_FILE; ?>"><img src="images/gb.png" alt="English"></a> 
<a href="<?php echo switchLangHref('fr'); ?>"><img src="images/fr.png" alt="Fran&#231;ais"></a> 
<a href="<?php echo switchLangHref('de'); ?>"><img src="images/de.png" alt="Deutsch"></a> 
<a href="<?php echo switchLangHref('es'); ?>"><img src="images/es.png" alt="Espa&#241;ol"></a>
</div>

 

I can keep the english versions of the files such as: http://www.website.com/index.php and then have a directory of duplicated files for the other languages such as: http://www.website.com/fr/index.php.

 

I can't see an easy way of using defines and loading the different languages within a single page as first suggested, that would still be search engine friendly. Additionally, this way i am able to keep my existing english file structure, I don't need to update anything in the search engines and I don't need the 'GET' param as I can link to all the languaged pages from within the languaged pages. It does make more work for me though in keeping everything upto date and editing.

 

Is this right? Or am I still going about it in the worst way possible?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.