Routing to Controller in Laravel4 - laravel

I am using laravel for the first time and need some help understanding routes. I am setting up a view that will show a list of orders placed by customers. Above this list are 2 search boxes. One for searching by ID, the other for selecting a date. I'd like to have a "default" route so when id/date are NOT included in the route, we see all orders placed so far today.
Routes should be as follows:
orders - Should display all orders placed today.
orders/{id} - Should show only the specific order that belongs to that id.
orders/{date} -
Should show all orders placed on a specific date.
{id} and {date} should be distinguished by regular expressions.
I can get any one of the routes to work by themselves but when I try to create the routes for all 3 and modify my controller accordingly I break the others. One example is this:
Route::get('orders/{id}', 'OrderController#getOrders')->where('id', '[0-9]+');
Which works for getting the order by ID, but if I wanted to allow for dates as well I would have to change the route entirely. From that point I'd like to be able to go even further, for example the route orders/12345/edit should bring me to the view that allows me to edit the order.
How can I properly setup my routes/controller to do this?

Unless you manage to write a regular expression that validates dates or numeric values you have two options:
Write two different routes: one that validates dates and other that validates IDs. Both would point to different methods in the controller.
Use one route that doesn't validate its the parameter and that points to one method in the controller where the type of parameter would be checked for date or ID.
I like the first option better, because I believe both routes are similar yet very different.
EDIT
If you want to use the same form to target to different urls depending on the contents of inputs you have to use javascript, you can change the action in the form using:
$('#form').attr('action', "the_url");
And you'd have to set up a listener for the inputs to know which url to point to:
Detecting input change in jQuery?
I hope this helps you!

just make three routes like laravel documentation
orders route:
Route::get('orders', 'OrderController#getOrders');
orders by id route:
Route::get('orders/{id}','OrderController#getOrdersById')->where('id', '[0-9]+');
orders by data route:
Route::get('orders/{data}', 'OrderController#getOrdersByData')->where('name', '[A-Za-z]+');
also you can create three route into your OrderController like documentation

Related

Using multiple Routes and Controllers on single blade file

I have created multiple controller and routes but they are working 1 at a time, I have to disable the other and change the code of my blade file or use different blade file for them but is there an easy way to use it.
The routes are
Route::get('/students/{alphabet}', 'PostController#showByAlphabet');
Route::get('/students/{name}', 'PostController#showByName');
Route::get('/students/{class}', 'PostController#showByClass');
I do not want to create different blade files like
http://example.com/students/alphabet/a
http://example.com/students/name/nadia
http://example.com/students/class/b_com
but like this
http://example.com/students/a
http://example.com/students/nadia
http://example.com/students/b_com
is it possible?
All controllers show different data.
1. Alphabet show list of students starting with same initial.
2. Name shows profile data of the student.
3. Class shows list of students in that subject class.
Since you have a wildcard at the end of your routes the first one will always trigger. So make sure you have individual routes for the controller functions. You can still use the same blade file in the controller.
Route::get('/students/alphabet/{alphabet}', 'PostController#showByAlphabet');
Route::get('/students/name/{name}', 'PostController#showByName');
Route::get('/students/class/{class}', 'PostController#showByClass');
If you have the same route with a parameter there is no way for the router to know if the characters you're sending in are alphabet, name or class.

How to map multiple URLs references of same content to one SEO friendly URL?

