codeigniter CI-Smarty + Internationalization (i18n) for CodeIgniter 2.x - codeigniter

I'm developing a Codeigniter application that requires internationalization (i18n) support.
I'm using CI-Smarty (Smarty 3) as a template solution, and Internationalization (i18n) for CodeIgniter 2.x, but I cant get the multilingual support to work with CI Smarty, I've tried to change the code, tried adding routes, and doing both at the same time but without success.
My site controller:
public function index() {
$this->news();
} #index
public function news() {
$xml = $this->pages->news();
$data['news'] = $xml->xpath('//item');
$data['date'] = $xml->xpath('//item/pubDate');
$data['alphabet'] = $this->pages->alphabet();
$data['numbers'] = $this->pages->numbers();
$data['pagetitle'] = $this->config->item('news_pagetitle');
$data['description'] = $this->config->item('news_description');
$data['keywords'] = $this->config->item('news_keywords');
$this->pages->page('news', $data);
} #news
My pages model:
function page($page, $data = NULL) {
$data['base'] = base_url();
$data['current'] = current_url();
$data['page'] = $page;
$data['title'] = $this->config->item('title');
$data['tagline'] = $this->config->item('tagline');
$data['datetime'] = date('l, F d, Y');
$data['dateshow'] = date('Y-n-j');
$this->parser->parse('header', $data);
$this->parser->parse($page, $data);
$this->parser->parse('footer', $data);
} #page
My routes.php:
$route['^(en|pt)/(.+)$'] = "$2";
// '/en', '/de', '/fr' and '/nl' URIs -> use default controller
$route['^(en|pt)$'] = $route['default_controller'];
// Prettify the url
$route['default_controller'] = 'site';
$route['404_override'] = 'site/e404';
$route['scaffolding_trigger']= "";
$route['(:any)'] = 'site/$1';
$route['guide/(:num)'] = 'guide/$1';
$route['shows/(:any)'] = 'shows/$1';
$route['shows/(:any)/(:num)'] = 'shows/$1/cat/$2';
$route['title/(:num)/(:any)'] = 'title/$1';
When I request the index page using the www.example.com/en/ which will show the news info it loads fine, but if I request the page news using www.example.com/en/news it does not load the news, and instead loads the 404 page, and do the same to all other pages.
The application works fine without the internationalization (i18n) support, loading all the pages ok, including the news page.
And also the internationalization (i18n) support works fine, I've tested it in a version without the CI-Smarty.
I need to translate this app into multiple languages, so I need to find a way for Codeigniter with CI-Smarty to support it. Is there one? Thanks to all those how can help.

Related

Make user-friendly URL in Codeigniter with multi-language support

I have created a multi-language website.
Facing issue while creating SEO user-friendly URL.
current URL:
http://localhost/example/en/user/myaccount OR
http://localhost/example/fr/user/myaccount
want to change it with
http://localhost/example/en/myaccount OR
http://localhost/example/fr/user/myaccount
routes.php
$route['default_controller'] = 'welcome';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
// URI like '/en/about' -> use controller 'about'
$route['^(en|de|fr|nl|id|es)/(.+)$'] = "$2";
// '/en', '/de', '/fr','/es' and '/nl' URIs -> use default controller
$route['^(en|de|fr|nl|id|es)$'] = $route['default_controller'];
also tried with
$route["myaccount"] = "user/myaccount";
$route["^(en|de|fr|nl|id|es)$/myaccount"] = "user/myaccount";
Nothing will work in this case. Already used following in routes.php file other demo projects with out multi-language. There it's work perfectly.
$route["myaccount"] = "user/myaccount";
Thanks in advance
you can consult the documentation for routes here
https://www.codeigniter.com/user_guide/general/routing.html
and for your problem
$route["(:any)/myaccount"] = "user/myaccount/$1";

codeigniter Different/separate 404 page for frontend and backend

