Php for a bilingual site - php

Is it possible using php, for a user to click on a english/french toggle button, that would then read the current url, and match it to the french version of the page?
Thank you for your time.

When the users clicks the button, populate a session variable with the selected language:
session_start();
$_SESSION['language'] = 'FR'; // Or 'EN', etc
Then use templates to store your language-specific information. When you load the template, include the language code
// Load a template
Template::load( '<page_name>', $_SESSION['language'] );
// Where the `load()` method looks something like this:
public function load( $page_name, $language ) {
// Construct the path to the template
$file_handle = fopen( PATH_TO_TEMPLATES . $language . "/" . $page_name );
// Do something with the template here.
}

Related

WPML changes WordPress language to default when redirecting from login page

I am building a bilingual website using WordPress and WPML(the translation plugin WPML), also to handle login and registration I used Theme my login, however since it's not compatible with WPML, I had to find an alternative (tried clean-login ) but still no luck.
The problem I faced with theme my login; it's not supporting templates for both languages only the English part (the other language is Arabic), while using clean-login you can't modify it's templates (while I needed to add some fields to user registration).
Finally I followed the tutorial in this link to build my own login and registration plugin, the problem I'm facing now is that each time a login is made, I'm being redirected to the user profile (which is the correct behavior) but instead of keeping the same language from the login page, it redirects to the user profile with the default language although I was trying to login from the Arabic login page.
I tried several fixes for the language redirection problem; like trying to modify the locale using wp locale filter through a custom function, or by using a conditional on the $_GET['lang'], unfortunately nothing worked.
An example for the various solutions I tried using the $_GET['lang'] parameter;
setting a public variable ($site_lang) in the custom plugin class:
public $site_lang;
public function __construct() {
global $sitepress;
$current_lang = $sitepress->get_current_language();
if ( isset($_GET['lang']) && $_GET['lang'] == 'ar'){
$this->site_lang = 'ar';
}else{
$this->site_lang = 'en_US';
}
}
Another variation using session through the plugin WP_SESSION
global $sitepress;
$current_lang = $sitepress->get_current_language();
$wp_session = WP_Session::get_instance();
$wp_session['act_lang'] = 'ar';
if (!isset($_GET['lang'])){
$wp_session['act_lang'] = 'en';
}else{
$wp_session['act_lang'] = 'ar';
}
$this->site_lang = $wp_session['act_lang'];
and the redirect on registration error function, which is one of many functions that deals with redirect, I'm putting it here as an example on how I'm using the public variable for redirection
public function maybe_redirect_at_authenticate( $user, $username, $password ) {
if( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
$login_url = ($this->site_lang == 'ar') ? site_url( 'تسجيل-الدخول/?lang=ar' )
: home_url( 'member-login' );
$login_url = add_query_arg( array('login' => $error_codes), $login_url );
wp_redirect( $login_url );
}
}
If anyone has a solution on how to keep the language the same after redirection, I really do appreciate the help.

Using a link and submit button to submit a form

