i'm having a problem with yii which seems very simple but i can't find an appropriate solution for it. I need to do I18N in web page and i'm using yii, i have translations already done, i found that it's possible to easily change language in controller class like that:
class Controller extends CController
{
function init() {
parent::init();
if(isset($_GET['lang'])) {
Yii::app()->language = 'lt';
}
}
}
Everything is ok, but obviously the language parameter is lost when url doesn't contain the language parameter. One way around is adding the parameter in all urls across whole site, but that doesn't seem like a solution.
Is there some more static way of passing the parameter? Maybe some option in UrlManager in yii? Or maybe there is another way of changing the language more dynamically?
And what if you'll use session only when get-request is absent?
But it is still bad idea to show different content on the same url.
if(isset($_GET['lang'])) {
$app->session['language'] = 'lt';
} elseif($app->session->contains('language')) {
$app->language = $app->session['language'];
}
A very simple solution is to use session data to remember the user's language choice across pages:
function init() {
parent::init();
$app = Yii::app();
// If "lang" is specified, remember that
if(isset($_GET['lang'])) {
$app->session['language'] = 'lt';
}
// If we remember a language put it in use
if($app->session->contains('language')) {
$app->language = $app->session['language'];
}
}
You can easy add it as static param to url manager rules. I recommend using urls in form /en/controller/action etc, so first parameter is always language. I'm using this approach for long time and works like a charm.
For details check this answer: https://stackoverflow.com/a/4625710/133408
Related
In my controller i used this way. i want to pass a variable data to my index function of the controller through redirect
$in=1;
redirect(base_url()."home/index/".$in);
and my index function is
function index($in)
{
if($in==1)
{
}
}
But I'm getting some errors like undefined variables.
How can i solve this?
Use session to pass data while redirecting. There are a special method in CodeIgniter to do it called "set_flashdata"
$this->session->set_flashdata('in',1);
redirect("home/index");
Now you may get in at index controller like
function index()
{
$in = $this->session->flashdata('in');
if($in==1)
{
}
}
Remember this data will available only for redirect and lost on next page request. If you need stable data then you can use URL with parameter & GET $this->input->get('param1')
So in the controller you can have in one function :
$in=1;
redirect(base_url()."home/index/".$in);
And in the target function you can access the $in value like this :
$in = $this->uri->segment(3);
if(!is_numeric($in))
{
redirect();
}else{
if($in == 1){
}
}
I put segment(3) because on your example $in is after 2 dashes. But if you have for example this link structure : www.mydomain.com/subdomain/home/index/$in you'll have to use segment(4).
Hope that helps.
Use session to pass data while redirecting.There are two steps
Step 1 (Post Function):
$id = $_POST['id'];
$this->session->set_flashdata('data_name', $id);
redirect('login/form', 'refresh');
Step2 (Redirect Function):
$id_value = $this->session->flashdata('data_name');
If you want to complicate things, here's how:
On your routes.php file under application/config/routes.php, insert the code:
$route['home/index/(:any)'] = 'My_Controller/index/$1';
Then on your controller [My_Controller], do:
function index($in){
if($in==1)
{
...
}
}
Finally, pass any value with redirect:
$in=1;
redirect(base_url()."home/index/".$in);
Keep up the good work!
I appreciate that this is Codeigniter 3 question, but now in 2021 we have Codeigniter 4 and so I hope this will help anyone wondering the same.
CI4 has a new redirect function (which works differently to CI3 and so is not a like for like re-use) but actually comes with the withInput() function which does exactly what is needed.
So to redirect to any URL (non named-routed) you would use:
return redirect()->to($to)->withInput();
In your controller - I emphasise because it cannot be called from libraries or other places.
In the function where you are expecting old data you can helpfully use the new old() function. So if you had a key in your original post of FooBar then you could call old('FooBar'). old() is useful because it also escapes data by default.
If however, like me, you want to see the whole post then old() isn't helpful as the key is required. In that instance (and a bit of a cheat) you can do this instead:
print'<pre>';print_r($_SESSION['_ci_old_input']['post']);print'</pre>';
CI4 uses the same flash data methods behind the scenes that were given in the above answers and so we can just pull out the relevant session data.
To then escape the data simply wrap it in the new esc() function.
More info would be very helpful, as this should be working.
Things you can check:
Is your controller named home.php? Going to redirect(base_url()."home"); shows your home page?
Make your index function public.
public function index($in) {
....
}
Hello.
In Yii1.1 i could make an action in siteController and then using: Yii::app()->controller->createUrl('actionname', array('language'=>'new language to toggle'));
It was possible to me to create hiperlinks with CHTML in index file and when clicked those hiperlinks changed the entire tranlations of the website from Portuguese to other language and all way around.
Now i'm beginning with Yii2 and controller does not have createUrl() anymore. Also the other methods dont work that way. I tried run, runAction, tried with the Url:: class and nothing.
Also, in Yii2 making <?php echo Html::a('Portuguese', Yii::$app->language = "pt"); ?>
Doesn't do anything !!! When clicked the hyperlink does not change the language of the site.
Does anyone know how to create an hiperlink or some other way in Yii 2 that toggles completely the entire website language. I need to have two versions of this website -> English and Portuguese.
I need to perform like this -> when click in the english word it will translate to English, and when click the portuguese word it will change the site to Portuguese language.
Any Ideas ??
Many thanks in advance.
NEW EDIT TO THE QUESTION
I wrote this code in my siteController, and now the sites toggles languages, but only on second mouse click the toggle happens and the content is refreshed. Anybody knows why?
Here are my actions
public function beforeAction($action) {
if (Yii::$app->session->has('lang')) {
Yii::$app->language = Yii::$app->session->get('lang');
} else {
Yii::$app->language = 'us';
}
return parent::beforeAction($action);
}
public function actionLangus(){
Yii::$app->session->set('lang', 'us'); //or $_GET['lang']
return $this->render('index');
}
public function actionLangpt(){
Yii::$app->session->set('lang', 'pt'); //or $_GET['lang']
return $this->render('index');
}
I opted for render('index'), because redirect was not finding the view to display.
Many thanks for a solution...
You can do like below in Yii2:
\yii\helpers\Html::a('Change Language',\yii\helpers\Url::toRoute(['controller/action',['language'=>'NEW_LANGUAGE']]));
\yii\helpers\Html::a('Change Language',['controller/action',['language'=>'NEW_LANGUAGE']]);
Or:
use yii\helpers\Html;
use yii\helpers\Url;
Html::a('Change Language',Url::toRoute(['controller/action',['language'=>'NEW_LANGUAGE']]));
Html::a('Change Language',['controller/action',['language'=>'NEW_LANGUAGE']]);
Then, in your action, you need to do:
//validation
Yii::$app->language= "NEW_LANGIAGE";
// store current language using state or cookie or database
UPDATE
action code:
//please put some validation on $_GET['lang']
Yii::$app->session->set('lang', 'us'); //or $_GET['lang']
$this->redirect('controller/action'); // redirecting user to somewhere
Then in your controller's beforeAction:
public function beforeAction($action) {
if (Yii::$app->session->has('lang')) {
Yii::$app->language = Yii::$app->session->get('lang');
} else {
//or you may want to set lang session, this is just a sample
Yii::$app->language = 'us';
}
return parent::beforeAction($action);
}
By above code, in every action, it checks whether the language is set in session or not. If yes, it changes the language. If not, it sets language to us as default. In your change language action, it just sets the new language, which, is given from $_GET request, into the session. Then it redirects user to another page.
Please note that, this is just a suggestion, others might use different ways, such as creating a bootstrap component, using controller init() method, storing lang into cookie or database and so on.
I'm trying to achieve something so basic in my cakephp-app, that I'm quite surprised I didn't easily find a solution to it...
What I just want to do is to set available links for my app's main navigation depending on the user being logged in or not and if he is, depending on his role (which is stored in the users-table).
So basically a function like this:
if(!$this->request->is('ajax')) {
if(_user_is_not_logged_in_) {
$availableNavItems = array('login','help');
}
else {
if($this->Auth->User('role') == 'user') {
$availableNavItems = array('something','something else','whatever','help','logout');
}
elseif($this->Auth->User('role') == 'admin') {
$availableNavItems = array('something','something else','whatever','admin-tool','user management','help','logout');
}
}
// set available pages for layout
$this->set('availableNavItems',$availableNavItems);
}
In my layout of course I would create a navbar with links to those available pages.
The only question I have - where would I put code like the above? Is there any callback-function I could put in AppController which cakephp calls on every request?
And, what would be a good way to check what I wrote as pseudo-code "_user_is_not_logged_in_" above?
Thanks in advance for any help!
if(_user_is_not_logged_in_) {
could be written as
if(!$this->Auth->user('id')){
And you could put the function in your beforeRender method of your AppController, which executes on every request, right before the view is rendered.
Also of note is the beforeFilter method, which gets called early, before the controller logic executes. You shouldn't need it in this case, but it's worth knowing about.
So I want to make my page to have multi language function, like German, English, and Hungarian. I started to learn OOP in PHP, and now I force myself to use OOP in everything, sure not a good idea, but I try to learn. So this is what I got so far:
<?php
class class_lang {
private $language;
public function __construct() {
$this->language = $_GET['lang'];
}
public function select_lang($var);
return ('language_'.$this->select_lang($var));
}
?>
So what is going on. On my index page i got 3 links (national flags) when i click 1 my class gets the value from the url like this: href="index.php?lang=uk". Now what i am not sure about is how do i make the string: cause my lang files i want to include look like language_uk.php , language_ge.php etc... So i just want to creat that string and pass it back to my index page in a value so i can include then the right file.
If I understand it correctly, this should work:
return 'language_' . $this->language;
try to make public var $language ,
construct could filter and validate the GET var, save the object somewhere (sessions) to interact with object
additional methods you could use are
ChangeLang
SetLang
LoadLangFile
SaveToSession
many other..
(1) In PHP, field members are declared with leading "$", but, later, witouth it, and prefixed with "$this->". So:
$language;
Becomes:
$this->language
(2) Extra, remove the semicolon from the method header:
public function select_lang($var)
{
return ('language_' . $this->language($var));
}
(3) Extra, add a temporally variable to methods that return a value, its not required by syntax, but, will allow you to debug ("ToString"), and avoid a lot of problems:
public function select_lang($var)
{
$Result = ('language_' . $this->language)
return $Result;
}
Cheers.
I am currently working on CMS for a client, and I am going to be using Codeigniter to build on top of, it is only a quick project so I am not looking for a robust solution.
To create pages, I am getting to save the page details and the pull the correct page, based on the slug matching the slug in the mysql table.
My question is however, for this to work, I have to pass this slug from the URL the controller then to the model, this means that I also have too have the controller in the URL which I do not want is it possible to remove the controller from the URL with routes?
so
/page/our-story
becomes
/our-story
Is this possible
I would recommend to do it this way.
Let's say that you have : controller "page" / Method "show"
$route['page/show/:any'] = "$1";
or method is index which I don't recommend, and if you have something like news, add the following.
$route['news/show/:any'] = "news/$1";
That's it.
Yes, certainly. I just recently built a Codeigniter driven CMS myself. The whole purpose of routes is to change how your urls look and function. It helps you break away from the controller/function/argument/argument paradigm and lets you choose how you want your url's to look like.
Create a pages controller in your controllers directory
Place a _remap function inside of it to catch all requests to the controller
If you are using the latest version of CI 2.0 from Bitbucket, then in your routes.php file you can put this at the bottom of the file: $routes['404_override'] = "pages"; and then all calls to controllers that don't exist will be sent to your controller and you then can check for the presence of URL chunks. You should also make pages your default controller value as well.
See my answer for a similar question here from a few months back for example code and working code that I use in my Codeigniter CMS.
Here's the code I used in a recent project to achieve this. I borrowed it from somewhere; can't remember where.
function _remap($method)
{
$param_offset = 2;
// Default to index
if ( ! method_exists($this, $method))
{
// We need one more param
$param_offset = 1;
$method = 'index';
}
// Since all we get is $method, load up everything else in the URI
$params = array_slice($this->uri->rsegment_array(), $param_offset);
// Call the determined method with all params
call_user_func_array(array($this, $method), $params);
}
Then, my index function is where you would put your page function.