In My Application
We can access user profile screen by any of next URLs format
http://example.com/users/123/
http://example.com/users/123/mike
http://example.com/users/123/mike-pedro
But the problem is that
Now many URLs will show the same content
Because i dont care about last {slug}, i only use {id} to show the content
And according to
http://blog.codinghorror.com/url-rewriting-to-prevent-duplicate-urls/
That will lowers my PageRank
And divvied up between the 3 different URLs instead of being concentrated into one of them.
When i checked stackoverflow implementation
I found
The 3 different URLs will directed to the same content and the same URL
for example
All next 3 links
https://stackoverflow.com/users/1824361/
https://stackoverflow.com/users/1824361/yajli
https://stackoverflow.com/users/1824361/yajli-maclo
ALL Will directed to one target URL and show its content
https://stackoverflow.com/users/1824361/yajli-maclo
The target link = {id} + {slug}
How to implement that using codeigniter
In your controller you can change the method where you'll be sending the ID to a model (with 1 argument - $id) that will return the "slug" (name) from the table for that specific ID.
With these you can then call another method in the controller that will take 2 arguments (Id and slug). This will make the link look like this: example.com/users/123ID/blaSlug
So if you access the first method, he will do the job and go to the second method.
Hope this helps
Cheers

How to pass route values to controllers in Laravel 4?

I am struggling to understand something that I am sure one of you will be able to easily explain. I am somewhat new to MVC so please bear with me.
I have created a controller that handles all of the work involved with connecting to the Twitter API and processing the returned JSON into HTML.
Route::get('/about', 'TwitterController#getTweets');
I then use:
return View::make('templates.about', array('twitter_html' => $twitter_html ))
Within my controller to pass the generated HTML to my view and everything works well.
My issue is that I have multiple pages that I use to display a different Twitter user's tweets on each page. What I would like to do is pass my controller an array of values (twitter handles) which it would then use in the API call. What I do not want to have to do is have a different Controller for each user group. If I set $twitter_user_ids within my Controller I can use that array to pull the tweets, but I want to set the array and pass it into the Controller somehow. I would think there would be something like
Route::get('/about', 'TwitterController#getTweets('twitter_id')');
But that last doesn't work.
I believe that my issue is related to variable scope somehow, but I could be way off.
Am I going down the wrong track here? How do I pass my Controllers different sets of data to produce different results?
EDIT - More Info
Markus suggested using Route Parameters, but I'm not sure that will work with what I am going for. Here is my specific use case.
I have an about page that will pull my tweets from Twitters API and display them on the page.
I also have a "Tweets" page that will pull the most recent tweets from several developers accounts and display them.
In both cases I have $twitter_user_ids = array() with different values in the array.
The controller that I have built takes that array of usernames and accesses the API and generates HTML which is passed to my view.
Because I am working with an array (the second of which is a large array), I don't think that Route Parameters will work.
Thanks again for the help. I couldn't do it without you all!
First of all, here's a quick tip:
Instead of
return View::make('templates.about', array('twitter_html' => $twitter_html ))
...use
return View::make('templates.about', compact('twitter_html'))
This creates the $twitter_html automatically for you. Check it out in the PHP Manual.
 
Now to your problem:
You did the route part wrong. Try:
Route::get('/about/{twitter_id}', 'TwitterController#getTweets');
This passes the twitter_id param to your getTweets function.
Check out the Laravel Docs: http://laravel.com/docs/routing#route-parameters

MVC3 Routing - Routes that builds on each other