I am working on a website. I would like the website to redirect from index.php to index.php?lang=En.
This is because the site is multi-lingual and the default language needs to be set to English on the home page. I used the header() method to do this but that causes a redirect loop as the site keeps reloading forever.
How can I overcome this barrier?
In your PHP:
<?php
// Default to English if $_GET['lang'] isn't set
$lang = isset($_GET['lang']) ? $_GET['lang'] : 'En';
// If language not in array of available languages, reset to English
if (!in_array($lang, array('En', 'Es', 'Fr'))) {
$lang = 'En';
}
header('Location: index.php?lang=' . $lang);
?>
In your HTML:
English,
Español,
Français
I would do like this:
if(!isset($_GET['lang']) {
header('location: http://www.example.com/index.php?lang=En');
}
Check if the lang parameter exists in the URL, and do the redirect only if it doesn't:
if (!isset($_GET['lang']) {
header('Location: http://www.example.com/index.php?lang=En');
}

Smarty PHP, AbanteCart E-Commerce User Agent Theme

I've been using the open source AbanteCart E-Commerce for selling productus and was wondering if someone knew there was a way to redirect the template for use of a mobile template instead.
i guess the easiest way is hook of all controllers and adding new variable into request (sf) which contains template_text_id... plus using cookie about template mode(desktop or mobile).
/**
* redirect to mobile template if we load page in mobile device
**/
public function onAHook_InitEnd() {
if ( $this->_processHooks() ) return;
$device = $this->baseObject->request->getDeviceType();
if ( !empty($device) && empty( $this->baseObject->request->cookie['abantecart_mobile_redirect'] ) ) {
//set flag that redirect was done
setcookie("abantecart_mobile_redirect", "1", time() + 3600*24);
//set template to mobile
$url = $this->baseObject->html->removeQueryVar($_SERVER['REQUEST_URI'], 'sf');
$url .= '&sf=your_mobile_template_text_id';
header ( 'Location: '. $url );
}
}
private function _processHooks(){
return $this->registry->get('config')->get('config_storefront_template') == 'your_mobile_template_text_id';
}
That variable (sf) processed by engine in core/init.php file and switch desktop template to mobile.

How to structure a dynamic website with Codeigniter

I have some experience with php, but I just recently started learning Codeigniter. I used to have a website with a fixed navigation pane and sidebar, but the main section of the site loaded dynamically based on a Get variable. It was basically
include head.php
include navbar.php
include sidebar.php
include the page requested from the get variable (home, about, contact, etc.)
include footer.php
I liked this because the entire site did not have to reload when the user navigated from page to page.
I can't figure out how do this with Codeiginiter. Should I be using a controller for each page or one controller with a function for each page? Do anyone know of a good tutorial that does something similar? All the tutorials I've seen reload the entire site for every page.
Edit: Essentially I want to do this but with Codeigniter
Since it looks like you want relatively static content, but loaded dynamically you can do with one controller and (maybe) one method in the controller.
To do it with one method, do this in the welcome controller:
public page( $page_id ){
// views/header.php
$this->load->view( "header" );
if( $page_id = "about" ){
$this->load->view("about"); // views/about.php
}
else if( $page_id = "contact" ){
$this->load->view("contact"); // views/contact.php
}
// views/footer.php
$this->load->view("footer");
}
This takes a single get variable and figures out what page to load in between the header and footer.
This way www.yoursite.com/page/about will load the about page, www.yoursite.com/page/contact will load the contact page
Now, if you want to get rid of the /page part, you need to do some URL rerouting in application/config/routes.php
Alternatively you could use several methods in one controller:
public about( ){
// views/header.php
$this->load->view( "header" );
$this->load->view( "about" );
// views/footer.php
$this->load->view("footer");
}
public contact( ){
// views/header.php
$this->load->view( "header" );
$this->load->view( "contact" );
// views/footer.php
$this->load->view("footer");
}
Now your URLs look nicer without routing, but you have to load the header/footer for every page.
do you really like to copy/paste many $this->load->view() to any controller function?
It's a spaghetti code. You can try next: for example we have main.php controller as default controller. This main controller contain main function:
public function index()
{
ob_start();
$this->load->model('mainmodel');
$data = $this->mainmodel->_build_blocks(); //return array with needed blocks (header, menu, content, footer) in correct order
foreach ($data->result_array() as $row) {
$this->load->module($row['block_name']);
$this->name = new $row['block_name'];
$this->name->index();
}
ob_end_flush();
}
So, each other controller also have index() function which can dispatch actions depends on url segments, prepare params etc.
Footer controller as example (I use Smarty as template engine):
public function index()
{
$this->mysmarty->assign('year', date("Y"));
$this->mysmarty->view('footer');
return true;
}
Content controller will have:
public function index()
{
$name = $this->uri->segment(1, 'index');
$act = $this->uri->segment(2, 'index');
$this->load->module($name);
$this->name = new $name;
$pageData = $this->name->_show($act);
if ($pageData)
{
$this->mysmarty->assign($name, $pageData);
}
$this->mysmarty->view($name);
}
Thats mean what if you want to show http://site.name/page/contactus , we do next:
1) main.php start cycle by needed blocks
2) firstly we show header.tpl by header controller
3) then we show menu
4) then we call content controller which parse url, found what he should call _show() function in Page controller and pass action='contactus' to it. _show() function can contain some switch/case construction which show templates depends of action name (contactus.tpl in this case)
5) in the end we show footer template
In such case we have flexible structure. All controllers should have index() functions and all controllers who can be called in content should have _show($act) function. Thats all.
In codeIgniter you can do that like this, you can load different views at the same time from your controller. for example:
for example in your navbar view you have a Contacts button in your menu that would look like this:
<a href='contacts'>Contacts</a>
In your controller:
public function contacts()
{
$this->load->view('header');
$this->load->view('navbar');
$this->load->view('sidebar');
$this->load->view('contacts_view');
$this->load->view('footer');
}
So we're assuming here that you have the following views already that is ready to be loaded (header.php, navbar.php, sidebar.php, contacts_view.php, footer.php).
UPDATE:
you don't need to have $_GET[] request, just provide the method name from your controller in the <a> anchor tag
in codeigniter i using template
first make template file in one folder with header.php, navbar.php, etc.
example : template.php
<?php
echo $this->load->view('header'); //load header
echo $this->load->view('navbar');//load navbar
echo $this->load->view('sidebar');//load sidebar
echo $this->load->view($body); //load dynamic content
echo $this->load->view('footer');//load footer
?>
second in controller
function index( ){
$data['body'] = 'home'; // cal your content
$this->load->view('template', $data);
}

