I am developing an ecommerce website with CI that has product categories and products. I want to route the URL so that it will go to the products controller, then run the getCategoryByName function for the first segment, then run the getProductByName for the second segment. Here is what I have:
URL:
products/docupen/rc805
routes.php:
$route['products/([a-z]+)'] = "products/getCategoryByName/$1";
$route['products/([a-z]+)/([a-z0-9]+)'] = "products/$1/getProductByName/$2";
But its not working. "docupen" is the category, and "rc805" is the product.
Thanks in advance.
Thank you all for your help. This is what I ended up with for what I needed.
$route['products/:any/:num'] = "products/getProductByID";
$route['products/:any/:any'] = "products/getProductByName";
$route['products/:any'] = "products/getCategoryByName";
My answer builds a bit on Colin's answer.
When I played around with the routes in CodeIgniter I came to the conclusion that the order of the routes was important. When it finds the first valid route it won't do the other routes in the list. If it doesn't find any valid routes then it will handle the default route.
My routes that I played around with for my particular project worked as follows:
$route['default_controller'] = "main";
$route['main/:any'] = "main";
$route['events/:any'] = "main/events";
$route['search/:any'] = "main/search";
$route['events'] = "main/events";
$route['search'] = "main/search";
$route[':any'] = "main";
If I entered "http://localhost/index.php/search/1234/4321" It would be routed to main/search and I can then use $this->uri->segment(2); to retrieve the 1234.
In your scenario I would try (order is very important):
$route['products/:any/:any'] = "products/getProductByName";
$route['products/:any'] = "products/getCategoryByName";
I don't know enough to route the way you wanted (products/$1/getProductByName/$2), but I'm not sure how you would create a controller to handle this particular form of URI. Using the $this->uri->segment(n); statements as mentioned by Colin in your controller, you should be able to do what you want.
You should use the URI class to retrieve the "docupen" and "rc805" segments from your url. You can then use those values in whatever functions you need.
For example, if your url is www.yoursite.com/products/docupen/rc805, you would use the following in your products controller to retrieve the segments and assign them to variables:
$category = $this->uri->segment(2); //docupen
$product = $this->uri->segment(3); //rc805
Then you can use $category and $product however you need to.
CodeIgniter routes don't work well with regex. They are supported, not I can never get them to work. It would be much easier to catch them like this
$route['products/(:any)'] = "products/getCategoryByName/$1";
$route['products/(:any)/(:any)'] = "products/$1/getProductByName/$2";
Related
I have a Real Estate Site, in CodeIgniter my link names is:
htp://examplesite(dot)com/property/31/en/property_title
I want to replace it with:
htp://examplesite(dot)com/my-custom-slug.htm
or
htp://examplesite(dot)com/property_title
Both ways might be ok. My routes are:
$route['default_controller'] = "frontend";
$route['404_override'] = 'frontend';
/* Custom routing */
$route['admin'] = 'admin/dashboard';
//$route['secret'] = 'admin/dashboard';
// To change property->listing in uri
$route['listing/(:num)/(:any)/(:any)'] = "property/$1/$2/$3";
$route['listing/(:num)/(:any)'] = "property/$1/$2";
what is the best way in this case?
I know there is a possible solution that:
Add
$config['listing_uri'] = 'listing';
Than add to:
In ‘application\config\routes.php’
After:
$route['listing/(:num)/(:any)/(:any)'] = "property/$1/$2/$3";
$route['listing/(:num)/(:any)'] = "property/$1/$2";
Add also:
$route['changed/(:num)/(:any)/(:any)'] = "property/$1/$2/$3";
$route['changed/(:num)/(:any)'] = "property/$1/$2";
but is there any way to remove the 'listing', to see only the clean url (for better seo purpose) ??
Welcome, luckily your problem isn't too big :)
Maybe have one slug before the property title to make the solution a bit more scalable:
$route["listing/(:any)"] = "property/view/$1";
Then point your browser to yoursite.com/listing/some_slug or yoursite.com/listing/12
You will need to have a slug associated with each property, otherwise you can use the id, and in the view function just retrieve the property based on the slug or id parameter.
If you don't want to include the listing/ you might have problems down the line when trying to create other routes.
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 searched for the solution to my problem in CI user guide and on Stackoverflow as well but couldn't find. So, here is my problem.
I need to build SEO friendly URLs. I have a controller called "Outlets" and the view that I need to generate will have a URL structure like http://www.mysite.com/[city]/[area]/[outlet-name].
The segments city and area are fields in their respective tables and outlet_name is a field in the table "Outlets".
I am able to generate a URL like http://www.mysite.com/outlets/123 but how do I add the city and area name to the URL.
If all of your page use the same controller, in config/routes.php add this...
$route['(:any)/(:any)/(:any)'] = "outlets/$1/$2/$3";
$route['(:any)/(:any)/(:any)/(:any)'] = "outlets/$1/$2/$3/$4"; // fixed typo
In the controller you will want to remap the function calls because Codeigniter will be looking for functions with the names of the city and they will not exist.
http://codeigniter.com/user_guide/general/controllers.html#remapping
public function _remap($city, $area, $outlet, $options = '')
{
$this->some_function_below($city, $area, $outlet, $options);
}
Another alternative solution.
You can use URI segments. For an url like http://www.mysite.com/[city]/[area]/[outlet-name]
<?php
$this->uri->segment(3); // city
$this->uri->segment(4); // area
$this->uri->segment(5); // outlet-name
?>
and so on... See http://codeigniter.com/user_guide/libraries/uri.html for more details.
I'm new to CodeIgniter and going to be using it for building a sort of reusable application with multiple instances of an application. For example, each instance of the application will have an id "12345", and inside that instance, there will be entry IDs of 1,2,3,4,5,6,7,8, etc.
to do this, I think I will want to be able to using Routing to set up something like:
http://example.com/12345/Entry/Details/1
Where this URI will go to the Details page of the Entry of ID=1, inside application ID 12345. This would be a different group of entries from a url of, say, /12346/Entry/Details/1. Is this a routing rule that needs to be set up, and if so, can someone please provide an example of how this could be configured, and then how I would be able to use 12345, and 1, inside of the function. Thanks so much for your help, in advance.
My suggestion would be that you route your urls like this:
$route['(:any)/{controller_name}/(:any)/(:any)'] = '{controller_name}/$2/$3/$1';
so that the last parameter for the function is always the id of the app (12345/12346). Doing this means that your Entry controller functions will look like this:
class Entry extends CI_Controller
{
function Details(var1, var2, ..., varn, app_id){}
function Someother_Function (var 1, app_id){}
}
you will also need to add a route for functions that don't have anything but the app_id:
$route['(:any)/{controller_name}/(:any)'] = '{controller_name}/$2/$1'; //This may work for everything.
I hope this is what you we're asking...
Edit:
If you are only going to be using numbers you could use (:num) instead of (:any)
You can achieve a routing like that by adding this rule to the application/config/routes.php file:
$route['default_controller'] = "yourdefaultcontroller";
$route['404_ovverride'] = "";
// custom route down here:
$route['(:num)/entry/details/(:num)'] = "entry/details/$1/$2",
of course assuming your URI to be like the example.
In your controller "Entry" you'll have a method "details" which takes 2 parameters, $contestID and $photoID, where $contestID is the unique instance you're assigning, while $photoID is the other (assumed) variable of your url (last segment).
class Entry extends CI_Controller(
{
function details {$contestID, $photoID)
{ //do your codeZ here }
}
See URI routing for more info on that. You might also want to consider the __remap() overriding function, in case.
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.