Best way to include different languages into a webpage - php

I would like to include a language menu on the top of my webpage where you can select between the languages English (en), Spanish (es) and German (de) (More languages might be added in the future). My website consists of the three pages nav.php, index.php and faq.php.
However, I am not sure about the best way to implement the languages on my website. So far I have come up with the following options:
(1) Create every page of the website in a different language and put it in the same folder:
website/pages/nav-en.php
/nav-es.php
/nav-de.php
/index-en.php
/index-es.php
...
(2) Create every page of the website in a different language and create an own folder for each language:
website/en/nav-en.php
/index-en.php
/faq-en.php
website/es/nav-es.php
/index-es.php
/faq-es.php
....
(3) With the options (1) and (2) described above I see the issue that code changes have to be done for each of the pages manually. Therefore, my solution would be to divide the functional code from the text content and loading the text file depending on the language that is selected in the menu:
website/pages/nav.php
/index.php
/faq.php
website/text-content/nav-text-en.php
/nav-text-es.php
/nav-text-de.php
/index-text-en.php
/index-text-es.php
....
Since I am a newbie in webdeveloping I wanted to ask you:
(a) Are the options described above the only once or is there another (better) way to include different languages on a webpage?
(b) Based on your experiences which option would you recommend?
(c) Is there anything else I need to consider?
Thanks for any advice.

You can use gettext for translation. This way you can have one file with structure and text in the same place for all languages, and translate your strings with an editor (like poedit), which could also be done by a translator. The translator would then only see the strings in one language and have to fill in the translated version, without having to deal with the HTML around it.
There is a shortcut to the gettext() function, _(), so you can write something like
<?=_("Linktext in different languages")?>
It's a bit more work to setup once, but after that, adding additional languages will be a lot easier than having different files with all the structure included, which will quickly become a maintenance nightmare.

(a) Are the options described above the only once or is there another (better) way to include different languages on a webpage?
I think using a $_GET param for both language and content is better way. For example,
index.php?page=faq&lang=en
(b) Based on your experiences which option would you recommend?
Using the power of php language is my advice. You may forget about static HTML website architecture.
(c) Is there anything else I need to consider?
If you're using apache, I suggest to use mod_rewrite. This way each page URL looks better:
index.php/en/faq
instead of
index.php?page=faq&lang=en

Well if you google at localization for PHP you will come up with multiple idea's. Personally I would use gettext. This way you can also format the numbers in the correct format.

My experience so far:
It's a nightmare to improve or even maintain a webpage where different views of the same content are based on different files, e.g. your start-page in english, german and spanish.
Therefore, it is a good approach to decouple the HTML-frame (+ CSS) from the language-dependent text. You can do that by implementing your own ideas ... or you are looking for a php framework which provides such functionality. I'm mainly a Java-guy so I don't know such framework. I guess Laravel and Zend Framework 2 could provide localization. Like others mentioned in the thread gettext also looks like a good way to realize localization in your project.
Hope that helps.