How can set auto route 404 page of frontend and backend different ? I have searched a long time but i have not found perfect answer.
Btw, can we make the same for error 500 ?
You can easily do it by using conditional statement.
go to application/config/routes.php and remove:
$route['404_override'] = '';
After that add the following code.
$req_uri = $_SERVER['REQUEST_URI']; // $req_uri = /myproject/backend
$req_uri = explode('/', $req_uri);
$req_uri = $req_uri[2]; // $req_uri[2] = backend
if($req_uri == 'backend'){
$route['404_override'] = 'Backend_error'; // Not found controller for backend
}else {
$route['404_override'] = 'Frontend_error'; // Not found controller for frontend
}
You can use echo statement to analyze further. and then do more stuff accordingly.

Codeigniter minimize URLs with extending controller and multilingual

I've configured Codeigniter 2.1 with i18n and extended controller.
I've hide the main controller "main" and I kept visible "admin" and "blog" controller.
This urls works fine:
www.mysite.com/ en / functionname
www.mysite.com/ en / blog /
This is my problem:
www.mysite.com/ it / blog / functionname
With the main controller "blog" everything after "/" is ignored.
Is it possible to do this?
My routes.php file:
$default_controller = "main";
$language_alias = array('it','en');
// exceptions
$controller_exceptions = array('admin','blog');
// route
$route['default_controller'] = $default_controller;
$route["^(".implode('|', $language_alias).")/(".implode('|', $controller_exceptions).")(.*)"] = '$2';
$route["^(".implode('|', $language_alias).")?/(.*)"] = $default_controller.'/$2';
$route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1';
foreach($language_alias as $language) {
$route[$language] = $default_controller.'/index';
}
$route['404_override'] = '';
// URI like '/en/about' -> use controller 'about'
$route['^(it|en)/(.+)$'] = "$2";
// '/it', '/en' URIs -> use default controller
$route['^(it|en)$'] = $route['default_controller'];
If I remove lang in my URL everything works fine:
www.mysite.com/ blog / functionname
I think you need another segment in your routes for accessing the controllers function.
so you'll need a second line:
// '/it', '/en' URIs -> use default controller
$route['^(it|en)$'] = $route['default_controller'];
// URI like '/en/about' -> use controller 'about'
$route['^(it|en)/(.+)$'] = "$2";
// URI like '/en/about/test' -> use controller 'about' with function 'test'
$route['^(it|en)/(.+)/(.+)$'] = "$2/$3";
I don't use the i18n or support multiple language in any project atm so I can't test but this should do the trick.

CodeIgniter - dynamic pages - default controller url

edit
my solution in routes.php:
$route['news'] = 'news_controller';
$route['gallery'] = 'gallery_controller';
$route['(:any)'] = 'sites/$1';
and in my site conroller:
function index($site_id = '') {
//sanitize $site_id.
$this->site = $this->sites_model->get_site($site_id);
//etc.
}
THX to YAN
question:
so i wrote a little CMS with CodeIgniter. The admin can create sites. the site opens automatically when the segment of the url is like one in the DB. eg mysite.com/sites/about will call the "About" site. this works fine.
now i got a problem with my URL. i want this url
http://www.mysite.com/sites/about
turns to this:
http://www.mysite.com/about
the problem is, that i cannot use the routes.php and set wildcards for each site. (because they are dynamic and i dont know wich site the customer will create - and i dont want to edit the routes.php file for each site he will create - this should be done automatically)
the problem is i got other fix controllers too, like news, gallery or contact:
mysite.com/news, mysite.com/gallery, ...they work fine
so here is my Site Controller:
class Sites extends Public_Controller {
public $site;
public $url_segment;
public function _remap($method)
{
$this->url_segment = $this->uri->segment(2);
$this->load->model('sites_model');
$this->site = $this->sites_model->get_site($this->url_segment);
if($this->site !== FALSE)
{
$this->show_site($this->site);
}
else
{
show_404($this->url_segment);
}
}
public function show_site($data)
{
$this->template->set('site', FALSE);
$this->template->set('site_title', $data['name']);
$this->template->set('content',$data['content']);
$this->template->load('public/template','sites/sites_view', $data);
}}
and this is the Site_model who checks the database...if the url_segment fits the title in the DB:
class Sites_model extends CI_Model {
public function get_site($site_url)
{
if($site_url != ""){
$this->db->where('name', $site_url);
$query = $this->db->get('sites', 1);
if($query->num_rows() > 0){
return $query->row_array();
}
else
{
return FALSE;
}
}else{
return FALSE;
}
} }
i think i need something who checks if the controller exists (the first segment of the url) when not call the Site controller and check if the site is in the DB and when this is false then call 404.
any suggestions how this can be solved?
btw: sry for my english
regards GN
You can handle routes.php in the following way, just keep the (:any) value last:
$route['news'] = 'news_controller';
$route['gallery'] = 'gallery_controller';
$route['(:any)'] = 'sites/$1';
In your sites controller route to the specific site using the data from the URL.
function index($site_id = '') {
//sanitize $site_id.
$this->site = $this->sites_model->get_site($site_id);
//etc.
}
I am having trouble understanding the full intent of the question, but, from what I can tell, don't you simply need to add:
if ($this->uri->segment(1) != 'sites')
... // handle malformed URL

