I saw this route I downloaded from sample module at pyrocms
$route['sample(/:num)?'] = 'sample/index$1';
I tried to removed the '$1' above and the site runs smooth. I am wondering what's that for, and can I remove it.
$1 would be whatever matched by (:num) group - which is, really, any valid numbers. Whatever you add will get passed as the parameter for view method in pages controller. for example
$route['sample(/:num)?'] = 'sample/index/$1';
now in sample controller
function index($id){
// $id something that matched by group (:num)
}
$1 in the sense anything comes dynamically after the url sample/index
Related
Hi guys I am trying to achieve something that I hope is possible but couldn't find the right way to find.
I am using codeigniter 2.2.0
I want to use an url in codeigniter like
domain/username/controller/method/$args
Let me explain When user types an url like
domain/mike/job/editJob/12/urgent/
Here "mike" is someone's user name
"job" will be a controller alias
"editJob" will be a method
"12" and "urgent" will be parameter of editJob method.
editJob method will have three parameters.
I want "mike" as 1st parameter,
then "12" and "urgent" as second and third parameter.
So far what I have done in my routes
$route['(:any)/job/(:any)'] = 'job_c/$2/$1';
When I type in the url
domain/mike/job/editJob/12/urgent
in Job controller I get
"12" as first parameter
"urgent" as second parameter
and "mike" as third parameter
**
Is there any possible way to get "mike" as first parameter and then the rest is okay**
Edited:
One more thing if I pass three parameters after method then I am not
getting the username!!
I need to have the username as first parameter because there may have multiple parameters in any method and there is a possibility to have conditional parameters as well.
One more thing I want to know. Is it possible to make such route that will work the same as my given route but the controller alias will also be wildcard. Or if there is any way to check if a segment in url is a controller then one route and if not a controller then something else should happen.
I am not a well describer still tried to keep it simple. If anyone knows something that will help me a lot.
Thanks
UPDATE
Is there any way to keep the username "mike" in session from routes.php file thus I don't have to pass this as a parameter.
Updating Again
I have solved the issue somehow.
I am using
$route['(:any)/garage/([^/]*)/([^/]*)/(.*)'] = '$2/$3/$1/$4';
Here garage is nothing but a simple identifier for the route. This route will work when it gets garage as a second segment in url. It will work like
domain/user/garage/anyControler/anyMethod/manyParameters
It's completely dynamic only the garage is used as identifier. If you want you can use your controller name instead of using any identifier. then you don't have to declare same thing multiple times for multiple controllers but it will work fine. It will work for any controller and any method. In addition it supports dynamic number of parameters.
I don't know if there is any better way to do this but it solves my issue. If anyone know something better then this then please share.
I think what is happening is that you are accessing
domain/mike/job/editJob/12/urgent
and its being parsed like:
job_c/editJob/12/urgent/mike
Because:
$route['(:any)/job/(:any)'] = 'job_c/$2/$1';
$2 = (:any)/job/(:any) = editJob/12/urgent
$1 = (:any)/job/(:any) = mike
Substituting:
job_c/editJob/12/urgent/mike
You could try to keep your route as similar as your current one:
$route['(:any)/job/(:any)/(:any)'] = 'job_c/$2/$1/$3';
This will allow you to match $2 to any method name, and have $1 as the first parameter and $3 as the rest of params.
But, I would suggest, if this is a very specific route, substituting the $2 :any, with the actual method name and the expected type of the params, otherwise, you might receive unexpected values to every method in the matching controller.
I would use something like:
$route['(:any)/job/editJob/(:num)/(:any)'] = 'job_c/editJob/$1/$2/$3';
Hope this helps.
Update:
For the controller matching: Code Igniter uses the form controller/method/param1/param2/...
As long as you create routes that matches controllers, methods and params in that order, you can do anything.
$route['(:any)/(:any)/(:any)'] = '$1/$2/$3';
or just
$route['(:any)'] = '$1';
and hopefully it will contain a controller and method and the required params.
I think this will totally be missing the point of having a routing system.
I am working on an API via which I embed images of country flags on my website & several others.
I am taking in 3 parameters i.e
Country (Name of Country - ISO Code or Full Name)
Size (Dimension of Image)
Type (Styles like flat flag, shiny round flag etc...)
Now, have everything setup correctly but stuck in handling URI.
Controller -> flags.php
Function -> index()
What I have now is :
http://imageserver.com/flags?country=india&size=64&style=round
What I want
http://imageserver.com/flag/india/64/round
I went through some articles and made this route but all of them failed
$route['flag/(:any)/(:num)/(:any)'] = "welcome/index/country/$1/size/$2/style/$3";
$route['flag/(:any)/(:num)/(:any)'] = "welcome/index/$1/$2/$3";
$route['flag/(:any)/(:num)/(:any)'] = "welcome/index?country=$1&size=$2&style=$3";
I have also been having trouble with routes while writing my custom cms. Reading through your question, I see a couple issues that might very well be the answer you are looking for.
For starters, let's look at the routes you have tried:
$route['flag/(:any)/(:num)/(:any)'] = "welcome/index/country/$1/size/$2/style/$3";
$route['flag/(:any)/(:num)/(:any)'] = "welcome/index/$1/$2/$3";
$route['flag/(:any)/(:num)/(:any)'] = "welcome/index?country=$1&size=$2&style=$3";
If you want to run the index method from your flags class, which it looks like you do, you don't want to route to the welcome class at all. Currently, however, you are. Your routes should look like:
$route['flag/(:any)/(:num)/(:any)'] = "flags/index";
That way, Codeigniter will run the index method from your flags class. You don't have to worry about the country, size, or style/type in the route. The best option there would be to use the URI segment function like this:
$country = $this->uri->segment(2); //this would return India as per your uri example.
$size = $this->uri->segment(3); //this would return 64 as per your uri example.
$style = $this->uri->segment(4); //this would return round as per your uri example.
You could then use those variables to query your database and get the correct flag or whatever else you need to do with them.
So to restate my answer with a little more explanation as to why:
The routes you have currently are running the welcome controller/class and the index function/method of that controller/class. This, obviously, is not what you want. So you need to make sure your routes are pointing to the correct controller and function like I did above. The extra segments of the URI don't need to be in your route declaration, so you would then just use the uri_segment() function to get the value of each segment and do what you need with them.
I hope this helps you. I may not have found an answer for my problem, but at least I could provide an answer for someone else. If this seems confusing to you, check out the user guide at http://ellislab.com/codeigniter/user-guide. The main links you need for this are:
http://ellislab.com/codeigniter/user-guide/libraries/uri.html
and
http://ellislab.com/codeigniter/user-guide/general/routing.html
Let me know if you need more help or if this helped solve your problem.
I have these routes:
$route['shop/(:any)/(:any)'] = 'product/category_listing/$1/$2';
$route['shop/(:any)/(:any)/(:any)'] = 'product/product_listing/$1/$2/$3';
When I call this url:
http://mysite.com/shop/mens/trainers/a-product
the product_listing method should be called but instead the first method (category_listing) gets called and product_listing is never invoked.
How can I make this work as required?
Order of array elements matters!
Keyword (:any) matches everything, even slashes, so in your example CodeIgniter finds the first matching route and doesn't look any further.
So, if we do like this:
$route['shop/(:any)/(:any)/(:any)'] = 'product/product_listing/$1/$2/$3';
$route['shop/(:any)/(:any)'] = 'product/category_listing/$1/$2';
...then product listing is matched first, then everything else.
Even more, you can use regular expressions (e.g. ([a-z0-9]+)) to create rules you need.
I am trying to set a custom route for friendly url when loading a tag, by that I mean that I want to convert this: http://test.com/en/results?search_query=data&search=tag to this http://test.com/en/tag/data
Tried to do so by setting this in my routes.php:
$route['^(en|es|ro)/tag/(:any)'] = "fetch/results?search_query=$1&search=tag";
But no success, am I doing it wrong?
My routes.php:
$route['default_controller'] = "home";
// URI like '/en/about' -> use controller 'about'
$route['^(en|es|ro)/video/(.+)$'] = "video/id/$2";
$route['^(en|es|ro)/results$'] = "fetch/results$2";
$route['(en|es|ro)/tag/(:any)'] = "fetch/results?search_query=$2&search=tag";
$route['^(en|es|ro)/(.+)$'] = "$2";
// '/en', '/de', '/fr' and '/nl' URIs -> use default controller
$route['^(en|es|ro)$'] = $route['default_controller'];
$route['404_override'] = '';
I'm fairly sure the ^ is not necessary. Try without it:
$route['(en|es|ro)/tag/(:any)'] = "fetch/results?search_query=$1&search=tag";
In that context, ^ will be treated as a literal string. If you wanted top use a regex, I believe you'd have to wrap the regex itself in parentheses, like so:
$route['(^(en|es|ro))/tag/(:any)'] = "fetch/results?search_query=$1&search=tag";
I'm not 100% certain on that, but if I'm correct both should work. However, routes always assume the first part of the pattern is what the string should start with, so the ^ shouldn't be necessary anyways.
One more thing: You aren't using the second match, but the first. I believe you want to replace $1 with $2 in your route.
$route['(en|es|ro)/tag/(:any)'] = "fetch/results?search_query=$2&search=tag";
// ^^^1^^^^ ^^^2^^ ^^
EDIT: Upon further investigation and testing, it seems that Codeigniter cannot properly handle routes that use a query string like ?key=value. If you use a slash before the ? question mark, you can at least get it to route to the right controller and method:
$route['(en|es|ro)/tag/(:any)'] = "fetch/results/?search_query=$2&search=tag";
A url like this:
http://example.com/es/tag/Codeigniter's Router
...will be routed to the results method with this string as an argument, but $_GET will be empty:
?search_query=Codeigniter%27s%20Router&search=tag
So, you could pick apart the argument with parse_str():
function results($request)
{
$request = ltrim($request, '?');
parse_str($request, $get);
// echo $get['search_query']
}
You could always use .htaccess of course, but I understand the desire to keep all the routing logic in one place. Sorry if this isn't the answer you hoped for, but I'm afraid that without writing a custom router it's not possible to do this the obvious way in Codeigniter. My suggestion would probably be to find another way to handle your routing and the way you're accessing data from the URL.
You may need to escape the forwardslashes around tag. So it should look like this:
$route['^(en|es|ro)\/tag\/(:any)']
I have something similar, and it looks like
$route['(:any)/something/(:any)'] = "real/$2/path/$1";
I'm using URI re-routing in CI to make better URLS. An example here would be:
$route['users/(:any)'] = "users/index/$1";
The aim here is to get rid of the index from URL. This works well. However it stops me from being able to access any functions in the users controller, for example
mywebsite.com/users/messages
Just redirects to the users/index. Is there a way around this?
Define the list of methods you wish to keep then let the rest wildcard match:
$route['users/(messages|login|something)'] = "users/$1";
$route['users/(:any)'] = "users/index/$1";
Hi I'm not familiar with CI but i have a similar routing system. The (:any) works as a sort of catch all. When my router checks the routing rules it stops checking if it has found an exact match. So then the answer would be to just add another functions route before the catch all. Like
$route['users'] = "users/index/";
$route['users/messages/(:any)'] = "users/checkmessages/$1";
$route['users/(:any)'] = "users/$1";
Not sure how CI handles this but i can think of something like the first URL part is the class and the second the function. The router or the controller module should have the intelligence to start calling the function even without the routing table.
The routing table should only be used in case of "other callable names" like i did above with the messages/checkmessages thingy.
hope that gets you going.