I have an AREA setup in my project. I need to make the routes for the area progressive, meaning that the route will build on each other.
I'm looking at this as something like a link list. Each node in the list will have a reference to a parent. As move from left to right in the list it builds, and from right to left it removes.
In the area, I have companies and that have contacts, and child companies.
For example, I have companies that would have the following:
/Companies/list
/Company/{Id}
/Company/{id}/add
/Company/{id}/edit
/Company/{id}/delete
For the contact section I need to create the following routes:
/Company/{id}/contacts/list
/Company/{id}/contact/{id}/add
/Company/{id}/contact/{id}/edit
/Company/{id}/contact/{id}/delete
How do I make sure that /Company/{id} is always in the Contact and Child Company sections of the route?
I hope that I have made my question clear.
Subjective Generalities (take with a pinch of salt):
First off, you are using Company (singular) for companies, but then you are using contacts (plural) for the contacts. There is nothing wrong with this, from a structural point of view, but your users will thank you if you are consistent with your pluralizations. I would use the plural in both cases, but that is just my preference... it looks more like English.
You also use lower case for contacts, but upper case for Company. Doesn't look professional.
The next thing that is confusing is that you are using two {id} parameters, one for companies, one for contacts. I presume these are the ids for Company and Contacts respectively. But I am confused, but being human, I am able to deduce context unlike a computer. So you would be better of specifying the parameters in your routes. Ie:
/Companies/{CompanyId}/Contacts/{ContactId}/[action]
Answering your Question with an Example:
I get the feel you don't understand routes properly. If you did, your question would be more specific.
Your route parameters can come from a number of sources, depending on how the route is requested.
You could hard code it into a link. Or, more usefully, your route registration would be designed to catch requests that map to your Action signatures.
For example, I have an eLearning app with tutors, pupils, courses and steps (ie, the steps are like sections of a course, the pupil advances through the course step by step)
The route registration looks something like:
Route or Area Registration:
context.MapRoute(
"StepDisplay",
"Course/{CourseId}/Step/{StepOrder}/Pupil/{PupilName}/{TutorName}",
new { controller = "Course", action = "Display", TutorName = UrlParameter.Optional },
new[] { "ES.eLearningFE.Areas.Courses.Controllers" }
);
This route will catch a request from the following ActionLink:
ActionLink in View:
#Html.ActionLink(#StepTitle, MVC.Courses.Course.Actions.Display(Model.CourseId, step.StepOrder, Model.Pupil.UserName, tutorName))
Now, I just need to show you the Display action's signature:
CoursesController:
public virtual ActionResult Display(int CourseId, int StepOrder, string PupilName, string TutorName)
There are a few things to note here:
That I am able to call this specific route by giving the user a link to click on.
I construct this link using the Html.ActionLink helper
I have used David Ebbo's t4mvc nuget package so that I can specify the action I am calling and its parameters. By which I mean specifying the ActionResult parameter of the Html.ActionLink helper using:
MVC.Courses.Course.Actions.Display(Model.CourseId, step.StepOrder, Model.Pupil.UserName, tutorName)
If you think about it, what routes do is translate the url of a request into an action, so the parameters of my route are either the controller name, the action name or else they are the names of parameters in the action signature.
You can see now why naming two distinct route parameters with the same
name is such a bad idea (largely because it won't work).
So, look at your action signatures, and design your routes and your action links so that the everything marries up together.
MVC doesn't work by magic!! (Although the way it uses name conventions might lead you to believe it)

friendly url in codeigniter with variables in url

I'm making a site using Codeigniter and my URL for a particular product page is like http://www.domain.com/products/display/$category_id/$product_id/$offset
$offset is used for limiting the number of pages shown per page when using the Codeigniter's Pagination library.
How I want to make it such that my URL is something more human friendly, like http://www.domain.com/$category_name/$product_name/$offset ie. http://www.domain.com/weapons/proton-canon/3
Can anyone point me the general approach? I just started learning codeigniter and is working on my first project
You can use what's generally known as a URL slug to achieve this.
Add a new field to your table, called "url_slug" or similar. Now you will need to create a slug for each product, and store it in this field.
CI has a function in the URL helper - url_title($string) which will take a string, and convert it for use in URL's.
For example My product name would become my_product_name.
Now, in your method, you can either - keep the product_id intact, use this as a parameter for your method to show specific products, and use the slug for human friendly links, or you can just use the url_slug to refer to products.
Your URL may look like:
www.domain.com/$category_name/$product_id/my_cool_product/$offset
or it could look like
www.domain.com/$category_name/my_cool_product/$offset
with no ID. the choice is yours, but the url_slug may change - the ID won't. Which may have SEO impacts.
Regardless, your method needs to look something like:
function display_product($product_id, $url_slug, $offset) {
// do what you gotta do...
}
You can then use URL's like the above.
You will need to use URI routing as well, as the example above will attempt to look for a controller called $category_name and a method called my_cool_product, which will of course not exist.
See URI Routing for further info.

Resources