Internationalisation with PHP - order of execution of PHP functions

Hey all,
I am trying to internationalise my website with php. I am very new to PHP!
The index.php starts with this:
<?php session_start(); ?>
<?php include 'api/locale.php'; ?>
<html>
<!-- ... -->
<div><?php loc('foo') ?></div>
The locale.php looks like this:
<?php
if(isset($_GET['lang']) {
$_SESSION['lang'] = $_GET['lang'];
} else {
$_SESSION['lang'] = 'en'; // default value
}
// use the necessary language file
include('/locale/' . $_SESSION['lang'] . '.php');
// get phrase from URL
if (isset($_GET["phrase"]))
loc($_GET["phrase"];);
function loc($phrase)
{
global $lang;
if(array_key_exists($phrase, $lang)) {
echo $lang[$phrase];
} else {
echo $phrase;
}
}
?>
The idea is I want to use the function loc($phrase) to get the content either in German or English. But here is the problem:
If I have the code like this, I always get the english version, because in locale.php I can not get the lang from the URL: $_GET['lang'] is undefined. Therefore, the session language is always set to the default language (en).
However, if I move the session_start(); into the file locale.php, the internationalisation works:
index.php:
<?php include 'api/locale.php'; ?>
<html>
<!-- ... -->
<div><?php loc('foo') ?></div>
locale.php:
<?php
session_start();
if(isset($_GET['lang']) {
$_SESSION['lang'] = $_GET['lang'];
// ... rest the same as above
Why is it like this? Am I doing something conceptually wrong? The problem is I am also using this locale.php in ajax calls to get international content for dynamically generated HTML elements:
function loc(phrase)
{
var locString;
$.ajax({
// force synchronous ajax call, to return with locString
async: false,
// url with to be translated id
url: "api/locale.php?phrase=" + phrase,
// "get" for small data (otherwise post)
method: "get",
// callback function after server has reveiced information
success: function (data)
{
locString = data;
}
});
return locString;
}
So if I call locale.php over and over again with this AJAX call, aren't there new sessions starting over and over again? I am not sure if I designed my functions correctly. I am happy about any comments!
Thank you!
=============== EDIT ===============
ok, I tried a new way now:
session.php
// session starts at this point
session_start();
// internationalisation in EN and DE
$allowedLangs = array('en', 'de');
// check lang-parameter given in URL and set language from there
if(isset($_GET['lang']) && in_array($_GET['lang'], $allowedLangs))
$_SESSION['lang'] = $_GET['lang'];
if(!isset($_SESSION['lang']))
$_SESSION['lang'] = 'en'; // default value
locale.php
// include correct languguage file
$root = realpath($_SERVER["DOCUMENT_ROOT"]) ;
include($root . '/locale/' . $_SESSION['lang'] . '.php');
// get phrase from URL and translate it
if (isset($_GET["phrase"]))
{
$phrase = $_GET["phrase"];
global $lang;
if (array_key_exists($phrase, $lang))
echo $lang[$phrase];
else
echo $phrase;
}
both files get included in index.php
<?php include 'api/session.php'; ?>
<?php include 'api/locale.php'; ?>
However, if I locale a phrase with ajax now, the following error message appears:
Notice: Undefined variable: _SESSION in ... /locale.php on line 4
How can that be? I thought $_SESSION is superglobal ?!?
When you call the version of api/locale.php with the session_start via ajax, not a new but the same session will start, which is the correct behaviour.
Word start maybe confusing you but the session start will supply the information of the current session correctly, not a new one. So nothing to worry about.
Also you may consider looking at
$_SERVER['HTTP_ACCEPT_LANGUAGE']
before starting to ajax ping-pong of the server and client for an initial language quick guess...
For the two versions of your code, it is not a mystery why it works when session_start is
in locale.php.
The cause is:
Your ajax call is not entering your script from index.php, it enters directly to api/locale.php.
If you do not session_start in api/locale.php, the ajax call will enter into a sessionless php invocation.
So it will keep the default value since session data is neither can be fetched or can be recorded.
I think there is something conceptually wrong in your locale.php file.
The fact that you always set $_SESSION['lang'] is a bad smell.
There should be a case when you dont set the value of $_SESSION['lang']and just use the value of$_SESSION['lang']without modifying it.
With your locale file as it is , and your ajax call that does not pass 'lang' as a parameter, you will always get the default language.
But anyway your local.php file should start with session_start(); as explained by ishan.
By the way you should not use 'echo' inside your function loc. Instead return the result and do
echo loc('foo');
It would do the same job, but your loc function would be more reusable.
Hi Marcus I will try to answer your question in the comments.
$_SESSION id indeed a super global. But you need to call session_start() for it to works.
That's why it does not work anymore in locale.php
The problem is that your locale.php file is serving two purposes at the same time.
It should just translate but not be reachable directly from an url.
So you should do something like this :
session.php
`
//here you define a default value. So whatever happens, you know that $_session['lang']
//will always be set.
if(! isset ($_SESSION['lang'] {
$_SESSION['lang'] = 'en'; // default value
}
// internationalisation in EN and DE
$allowedLangs = array('en', 'de');
// check lang-parameter given in URL and set language from there
//if necessary, the default value will be overwritten.
if(isset($_GET['lang']) && in_array($_GET['lang'], $allowedLangs)) {
$_SESSION['lang'] = $_GET['lang'];
}
`translate.php
function getTranslation ($phrase, $lang='en') {
$root = realpath($_SERVER["DOCUMENT_ROOT"]) ;
include($root . '/locale/' . $lang . '.php');
//the array with the phrases and their translations should not be called $lang
//to avoid confusion. Let's call it $translations
if (array_key_exists($phrase, $translations))
return $translations[$phrase];
else
return $phrase;
}
}
locale.php
`
This file is to be called in ajax.
It will works providing $_SESSION['lang'] as already been defined
(in index.php for example). Otherwise you fall back to the default lang.
include 'path_to_translate/translate.php';
session_start();
if(isset($_SESSION['lang'] {
$lang = $_SESSION['lang'];
} else {
$lang = 'en';
}
$phrase = $_GET['phrase'];
echo getTranslation($phrase, $lang);
index.php
session_start();
include 'api/session.php';
include 'path_to_translate/translate.php';
$lang = $_SESSION['lang'];
<some html>
//to translate anything
<?php echo getTranslation($anything, $lang) ?>
</some html>
Hope this will help. Off course I can not test all this code , so their might be some mistake. But that's the general idea.
I tried not to change to much what you' have done. But there is still a problem. You should not define the lang in index.php. If there is a form in your index to choose the lang. Make a call in ajax to set_lang.php. It is not for the index to set the lang in session.

Categories