I am developing a site using php and mysql. I want to know... what's a good way to deal with multi-lingual support? I want a user to be able to select from a drop down and select their language. Then everything (content, buttons, links) except the user-written content is in their language.
What's a good way to approach this? Use a cookie? Session?
Something like this works fine:
Langs.php
<?
// check if language switch as been set at url var
if ($_GET["lang_change"]) {
$_SESSION['session_name']["lang"] = $_GET["lang_change"];
}
// set value to lang for verification
$active_lang = $_SESSION['session_name']["lang"];
// verify $lang content and set proper file to be load
switch ($active_lang) {
case 'prt':
$lang_file = 'prt.php';
break;
case 'gbr':
$lang_file = 'gbr.php';
break;
case 'fra' :
$lang_file = 'fra.php';
break;
case 'esp' :
$lang_file = 'esp.php';
break;
case 'deu' :
$lang_file = 'deu.php';
break;
default:
$lang_file = 'gbr.php';
}
// load proper language file for site presentation
include_once ('$lang_file);
?>
LANG GBR FILE (gbr.php)
define("LANG_PAGETITLE_HOMEPAGE", 'Homepage');
define("LANG_BTN_KNOW_MORE", 'know more');
METHOD TO CHANGE LANGUAGE (url sample)
USE ENG
Basically, you have PHP files with constants, each file with a lang.
On click you set a url var (ex: lang_change = lang).
That will force page reload, and the langs.php file include at top of your index.php will load the selected language...
If you need more explanation about this, leave a comment and I'll send you a working sample!
Ps: session variables shown in this code is usefully for interaction with login systems, or just to avoid having the url parameters...
Save all dynamic content flagged with actual language
Make use of gettext() for buttons, etc. This one is much faster than including .php files with arrays
First of all you have to add all values in each language dynamically.
While adding dynamic content to your website, u can add languageId to each field of your tables in database. And then you can show that content at front end on behalf of that languageId.
I think it's a good idea to consider working with a framework that has internationalization support.
Take a look at this example using CakePHP http://bakery.cakephp.org/articles/view/p28n-the-top-to-bottom-persistent-internationalization-tutorial
I think the following will help you get some basic idea of developing it.
In a website, specially a multilingual website should have user interfaces / templates where hardcoded labels should be linked to variables. These variables should be loaded with correct language values. This can be done easily by including the language file containing the values in that specific language. You can have as many language files in a folder.
You will need to write a script in php, as whenever the user selects the language from the drop down, the page can reload with a language session. Another php script to fetch the selected language inside this session data and include the relevant language file inside the template/UI.
The same approach can be used in fetching content data from a table, where in all MySQL queries, you can use an additional lookup for language type from the content table. so that that file will be loaded.
SELECT * FROM posts WHERE lang='en' AND featured = 1
In many cases, the languages require HTML and CSS to be set accordingly to make the language render perfectly inside the browser. This means, you can also define language inside the HTML and in CSS define the fonts and directions (right to left or left to right).
I am recommending you to read the following in order to get more information on how to do it.
http://www.stylusinc.com/website/multilanguage_support.htm
Related
I'm having a 2 issues with my website.
It's a multi language one (german, english).
I always kept the translations in an XML document like this
<?xml version="1.0" encoding="utf-8"?>
<root>
<les>
<en>Lesson</en>
<de>Lektion</de>
</les>
Then I converted those XML vars into php ones and echo'd them where needed like this
$xml=simplexml_load_file("langindex.xml") or die("xml not found!");
$les = $xml->les->$lang;
<?php echo $les;?>
Problem 1 is that no language is set as default when I open the Website so I always have to select a language first, even though I included that !isset. If I don't select anything, some images will be streched and it gives me the error that no language is set.
<?php
session_start();
$page = 0;
$lang = $_GET['lang'];
$langArray = array('en','de');
$found = false;
if(in_array($lang, $langArray))
$found = true;
if(!$found)
$lang = 'en';
if(!isset($_SESSION['lang']))
$_SESSION['lang'] = 'en';
if(isset($_GET['lang']) && in_array($_GET['lang'], array('en', 'de')))
$_SESSION['lang'] = $_GET['lang'];
include '../nihongo/php/dbconnect.php';
My language switch works with a simple <a href="?lang=X"> and that ?lang=X will be shown in the URL as well.
Enough of that.
Since XML is pretty inpractical I wanted to switch the whole thing up to an SQL database.
I've created a table with the columns ID, german and english and connected the db sucessfully.
Now I want PHP to tell SQL to get only the text of the session language with a select like this for example.
SELECT german FROM texts WHERE ID = '1'
SELECT english FROM texts WHERE ID = '2'
My problem is that I really don't know how to do that with PHP.
I would think that I'd either have to throw a PHP var into the statement somehow, or select the whole row and let PHP decide which one should be displayed.
Every advice/suggestion is welcome!
Thanks in advance!
I like the way OpenCart implemented this, because it's simple and doesn't add additional calls to the DB. Take a look at their implementation. You learn a lot investigating and learning from Open Source projects.
They have a php script per language and module with an array that contains all the strings. It just include or load the scripts to get access to the strings, for example: en-gb. Loading a string by its key with this method:
language->get('heading_title');
I am trying to fetch all language files data and store them in array. But I am only able to get default language data.
I need all language data to sync them in another files. So far I have tried following code,
public function SyncJsLanguageFile($Language) {
//I need German (de) and other data as well data
$this->lang->load('translate','de');
//But I can only get default language data. So I think above line is not working.
$LanguageMessage = $this->lang->language;
echo "<pre>";
print_r($LanguageMessage);
die;
}
I don't want to change default language, I just need all language data in array for specific purpose. I should not change Site default language.
Please help me out here.
I have tried,
$data = $this->lang->load('translate','de', TRUE);
but it is not working. :(
Please do these steps
//load helper for language
$this->load->helper('language');
//mytest is the language file in english folder
//application\language\english\mytest_lang.php
$this->lang->load('mytest','english');// filename, folder name in
//fetch all the data in your custom $all_lang_array variable
$all_lang_array=$this->lang->language;
//display or test the data.
print_r( $all_lang_array);
I've saved a product name in my DB with two language (En & Fr)
how can i load them differently by just changing the url
for example
localhost/mysite/en/products/
loads the "en_name" out of my table
and
localhost/mysite/fr/products/
loads the "fr_name" for me?
The language library is used if you want to store the text in different languages in a file (it will be included in the page) and not in a database. So if the language text is stored in the database, you want to check the method responsible for checking the url segment to check if the url contains the en or the fr and load the corresponding language.
So the method to use is:
$this->uri->segment(n)
More info on how to use it:
https://www.codeigniter.com/user_guide/libraries/uri.html
and your condition should be something like:
Edit
if($this->uri->segment(1) == "fr"){
$this->session->set_userdata('lang', 'fr');
}else{
$this->session->set_userdata('lang', 'en');
}
Now you can easily check for the language selected from the model (db files) by checking the value of the lang Session
I think the simplest method may be to pass the uri segment to the where clause of the query.
https://www.codeigniter.com/user_guide/libraries/uri.html
https://www.codeigniter.com/user_guide/database/query_builder.html?highlight=select#selecting-data
Something like:
$lang = $this-uri->segment(3);
$this->db->where('language', $lang);
$this->db->get('table');
i finally did it with this CI extension i18n and here is my code:
$lang = $this->uri->segment(1);
echo $prodct[$lang."_name"];
so now if i enter my url like this
localhost/mysite/en/products/
it will get those fields from DB which is like "en_name" ,
same goes for "fr" too.
One solution to automatically building navigation for a site is by scanning a folder for documents like this:
foreach(glob('pages/*.pg.php') as $_SITE_NAV_filePath):
$_SITE_NAV_filePath = explode('.pg',pathinfo($_SITE_NAV_filePath,PATHINFO_FILENAME));
$_SITE_NAV_fileName = $_SITE_NAV_filePath[0];
$_SITE_NAV_qv = preg_replace('/([A-Z])/','-$1',$_SITE_NAV_fileName); $_SITE_NAV_qv = trim($_SITE_NAV_qv,'-');
$_SITE_NAV_name = preg_replace('/([A-Z])/',' $1',$_SITE_NAV_fileName);
?>
<li><?=$_SITE_NAV_name?></li>
<?php
endforeach;
This code will turn "AnAwesomePage.pg.php" into a menu item like this :
<li>An Awesome Page</li>
This might be bad practice (?).
Anyway; I don't use this method very often since most of the time the sites have a database, and with that comes better solutions...
But my question is this:
Is there a way to prefix the filename with a integer followed by and underscore (3_AnAwesomePage.pg.php), for sorting order purposes, and pass it somehow to the destination page outside of the querystring and without any async javascript?
I could just explode the filename once again on "_" to get the sort order and store it somewhere, somehow?
This is the code for handeling the page query request:
$_SITE_PAGE['qv'] = $_GET['page'];
if (empty($_SITE_PAGE['qv'])){ $_SITE_PAGE['qv'] = explode('-','Home'); }
else { $_SITE_PAGE['qv'] = explode('-',$_GET['page']); }
$_SITE_PAGE['file'] = 'pages/'.implode($_SITE_PAGE['qv']).'.pg.php';
This code turns "An-Awesome-Page" back into "AnAwesomePage.pg.php" so it's possible to include it with php.
But with a prefix, it's not so easy.
The probliem is; Now there's no way to know what prefix number there was before since it has been stripped away from the query string. So I need to send it somehow along in the "background".
One very bad solution I came up with was to transform the navigation link into a form button and just _POST the prefix interger along with the form. At fist it sounded like a nice solution, but then I realized that once a user refreshes their page, it didn't look very good. And after all, that's not what forms are for either...
Any good solutions out there?
Or some other and better way for dealing with this?
There are two ways to keep that number saved, you can use cookies or php session variables.
But in this case, if user first enter the url in the browser or in a new browser, then he should be taken to default number.
Like you have:
1_first-page.php
2_first-page.php
3_first-page.php
If user enter the url like: domain.com/?page=first-page, you have to take him to 1_first-page.php to any number which you want to be default.
I wanted some suggestions from someone with experience in php.
I am making a website in php which will have 4 kinds of users :
1. guest(unregistered),
2. registered,
3. registered with special privilages,
4. admins
So the same page will be visible differently to all four of them.
Right now I am doing that by using if conditions.
In every page, I am checking the role of the user and then using many if statements to display the page accordingly.
It makes the code very big and untidy and I have to check conditions again and again in all the pages.
Is there a better way to do this?
How is this done in big professional websites?
Extended Question:
What is the most optimal way to do the same using a MVC framework like kohana 3.1? Does it have anything to do with acl?
It really depends on what you need.
For example if the page has big part that change completely, what I would suggest is to create different templates and include them depending on their "permissions"
$permission = $_SESSION['type_user'];
include '/path/to/file/with/permission/'.$permission.'/tpl.html';
and have something in the page similar to
<?php
//inside include.php you have the line similar to
//$permission = isset($_SESSION['type_user']) && $_SESSION['type_user']!=''?$_SESSION['type_user']:'common';
require_once '/mast/config/include.php';
include '/path/to/file/with/permission/common/header.html';
include '/path/to/file/with/permission/'.$permission.'/tpl_1.html';
include '/path/to/file/with/permission/common/tpl_2.html';
include '/path/to/file/with/permission/'.$permission.'/tpl_3.html';
include '/path/to/file/with/permission/common/footer.html';
?>
if the script is full of small parts like "show this text", or "show this button", you can create a function that will check the permissions for you
<?php
function can_user($action, $what){
switch($action){
case 'write':
return $your_current_if_on_what;
break;
case 'read':
default:
return $your_current_if_on_what;
break;
}
}
?>
and the template will look like:
[my html]
<?=can_user('read','button')?'My Button':''?>
[my html]
As a rule of thumb, if a piece of code is used more than 2 times, it needs to be put in a function/file separately, so if you have many "IFS" you need to create a function