I'm having some troubles with routing in codeigniter.
My routing file is as below:
$route['admin/newgallery'] = 'gallery/do_upload';
$route['admin/listgallery'] = 'gallery/list';
$route['admin/create'] = 'posts/create';
$route['admin/listposts'] = 'posts/list';
$route['admin'] = 'admin/index';
$route['posts/(:any)'] = 'posts/view/$1';
$route['posts'] = 'posts/index';
$route['default_controller'] = 'pages/index';
$route['(:any)'] = 'pages/index/$1';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
All routes work just fine except for the first two:
$route['admin/newgallery'] = 'gallery/do_upload';
$route['admin/listgallery'] = 'gallery/list';
When I type mypage/admin/listgallery it calls gallery/list correctly. The problem is when I type the address with the original controller/method (in this case gallery/list) it goes to the list page as well when it should call a 404 error! Every other routing rule I have set does that, except the first two!
Out of the Box, Codeigniter allows you to directly access any Controller/Method from the URL.
It also provides the creation of custom routes so you could have 10 or more urls all pointing at the same controller/method with parameter passing if that was your desire...
So in the case you ONLY want access to any Controller/Method that are defiend in the Routes config.
You need to test if the url is defined in the routes config array.
The main code is something like...
$this->load->helper('url');
if(!isset($this->router->routes[uri_string()])){
show_404(); // Or whatever you want ...
}
And you would put this in your controller's constructor you want to protect.
Of course you could create a common controller and extend those controllers you want to protect in this manner.
( NOT Recommended ) Or if you want to get really "hacky" you could put it in the system/core/controller constructor and make it system wide. SO Everything needs to be defined in a route.
NOTE: This breaks the 'default_controller'.
Related
i already tried this code in route file but it not convert _ to - by default
$route['translate_uri_dashes'] = TRUE;
$route['stock/upload_stock'] = 'stock/upload_stockt';
CodeIgniter 3 provides a nice way for it ,There is a route
$route['translate_uri_dashes'] = false;
which is by default set to false, but if you set it to true, you can name your controllers and controller methods using the underscores (_s) and can call them using dashes (-s).
For example you have a controller named Company, and inside your Controller you have a method called about_us, now you can call it both the ways /company/about_us and company/about-us , when your $route['translate_uri_dashes'] is set to true.
So, try making your route as below
$route['stock/upload-stock'] = 'stock/upload_stock';
exmple: this load default controller/class with function page,
www.example.com/page
unless we have controller/class named page AND set $route['page'] = 'page'; it'll load the controller. But if we dont set the $route, it'll still load default_controller.
is that true a controller must have a $route[''] always? is not it possible to load controller page without set $route[''] even there is no default controller function with same name?
Edit:
I access
www.mysite.com/index.php/user
I do have user controller with index function, but my route file only contain:
$route['default_controller'] = 'page';
$route['(:any)'] = 'page/$1';
$route['product'] = 'product';
//$route['user'] = 'user';
$route['404_override'] = '';
returns 404, only works if I uncomment this: $route['user'] = 'user';
why?
Thanks.
No, that's not true. CodeIgniter, by default, directly maps URI segments to:
example.com/index.php/controller/method/param/param/...
Or if you have an .htaccess / similar solution to remove index.php:
example.com/controller/method/param/param/...
Routing is used when you wish to use a URL that does not directly map to this convention.
Edit: You have conflicting routes. CodeIgniter will look at each route in order from top to bottom, and if it find one that matches, it stops looking and processes that route. Because you have an (:any) catch-all route, it will match anything (like it says).
The rule of thumb is to place your most specific routes first, and then get more generic and catch-all later. Your (:any) route should be the very last one in your list. And the default controller and 404 overrides should stay first.
$route['default_controller'] = 'page';
$route['404_override'] = '';
$route['product'] = 'product';
$route['user'] = 'user';
$route['(:any)'] = 'page/$1';
You need to add the product and user routes because you've defined the (:any) route. If you want to avoid writing route rules for every one of your existing controllers, but still take advantage of a catch-all controller, consider using the 404_override controller/method instead. You can do your verifications to check if the URI is valid there. Just make sure to throw a 404 error if not (you can use show_404()), since any non-existant URL will be routed to there.
I've got a website which has a URL structure that is not at all useful for breadcrumbs, conducive to SEO, or intuitive for users. It's something like
asdf.com/directory/listing/{unique_id}/{unique-page-name}/
I would really like to change this to
asdf.com/{state}/{city}/{unique_id}/{unique-page-name}/
or something very similar. This way, I can implement breadcrumbs in the form of
Home > State > City > Company
Does anyone have any ideas as far as converting the current structure to one as I've described above? Any way I look at it, it seems that it'll require a complete overhaul of the website. It would just be great to be able to show users something like Home > Florida > Miami > Bob's Haircuts
Thanks!
You'd just need to be creative with your routes: http://ellislab.com/codeigniter/user-guide/general/routing.html
You can set up a route to catch all traffic and point it to directory/listing, then in your listing method - you can access the url segments manually. For example:
// application/config/routes.php
$route[':any'] = "directory/listing";
/**
you might have to play with this a bit,
I'm not sure, but you might need to do something like:
$route[':any'] = "directory/listing";
$route[':any/:any'] = "directory/listing";
$route[':any/:any/:any'] = "directory/listing";
$route[':any/:any/:any/:any'] = "directory/listing";
*/
// application/controllers/directory.php
function listing()
{
// docs: http://ellislab.com/codeigniter/user-guide/libraries/uri.html
$state = $this->uri->segment(1);
$city = $this->uri->segment(2);
$unique_id = $this->uri->segment(3);
$unique_page_name = $this->uri->segment(4);
// then use these as needed
}
OR, as is probably the case, you need to be able to call other controllers and methods -
You can change the URL to point to a controller, then do the listing stuff -
So your url would become:
asdf.com/directory/{state}/{city}/{unique_id}/{unique-page-name}/
and your route would become:
$route['directory/:any'] = "directory/listing";
Then, you'd need to update the uri segments in your listing method to match the 2nd, 3rd, 4th, and 5th segments.
This way, you could still call another controller and it wouldn't be caught by your custom route:
asdf.com/contact/ --> would still access the contact controller and index method
UPDATE
You could also get creative and use a regular expression to catch any urls with state names in the first uri segment - then push those to directory/listing and then all other controllers will still work and you don't have to add the directory controller in the url. Something like this might work:
// application/config/routes.php
$route['REGEX-OF-STATE-NAMES'] = "directory/listing";
$route['REGEX-OF-STATE-NAMES/:any'] = "directory/listing"; // if needed
$route['REGEX-OF-STATE-NAMES/:any/:any'] = "directory/listing"; // if needed
$route['REGEX-OF-STATE-NAMES/:any/:any/:any'] = "directory/listing"; // if needed
/**
REGEX-OF-STATE-NAMES -- here's one of state abbreviations:
http://regexlib.com/REDetails.aspx?regexp_id=471
*/
I want address of my website user is mydomain.com/username/. But it seems very difficult to me using codeIgniter.Please help me what is best way to do it.
mysite.com/profile?user=username
is current url of profile but i want this
mysite.com/username
please help me and I'm not good english speaker so I'm sorry if you not understand my question.
In your routes.php file route every existing controller (you should have atleast one) to itself. For example if you have controller main in main.php file route it:
$route['main'] = "main";
$route['main/(:any)' = "main/$1";
The reason why you should route it twice is because you must make sure that opening http://yoursite/main works as well as http://yoursite/main/my_method/ etc. Do this for every other controller you have.
The next step is to route everything else to your users controller. For example you have a profile method that has 1 argument - the username.
$route['(:any)'] = "users/profile/$1";
So now you will have everything else routed to users/profile/username.
One thing to remember is that the topmost priority goes higher in the routes.php file so your routes file should look something like:
$route['main'] = "main";
$route['main/(:any)' = "main/$1";
$route['users'] = "main";
$route['users/(:any)' = "main/$1";
$route['(:any)'] = "users/profile/$1";
See if that works!
You can use the CI routing
In your route.php file, select all your users and create a route for each :
$aUsers = $this->oDb->getAllUsers();
foreach($aUsers as $oUser) {
$route[$oUser->username] = "profile/" . $oUser->username;
}
It should work.
When using
$route['(:any)'] = 'pages/view/$1';
and I want to use other controllers in my routing for example:
$route['del/(:any)'] = 'crud/del';
it won't work. I guess it will use
pages/view/del/$1
and not my crud-controller when deleting an item. How can I solve this?
As indicated, $route['(:any)'] will match any URL, so place your other custom routes before the "catch-all" route:
$route['del/(:any)'] = 'crud/del';
// Other routes as needed...
$route['(:any)'] = 'pages/view/$1';
Its hundred percent working
$route['(:any)'] url is placed last in your routes file
$route['(:any)/company_product_deal_detail'] = "mypage_product_picture/deal_detail/$1";
$route['(:any)/company_service_deals/(:any)'] = "mypage_service_deal_list/index/$1";
$route['(:any)/company_service_deals'] = "mypage_service_deal_list/index/$1";
$route['(:any)'] = "company/index/$1";
I know that it's an old question, but I have found myself a nice solution.
By default, CodeIgniter gives priority to URL's from routes config (even if straight controller, method etc. specified), so I have reversed this priority this way:
In system/core/Router.php find _parse_routes method.
Add this code under literal route match:
$cont_segments = $this->_validate_request($this->uri->segments);
if ($cont_segments == $this->uri->segments) {
return $this->_set_request($cont_segments);
}
I agree, that this approach is kinda wrong, because we edit file from system/core, but I needed a fast soluttion to work with a lot of URL's.