To build a multilangage website with easy maintenance, you can do this way :
1. You create ONE file by langage
en.php // english content
es.php // spanish content
...
2. Each file is an array with the same key, that content ALL the content you need to translate :
<?php
// en.php
$translate = array(
"menu_content" => array(
"home" => "Home page",
"nav" => "Nav page",
...
),
"nav_page_content" => array(
"title" => "Welcome to the nav page",
"content" => "In this page you will find...",
...
),
// same for ALL the content
);
3. Now, I see 2 ways you can add the content of your translation file in your website :
3.1 : You use $_SESSION['lang'] variable or some $_GET['lang'] variable if you have the current langage in your URL (eg. http://www.my-page?lang=en) and you load the php file you need at the begin of your PHP script. Then in your HTML you get the content according to your php array (the same key in ALL langage). For example using my example array for the menu :
<nav>
<ul>
<li id="home"> <?= $translate["menu_content"]["home"]; ?> </li>
<li id="nav"> <?= $translate["menu_content"]["nav"]; ?> </li>
...
</ul>
</nav>
And to change langage, you create a list of your langage and on click you change the $_SESSION['lang'] or $_GET['lang'] value and reload your page with the new php langage content.
3.2 : You can do almost the same without reload the page using $.ajax. The idea is almost the same : you have a list of all the langage of your website with a langage attribute for example :
<ul>
<li data-lg='es'>ES</li>
<li data-lg='en'>EN</li>
...
</ul>
On click, you you get this data-lg value and send it to your Ajax function, calling the php file of the choosen langage :
function changeLangue(lg) {
$.ajax({
type: "POST",
url: lg +".php", // eg. es.php, en.php, etc.
dataType: "json", // you will need to add "echo json_encode($translate);" at the end of your php file to send back JSON content
success: function(response){
// Here your change the content of your website without reloading the page, eg with my nav before:
$("#home").html(response.menu['home']);
$("#nav").html(response.menu['nav']);
...
},
error: function(x,e,t){
manageError(x,e);
}
});
With this method, you will need to change your current langage and rebuild your langage selection too but it's not that hard in JS/jQuery.
I don't know if it's the best way to do it to be honnest but it should work (I did it with the second method to test) and it's easy to add a new langage, you will only have to :
Create a new php file yournewlangage.php with the same array than before and translate the content
Add the yournewlangage to your langage list selection
And that's all if you did it right !
An other idea could be to use a Framework for you website. For example, I'm using Silex right now (micro-framework php), it's like Symfony but lighter and you can use the translation component to help you : https://silex.symfony.com/doc/2.0/providers/translation.html
Framework can help you to win some time if you can use them, take some time to use the best one for what you want to do !
Hope it's clear enought and it helps a little

Related

How to make clean links if I do no know the url

I try to design a web in different languages.
How can make the link that gives a clean url? Some pages are dynamic so, I do not know the url, I am searching for a way to make that links work in any page.
I know I can do this because it works in any page:
<a href='?lang=en'>en</a>
<a href='?lang=fr'>fr</a>
But, how to do that and be able to get a clean url like this?:
myDomain/someFolder/file.php // the default in English
myDomain/fr/someFolder/file.php // fr for French
(Beware that it is not just change fr to en. In English there is no /en/)
I have found that I have tu use a rewrite rule in the htaccess to change from myDomain/someFolder/file.php to myDomain/Folder/file.php?lang=en But this is not the point, my question is different, I ask: how to make clean links in the html if I do not know the url?
What I would do, which is not anywhere as fancy as an .htaccess rewrite tool...
First, I would do something to get the current page name. This can be as simple as:
$pagename = "contactme.html";
Now, I have an array of available languages:
$languages = array('en'=>'English','fr'=>'French','es'=>'Spanish');
With that, I can slap this on the top of every page:
Select your language: <?php
foreach($languages as $ln=>$language)
print " <a href='mysite.com/$ln/$pagename'>$ln</a> ";
That will spit out a list of abbreviations. Can they be little flags (a lot of people like those). Sure. Change $ln in the anchor to <img src='$ln.png' border='0'> and make sure you have all the images. Can they be in a form with a select list? Sure. Make a select list. Add an 'onchange' trigger to the form to reload to the correct URL. Can they be is a super-fancy rotating flash animation? Yes - if you really want to do something that silly.

How to output data after all php is executed?

I am creating breadcrumbs on my simple site.
I have some helper classes. I use them like this (just example):
$Breadcrumbs = new Breadcrumbs();
$Breadcrumbs->add(new Breadcrumb("/", "page1"));
$Breadcrumbs->add(new Breadcrumb("/", "page2"));
$Breadcrumbs->add(new Breadcrumb("/", "page3"));
$breadcrumb->show(); returns this:
<ol class="breadcrumb">
<li>page1</li>
<li>page2</li>
<li class="active">page3</li>
</ol>
So, in my project I have some switch-case constructions in which I include some files.
In this files I am using $breadcrumbs->add(...). This code:
<div class="container body">
<? $Breadcrumbs->show();?>
<?
$page = isset($_GET['page']) ? $_GET['page'] : null;
switch($page):
case "suppliers":
require_once($DOCUMENT_ROOT."/modules/suppliers.php");
break;
default:
require_once($DOCUMENT_ROOT."/modules/default.php");
break;
endswitch;
?>
<? $Breadcrumbs->show();?>
</div>
gives me this result:
Well, it works like it must work. I am using $breadcrumbs->add(...) in require files after I called $breadcrumb->show() first time thats why 1st call returns blank result. 2nd call of show() is after all breadcrumbs are added, so it returns fine result.
The questions is how to output breadcrumbs before switch blocks but with right content. Maybe I need a buffer or idk?
This is a good example of why it is such a good idea to separate out logic from presentation: you have a nice abstraction for crumb links, but can't use it properly because your other code is outputting as it goes along, rather than working with abstract data.
Obviously, you could throw away your current structure and port both logic and display directly into a new framework, but assuming you want to migrate from where you are now, here's one approach:
Create an object or array that represents the "result" of whatever module is called. Replace all current use of echo or ?> with concatenation to a string called something like $results['generic_output']. This is effectively like buffering your output, and is enough to let you use your existing abstractions like $breadcrumbs at any time. At this stage, your "template" would consist mostly of echo $results['generic_output'], plus the boilerplate header and footer which is probably already gathered in one place.
Start breaking down the output into sections. Particularly look for sections which are similar on multiple pages. For instance, if you have a "sidebar" with different content on each page but similar styling, make a $results['sidebar_content'] with just the content of that sidebar; the boilerplate to lay it out can then go into your template, and you've reduced the amount of code duplication.
Make the data you pass to the template increasingly abstract, with the goal of eventually having no HTML outside of the template(s). For instance, maybe the sidebar is made up of panels; you might start with an array of HTML blocks, one for each panel, but then turn it into an array of objects based on the actual data being displayed (say, a special offer, or the customer's current basket), with a set of templates for handling different kinds of panel. Eventually, it should be theoretically possible to build a plain-text version of your site with no HTML, just by changing the template layer, and none of the original modules.
The final step is to separate decisions about what to show from decisions about what to do. Continuing with my imaginary sidebar, your template could always receive the current basket as a general variable for use somewhere on the page, rather than as "sidebar item 1". This allows you to completely separate the actions that led into a page from the output that eventually results.
I would like to stress that this is not the way to a perfect framework, or the definitive solution to your situation, but it's one way of organising existing code (and existing thinking) in the right direction.
In the above, the "templates" could just be a set of PHP files using ?> or echo to produce the output, or it could be a dedicated templating system such as Smarty or Twig. Indeed, the point of the separation is that you could change your mind on that front later, because the result of the code modules would be an array of data to be displayed, which is just what Smarty or Twig would need as input.

opinion on my method for a multi language site

i'm working on my own way of handling a bilingual site. my method should allow proper search engine indexing and will keep everything on one page without external files.
one function would handle which content to display:
<?
function l($en, $fr){
echo ($_GET['lang'] === 'fr') ? $fr : $en ;
}
?>
then the appropriate text will display according to language in URL (/?lang=en)
<h1><? l('welcome!', 'bienvenue!') ?></h1>
for an image this is my solution:
<img src="<? l('hi-en.png', 'hi-fr.png')?>" width="100" height="20">
can anyone name drawbacks to this method if used? is it unusual to have a single function handle language for pages which would include all language content?
The general idea of using a singleton or global function like your l function is very common. You're definitely on the right track!
Your method does have some drawbacks, though:
If you have the same text or image that appears in numerous places in the code, you need to maintain the translation in every place.
Updating or correcting a translation requires wading through code, which is very difficult for inexperienced coders or non-coders (say, if you have a translator helping you).
If you were ever to add a new language, you would have to modify every source file, which would be excruciating. This may be unlikely, but if it ever happened, you'd be rather cross with yourself.
A more typical solution is to have the translations located in a separate file, either as a simple hash or as a structured data format like XML, and then your l function would just look like l('welcome'); the parameter is a key, and l will look up the correct translation in the given language from the separate file.

Apply a class to a <h1> based on the site url

I'm new to PHP and want to apply a specific class to the title of my page depending on what part of the site the viewer is browsing.
For instance, I want to apply the class "blog" to the if the viewer is at domain.com/blog OR domain.com/blog/post-1 so on and so forth BUT apply the class "pics" if they're viewing domain.com/pics or domain.com/pics/gallery-1 etc etc.
I found something that could be modified to serve my needs using javascript here
but I figured seeing as I'm using PHP already, it'd make more sense to keep this sort of thing server side.
As I say, I'm new to PHP. I've experimented with some regular expressions, but to no avail.
EDIT: Sorry not to be more specific in my first post, I am using wordpress as my CMS - this is my first stackoverflow post, I trust you can forgive me :)
<?php
if (substr($_SERVER['REQUEST_URI'], 0,5)=='/pics') {
$h1class='someclass';
}
The it depends on how you're putting the class in the tag, might be like this
?><h1 class="<?php echo $h1class; ?>">...
Rather than putting a class in based on the page, I would suggest having seperate CSS files for home.css, blog.css, whateverelse.css. Of course, these would be in addition to some sort of default.css or site.css or whatever that would contain the styles used across the site.
You can then build a function/method to create the CSS calls in the HTML header. I usually have a "Page" object that builds the actual HTML page, and a "get_css" method that spits out the CSS calls.
It's hard to get more specific without knowing how you currently build pages.
Here is the solution I ended up crafting. Credit to #m.buettner for pointing me towards explode().
<h1 id="title-text" class="
<?php #returns the category as a class
$url = array();
$url = explode('/', get_permalink());
echo $url[3];
?>
mono in-case-404">
SITE
</h1>

Change language on the fly codeigniter

I have a welcome controller, which allows the user to choose a language (en or fr) which then points to it's respective controller (en or fr) so the url looks like this www.xxx.com/en/func/func. I would like so that there can be a link that can change the language, and I would like it to switch language but stay at the same page. Simply grab the corresponding language lines from the proper language files.
Which is the best way to do this?
You should use routing for this, in your routes.php you should add this:
$route['([a-z]{2})/(:any)'] = 'yourdefaulthomecontroller/$2/lang/$1'; // rearrange as you like
Then in your default controller you could find the rsegment and use it against whatever you need.
print_r($this->uri->rsegment_array()); // This will print out the routes
In practical:
if($this->uri->rsegment(3) == 'lang' && $this->uri->rsegment(4))
{
// Do something
}
the easy way is to add to your change language links variables you need to be saved after page reload
so look in your code for all navigation variables and simply add them to your language links
How do you currently achieve the I18N?
Whenever I deal with multiple languages on a site I use parser class as it allows to add multiple languages very easily.
By using that it is quite easy to switch languages by determining language requested in the url.
If by "on the fly" you mean changing the language without realoading the page then that's a whole other thing.

Categories