I would like to add a language code segment to my URIs in CodeIgniter, but I'd like to somehow — possibly with routing — force the browser to stop interpreting a language code as a path.
I haven't yet successfully implemented any of the i18n libraries in my CodeIgniter install, and I'm fairly certain my problem is simple enough to solve without a library anyway.
The method I had in mind was simply to load the appropriate language files respective of the language code that appears in the URI.
For example
http://example.com/about // Default language
http://example.com/sv/about // Load Swedish language
Here's the controller logic:
<?php
// ** Update **
// The following updated code works, as long as the language code appears
// at the end of the URI, e.g, http://example.com/about/sv
//
// Ideally, I would like the language code segment to always appear first.
//
// There is also the problem of keeping the language selected while
// navigating around the site…
class Pages extends CI_Controller {
public function view ($page = 'home') {
if (!file_exists('application/views/pages/'.$page.'.php'))
show_404();
$uri = explode("/", $_SERVER['REQUEST_URI']);
$lang_code = end($uri);
$data['title'] = $lang_code;
switch ($lang_code) {
case "sv": $the_language = "swedish"; break;
case "no": $the_language = "norwegian"; break;
default: $the_language = "english";
}
$this->lang->load('general',$the_language);
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/footer', $data);
}
}
?>
Am I going about this the wrong way? If so, why? Please avoid canned responses.
I would go with CI routing:
$route['([a-z]+)/([a-z]+)'] = "pages/view/$2";
Then, your controller would look something like this:
<?php if (! defined('BASEPATH')) exit('No direct script access');
class Pages extends CI_Controller {
function __construct() {
parent::__construct();
$this->language = $this->uri->segment(1);
}
function view($page = 'home')
{
/* other stuff */
$this->lang->load('general',$this->language);
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/footer', $data);
}
}
Related
I'm re-writing an application previously written in CodeIgniter framework, my customer want have an independent app and a pure php code. Anyway don't tell me not to reinvent the wheel because I already know that my client is wrong. We come to the problem.
I'm looking for a simple Route class that allow me to call any files from any location. I found this simple and powerfull class, this is the repository.
I've implemented it in my project, copy the route.php file inside the index location and change my .htaccess as the documentation says. Instead of all, this is the structure of my project:
/ PUBLIC_HTML
/ application
/ controllers
/backend.php
/user.php
/ helpers
/ models
/ views
/backend
/backend.php
/calendar.php
/user
/users.php
/panel.php
/ assets
/ files used by frontend...
/ system
/ configuration
/ constant
/ .htaccess
/ index.php
/ route.php
when the applicationi is started from the index.php the configuration file is included for establish the connection with the database. In the same configuration file I've imported the route.php. Now my index.php page is very simple, like this:
// Check if the session is set
if(isset($_SESSION['user_info']['id_roles']))
{
switch($_SESSION['user_info']['id_roles'])
{
case 1: //Admin
$route->add('/application/controllers/backend', 'index');
$route->submit();
break;
case 2: //Provider
$route->add('/application/controllers/backend');
$route->submit();
break;
case 3: //Customer
$route->add('/application/controllers/appointments');
$route->submit();
break;
}
}
else
{
// Session isn't set, so I redirect user to login page
header('Location: application/views/user/login.php');
exit; // stop
}
so if the session is set I redirect the user type to the correct location, against, if isn't set I show the login page. The login page simply valorize the session variable, if the response is success the user is redirected again to the index page.
The problem now is that, for example when the admin is logged (so case 1), the route class doesn't valorize the $uri, a bit example:
public function submit()
{
$uri = isset($_REQUEST['uri']) ? $_REQUEST['uri'] : '/';
$uri = trim($uri, $this->_trim);
$replacementValues = array();
// Iterate on the list of URI
foreach($this->_listUri as $listKey => $listUri)
{
// Looking for a match..
if(preg_match("#^$listUri$#", $uri))
{
// Replace the values
$realUri = explode('/', $uri);
$fakeUri = explode('/', $listUri);
// Get value with .+ with real URI value
foreach($fakeUri as $key => $value)
{
if ($value == '.+')
{
$replacementValues[] = $realUri[$key];
}
}
// Pass array arguments..
call_user_func_array($this->_listCall[$listKey], $replacementValues);
}
}
}
check the full class here.
the $uri variable should be valorized with the current uri of the server but I tried with a var_dump and I get an empty value.Then the match condition is never invoked, and the correct file isn't displayed. I don't know why, I just want to understand why it is not working, I'm probably doing something wrong, someone can help me understand?
Completing the example of the admin redirect, I want to show only what is contained in the backend.php, which should be loaded from the route.
<?php
session_start();
class Backend
{
// Construct of class
public function __construct()
{
}
// Display the main backend page
public function index($appointment_hash = '')
{
$_SESSION['user_info']['hash'] = $appointment_hash;
$_SESSION['user_info']['dest_url'] = SystemConfiguration::$base_url . "backend";
// some content..
}
...
So how you can see, I simply want call the index function of the backend controller when I call ->add() for add the url of the controller to call, and ->submit() to perform the operation.
What am I doing wrong?
UPDATE - Router request task
First I updated the stack of my application.
I think at this point it's best to ask your expert advice on which OpenSource Router allow me to implement this tasks:
1. Import controller
Import all controllers that are contained in my folder called controllers. Once you imported I will simply call the instance of the router, and call up a specific function of the controller loaded. Example:
$router->backend->index();
where index(); It represents the function of controller called backend.
This must be done in my entire application. Also I would make sure that we can bring up the function also via the URL, in particular, if I insert this url:
localhost/application/controllers/backend/index
I can call the same function simply referring url.
2. Requests ajax
Delivery My Router must be able to run ajax requests from javascript, especially if I use this code:
$('#login-form').submit(function(event)
{
var postUrl = GlobalVariables.baseUrl + 'user/ajax_check_login';
var postData =
{
'username': $('#username').val(),
'password': $('#password').val()
};
$('.alert').addClass('hidden');
$.post(postUrl, postData, function(response)
{
I want to call the user function ajax_check_login.
contained in the controller user, imagine GlobalVariables.baseUrl, what is... How can we think is the url of the base application that can obviously vary.
Note that my Controller function return a json format.
3. Load view
in my application there is the view, which are saved in .php, but containing html file, an example of view (previously written in CodeIgniter) pul you find here.
I want to be able to call a view and show the new user html markup. I also need to call also more views at the same instant, for example at times I divide the body into:
header, body, footer
To simplify the understanding of what $this refers to in a view, since a view is "loaded" by a controller method, the view is still run in the same scope as that method, meaning $this can have a different context depending on which class loaded it.
For example:
class Controller1 extends CI_Controller {}
In any view file loaded in this example controller, $this refers specifically to the Controller1 class, which can access CI_Controller public and protected properties/methods as well (like the Loader or Input classes, which are assigned to the load and input properties of CI_Controller) since it extends that class.
Controllers are still just plain old PHP classes. If I were to do this:
class Controller1 extends CI_Controller {
$this->foobar = 'Hello';
}
class Controller2 extends CI_Controller {
$this->foobar = 'World';
}
...if we load the same view file in any method of either of these controllers, using $this->foobar in that view file will return a different value.
But this for now it's not important, I just want to be as clear as possible.
I start a bount and lose all my rep, but I really want to get help in this and learn.
You need to look at the index.php provided with the Router as an example. You'll see how to set the routes:
you always have to have 2 arguments: 1. uri, 2. function
according to the example the function has to be not the function name 'index', but a function body function(){...}. Maybe reference would work as well.
Routing IMHO should be not dependant on session (though it could be, but that's not the usual way to do)
instead of $router->backend->index();, I will have a common block of code at the end of the file so you don't have to copy&paste the code many times.
I'll show you with backend in your way, and then with appointments how could you make it general. So you should make your routes something like:
<?php
session_start();
include 'route.php';
$phpClass = false;
$view = false;
$func = false;
$route = new Route();
if(isset($_SESSION['user_info']) && isset($_SESSION['user_info']['id_roles'])) {
$route->add('/application/controllers/backend', function(){
echo 'You are now at backend page, and the role is ';
switch($_SESSION['user_info']['id_roles']) {
case 1: echo 'Admin'; break;
case 2: echo 'Provider'; break;
case 3: echo 'Customer'; break;
}
include 'backend.php';
$backend = new Backend();
$backend->index(/* I don't know what 'hash' could be */);
});
// more general case:
$route->add('/application/controllers/appointments', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'index'; // default is index, if it wasn't given on the url
});
$route->add('/application/controllers/appointments/add', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'add';
});
$route->add('/application/controllers/appointments/delete', function(){
// we only set the global $phpClass variable, and the rest is common, see below
global $phpClass, $func;
$phpClass = 'Appointements';
$func = 'delete';
});
$route->add('/application/controllers/foo', function(){
global $phpClass;
$phpClass = 'Foo';
});
$route->add('/application/controllers/bar', function(){
global $phpClass;
$phpClass = 'Bar';
});
$route->add('/application/views/bar', function(){
global $phpClass, $view;
$phpClass = 'View';
$func = 'show';
$view = 'bar.php';
});
$route->submit();
} else {
// Session isn't set, so I redirect user to login page
header('Location: /application/views/user/login.php');
exit; // stop
}
if ($phpClass === false || $func === false) {
die("You have to have both controller and function un the url");
}
// if we got here it means we're in the common case
// include the necessary controller. If you want you can
// include all of them at the top of the php and remove this line
include 'application/controllers/' . strtolower($phpClass) . '.php';
$controller = new $phpClass();
// this is instead of `$router->backend->index();`:
$controller->$func(/*$hash*/);
// I don't know what '$hash' could be, maybe javascript could send it via ajax
?>
controllers/view.php:
class View {
public function show() {
global $view;
include 'application/views/' . $view;
}
// here you'll need to have all the things that any of
// your views access as $this->bar :
$config = new stdClass(...);
$array = array();
function get_lang() {global $lang; return $lang;}
//...
}
Example of json response in controllers/user.php:
class User {
public function logged_in() {
$username = isset($_SESSION) && isset($_SESSION['username']) ? $_SESSION['username'] : false;
$response = array(
'success' => $username !== false ? 'OK' : 'ERROR',
'username' => $username
);
echo json_encode($response);
}
}
I'm new to CI, I barely managed to start my own website and had it running for a while now, I had all the views structure as the CI guide, but then I want to put a php file called igniel.php inside a folder called "vcard" inside the pages folder.
The problem is, when I try to load it using a full path like :
http://example.com/application/views/pages/vcard/igniel.php
its showing up nicely, but once I use
http://example.com/igniel (without the php)
it will show a 404 error.
here is my Pages.php content :
<?php
class Pages extends CI_Controller {
public function view($page = 'home')
{
if ( ! file_exists(APPPATH.'/views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header');
$this->load->view('templates/nav');
$this->load->view('pages/'.$page);
$this->load->view('templates/footer');
}
}
and here is my routes.php content :
$route['default_controller'] = 'pages/view';
$route['(:any)'] = 'pages/view/$1/$2';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
I've tried to googling and use a few suggestion around but still no luck...
many thanks in advance.
Best,
You are not sopposed to call view file. Instead you should make request through controllerwhich is meant to call specific file. So you never want to call (nor I am sure how you succeeded in request with that URL):
http://example.com/application/views/pages/vcard/igniel.php
but
http://example.com/pages/view/igniel
(withouth the extension).
You should follow basic example from CI documentation. In your case it means you are trying to use subdirectory vcard with same code in controller that doesn't fit your needs.
class Pages extends CI_Controller
{
public function view($page = 'home')
{
if ( ! file_exists(APPPATH.'/views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
elseif ( $page == 'igniel' )// your page is in subdirectory
{
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header');
$this->load->view('templates/nav');
$this->load->view('pages/vcard/'.$page);
$this->load->view('templates/footer');
}
else
{
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header');
$this->load->view('templates/nav');
$this->load->view('pages/'.$page);
$this->load->view('templates/footer');
}
}
}
But, if you want to call it like:
http://example.com/igniel
You have to change line in controller to include that file within it's path as described in elseif line.
Routing should take place like:
$route['(:any)'] = 'pages/view/$1';
If you have more subdirectories, you have to fit code in controller to aproach those as I describe it here for you.
In my Application
I have 3 routing rules (defined in routes.php file) thats directed to the one controller
$route[urlencode('news')] = "news/show-news";
$route[urlencode('letters')] = "news/show-news";
$route[urlencode('papers')] = "news/show-news";
so
if any user navigate to any of those URLs
http://example.com/news/
http://example.com/letters/
http://example.com/papers/
The target controller will be news/show-news
My need
How to identify Routing rule that used that directed to my Codeigniter controller?
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class News extends CI_Controller {
public function show-news(){
// came from [news OR letters OR papers] ??
}
}
You can do it with something like this, but there are various methods to achieve what you want. Basically, to give you a kick-start, check out the code below:
In your controller, you put this code:
class News extends CI_Controller {
public function show_news( $method = '' )
{
switch ( $method )
{
// If news requested
case 'news':
// your code here
echo 'news requested';
break;
// If letters requested
case 'letters':
// your code here
echo 'letters requested';
break;
// If papers requested
case 'papers':
// your code here
echo 'papers requested';
break;
// Default landing if nothing provided
default:
// your code here
echo 'select one of the show method';
}
}
}
And in your routes.php, you type this:
$route['news'] = "news/show_news/news";
$route['letters'] = "news/show_news/letters";
$route['papers'] = "news/show_news/papers";
So you have a 4th option, that if nothing is provided, you can redirect to some page where the users can choose one of the available types of news in the default section.
First thanks to #aspirinemaga
His answer is correct
But if we want to do that without using parametric controller function
We can do that
public function show-news(){
// came from [news OR letters OR papers] ??
$requested_URI_segment = $this->uri->segment(1);
$requested_URI_segment = urldecode($requested_URI_segment);
switch ( $requested_URI_segment ){
// If news requested
case 'news':
// your code here
echo 'news requested'. '</br>';
break;
// If letters requested
case 'letters':
// your code here
echo 'letters requested'. '</br>';
break;
// If papers requested
case 'papers':
// your code here
echo 'papers requested'. '</br>';
break;
// Default landing if nothing provided
default:
// your code here
echo 'select one of the show method'. '</br>';
}
Try this :
$route['news'] = "controller/method_name";
$route['letter'] = "controller/method_name";
$route['papers'] = "controller/method_name";
I have project which i made using CI before, and i have section which is for student & absent. So in my route i set like this :
$route['student/page'] = "student/index";
$route['student/page/(:num)'] = "student/index/$1";
$route['absent/page'] = "absent/index";
$route['absent/page/(:num)'] = "absent/index/$1";
And with some setting on htaccess.
I am following the tutorial-Static pages, from codeigniter website.
I extracted the codeignitor zip into my local server.
Edited the line
$config['base_url']='http://localhost/';
in application /config/config.php
Created the file: application/controllers/pages.php to have following contents:
<?php
class Pages extends CI_Controller {
public function view($page = 'home')
{
if ( ! file_exists('/var/www/application/views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/footer', $data);
}
}
Created the file: application/views/templates/header.php with some HTML content.
Created the file: application/views/templates/footer.php with some HTML content.
Now, when I go to
localhost/index.php/pages/view/about
I expect the 'about' page, but 404 error is shown.
Why is that?
please try following
if (file_exists(APPPATH."views/pages/". $page. ".php")) {
$this->load->view("pages/". $page);
}
APPPATH = well self explanatory
I think the problem is here-
if ( ! file_exists('/var/www/application/views/pages/'.$page.'.php'))
You should also mention the name of your codeigniter folder as well!
Some webservers expect a question mark, like so:
localhost/index.php?/pages/view/about
Can you test this?
Instead of this
$config['base_url']='http://localhost/';
Try
$config['base_url']='http://localhost/project_name/';
I have got many blogs. I have tried to find a solution why controller is not loading the page and displaying a blank page . But I would not find it useful. But the code works fine in localhost. I don't know why it is so. Unable find a solution. Any help would be appreciated.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Config_test extends CI_Controller {
public function __construct(){
parent::__construct();
if( $this->session->userdata('logged_in') != TRUE ){
redirect('login?reurl='.current_url());
}elseif (!$this->usergroup_model->page_allowed()) {
//This check will ensure that only authorised users can have access to any
//functions present in this controller
//Route all control requests only through config function only
show_error('The url is either wrong or the inputs are inadquate. Please navigate with the help of menu bar only...');
die();
}
$this->moduleID = '3';
$this->menu['main_menus'] = $this->usergroup_model->menu_access();
$this->menu['sub_menus'] = $this->usergroup_model->submenu_access($this->moduleID);
$this->menu['module_name'] = $this->usergroup_model->module_name($this->moduleID);
$this->load->vars($this->menu);
$this->load->model('model_1');
$this->load->model('model_2');
$this->load->model('model_3');
}
function index(){
$this->config();
}
function config($action=null)
{
//If customer ID is null... redirect to dashboard...
if($this->session->userdata('dashboard_customer_id') == null)
redirect('dashboard');
switch ($action)
{
case 'add':
$this->add();
break;
case 'add_save':
$this->add_save();
break;
case 'add_success':
$this->add_success();
break;
case 'edit':
$this->edit();
break;
case 'edit_save':
$this->edit_save();
break;
case 'edit_success':
$this->edit_success();
break;
default:
$this->edit();
break;
}
}
function add()
{
//doing some function
}
function add_save()
{
//some code
}
function add_success()
{
//some code
}
function edit()
{
//some code
}
function edit_save()
{
//some code
}
function edit_success()
{
//Not used here...
}
}
And this is my url http://localhost/tester/index.php/Config_test
May be mod_rewrite is not enabled on server.
enable mod_rewrite on server
The problem can be caused by many thinks like a missing extension of php. Have you looked into error logs. Maybe if you provide some more info I can be able to help you. What is the version of php you are using in localhost and the live system.
Apache is case-sensitive by default, so:
http://localhost/tester/index.php/Config_test
should be lowercase:
http://localhost/tester/index.php/config_test
Of course, keep the controller class name capitalized.