Codeigniter - best routes configuration for CMS?

I would like to create a custom CMS within Codeigniter, and I need a mechanism to route general pages to a default controller - for instance:
mydomain.com/about
mydomain.com/services/maintenance
These would be routed through my pagehandler controller. The default routing behaviour in Codeigniter is of course to route to a matching controller and method, so with the above examples it would require an About controller and a Services controller. This is obviously not a practical or even sensible approach.
I've seen the following solution to place in routes.php:
$route['^(?!admin|products).*'] = "pagehandler/$0";
But this poses it's own problems I believe. For example, it simply looks for "products" in the request uri and if found routes to the Products controller - but what if we have services/products as a CMS page? Does this not then get routed to the products controller?
Is there a perfect approach to this? I don't wish to have a routing where all CMS content is prefixed with the controller name, but I also need to be able to generically override the routing for other controllers.
If you use CodeIgniter 2.0 (which has been stable enough to use for months) then you can use:
$route['404_override'] = 'pages';
This will send anything that isn't a controller, method or valid route to your pages controller. Then you can use whatever PHP you like to either show the page or show a much nicer 404 page.
Read me guide explaining how you upgrade to CodeIgniter 2.0. Also, you might be interested in using an existing CMS such as PyroCMS which is now nearing the final v1.0 and has a massive following.
You are in luck. I am developing a CMS myself and it took me ages to find a viable solution to this. Let me explain myself to make sure that we are on the same page here, but I am fairly certain that we area.
Your URLS can be formatted the following ways:
http://www.mydomain.com/about - a top level page with no category
http://www.mydomain.com/services/maintenance - a page with a parent category
http://www.mydomain.com/services/maintenace/server-maintenance - a page with a category and sub category.
In my pages controller I am using the _remap function that basically captures all requests to your controllers and lets you do what you want with them.
Here is my code, commented for your convenience:
<?php
class Pages extends Controller {
// Captures all calls to this controller
public function _remap()
{
// Get out URL segments
$segments = $this->uri->uri_string();
$segments = explode("/", $segments);
// Remove blank segments from array
foreach($segments as $key => $value) {
if($value == "" || $value == "NULL") {
unset($segments[$key]);
}
}
// Store our newly filtered array segments
$segments = array_values($segments);
// Works out what segments we have
switch (count($segments))
{
// We have a category/subcategory/page-name
case 3:
list($cat, $subcat, $page_name) = $segments;
break;
// We have a category/page-name
case 2:
list($cat, $page_name) = $segments;
$subcat = NULL;
break;
// We just have a page name, no categories. So /page-name
default:
list($page_name) = $segments;
$cat = $subcat = NULL;
break;
}
if ($cat == '' && $subcat == '') {
$page = $this->mpages->fetch_page('', '', $page_name);
} else if ($cat != '' && $subcat == '') {
$page = $this->mpages->fetch_page($cat, '', $page_name);
} else if ($category != "" && $sub_category != "") {
$page = $this->mpages->fetch_page($cat, $subcat, $page_name);
}
// $page contains your page data, do with it what you wish.
}
?>
You of course would need to modify your page fetching model function accept 3 parameters and then pass in info depending on what page type you are viewing.
In your application/config/routes.php file simply put what specific URL's you would like to route and at the very bottom put this:
/* Admin routes, login routes etc here first */
$route['(:any)'] = "pages"; // Redirect all requests except for ones defined above to the pages controller.
Let me know if you need any more clarification or downloadable example code.

Resources