I have a working solution within routes.php, but I understand that laravel can handle restful routes better. I've tried using their documentation to implement restful resource controllers, but had no luck.
This is what I have at the moment
Route::get('/invoices', 'InvoicesController#showInvoices');
Route::get('/invoices/data', 'InvoicesController#getInvoices');
Basically, the showInvoices returns the invoices view and getInvoices returns a JSON string for DataTables which is called from the invoices view.
So I want to be able to call /invoices to get the view and then call /invoices/data using JavaScript.
Any suggestions how to convert this to a resource controller or more suitable controller?
Yes, there was a cleaner way. Route controllers were supported up to Laravel 5.3. Then this functionality was removed in favor of explicit routes, which leave the routes files in disarray when you have lots of routes.
Fortunately, there is a class I wrote called AdvancedRoute, which serves as a drop in replacement.
In your case you can use it like this:
Route::get('/invoices', 'InvoicesController#showInvoices');
Route::get('/invoices/data', 'InvoicesController#getInvoices');
Becomes:
AdvancedRoute::controller('/invoices', 'InvoicesController');
Explicit routes are built automatically for you. Have in mind you have to follow a convention by prefixing the method names with the request method, which I personally find very clean and developer friendly:
InvoicesController#getInvoices => /invoices
InvoicesController#getInvoicesData => /invoices/data
Full information how to install and use find at the GitHub repo at:
https://github.com/lesichkovm/laravel-advanced-route
Hope you find this useful.
You could create a "resource" route like so:
Route::resource('/invoices', 'InvoicesController');
Which will provide RESTful routes (GET, POST, PUT, etc...) for that particular /invoices route/resource. You can check this by executing php artisan route:list
You can learn more here.
I hope this helped.
Cheers!
Related
I'm looking for a solution where I can routing in Silex different URLs to a controller to get more organized my code.
The problem is that I need to route to the same controllerProvider some routes in different languages:
$app->mount("/{_locale}/string-in-english", new App\Controllers\myController());
$app->mount("/{_locale}/string-in-spanish", new App\Controllers\ myController());
Where /string-in-english and /string-in-spanish are routed to the same controller.
Most likely, the possible routes are inserted into a table in a database.
Greetings and thanks in advance.
Full i18n routing is tricky, you will need to use a translation service and a single call to a mount() that can handle translatable routes.
Take a look to this article. There are some interesting comments and the author published an I18nRoutingServiceProvider.
In my opinion Silex rocks when used in simple apps, but it can become really hard when you start to add this kind of features. Sometimes it is easier to implement them in a Symfony app.
I'm new to MVC's (this is my first time using one in a real scenario) and I am a little bit confused about how controllers (should) work.
After reading the Laravel documentation, I came to the conclusion that for general tasks like handling loading the sites (different sites are connected together), pages, admin, etc. I need RESTful controllers.
For the simple tasks it worked. It was easy and very fun to use. I had a Route like this:
Route::controller('admin', 'AdminController');
I had functions like
public function getProduct($id)
and it worked. (It was used to get a specific product: ../admin/product/1)
Now I want something more complex. Like
../sites/loadsite/mysite/mypage/mysubpage/123?myoption=yes
How do I do this? How do I begin, how to approach the problem? Do I have to use Route::get() for every single thing or is there a "nicer" way of doing this?
Laravel provides the "Resource Controllers" helper for generating RESTful routes for corresponding controller methods:
http://laravel.com/docs/controllers#resource-controllers
You can use this to easily create the standard REST routes for a given model, or, as shown in the example provided at laravel.com, you can restrict to only certain routes. The table they provide demonstrates how given paths map to given actions / controller methods.
Regarding the example url you give: ../sites/loadsite/mysite/mypage/mysubpage/123?myoption=yes, I'll break the question into two pieces, the url and query string:
Regarding the URL /sites/loadsite/mysite/mypage/mysubpage/123. This would not be considered by many to be a "RESTful" route. Instead of pages and subpages, you should be thinking in terms of models, and sometimes submodels. It is commonly considered best practice to avoid deeply nested routes, which typically means anything more than a single layer of depth: /model/{id}/submodel/[id]
Regarding the query string at the end of the url: ?myoption=yes: Laravel provides access to query string parameters by using the Input::get("Param") function. You do not have to designate query string params in your routes, they can simply be accessed in your controller method.
The "nicer" way is resource controllers - which of course may be combined with route prefixing and filters (e.g. authentication filters), etc.
Inside the methods of resource controllers, you can retrieve additional input (the option in the query string of your example) and process it with validation and whatever you want.
I have a CakePHP app and would like to incorporate a simple REST API, at first just for GET requests without authentication.
I have the conventional structure, e.g.:
Post (post model),
postsController (posts controller), method names match the routes.
views/posts (posts views - e.g. index.ctp etc)
Say I wanted a few REST API routes how would I add them alongside my normal views and controller methods. I presume having a separate apiPostsController might be a good idea but I'm not sure how to implement.
Route wise, for a given example.com/posts/view/123, the API equivalent might be example.com/api/v1/posts/view/123.
How might I implement this?
Looking at the book, the given instructions make use of the conventional controller and views which are already in use for actually viewing the app.
Why do you think you need another controller? This is not DRY. You'll replicate a lot when you do this.
If your API methods behave that much different you can still use prefix routing and prefix the methods with api, for example: api_some_action().
I guess your API is using XML or Json, see this chapter of the book how to archive this along side the regular HTML views: JSON and XML Views.
Router::connect('/api/:version/:controller/:action/*',
array(),
array(
'version' => 'v1|v2',
)
);
This route should work.
I'm coming From CodeIgniter to Laravel.
So, is a bad idea using automatic routes to all of controllers?
Route::controller(Controller::detect());
Should I use this instead creating routes in routes.php?
Yes this is bad.
Controller::detect() is actually not present in Laravel 4 because it is a bit broken.
detect() will go through your filesystem and return controller files, but this is a bad idea because the order you define your routes matters. If you have any nested controllers you will find this breaking very easily.
detect() will also return files in a different order depending on the file system, so this leads to a lot of unpredictability.
I would argue that you should define all your routes any ways, it is a lot easier to read and debug.
One of interesting things about Laravel that CI does not have is that for certain pages, you can route directly to the view without needing a controller at all. Think about static pages like 'About Us'. CodeIgniter would need you to set up a controller + view for that, even though the controller will do barely anything. In case of Laravel, you can route directly to a view in this case.
Setting up routes manually will allow you to set these short-circuited routes.
Automatic detection is a bad idea.
You can use routes or use Route::controller('mycontroller') or and array of controllers like Route::controller(array('mycontroller', mycontroller2');
Then you get the benefit, without the autodetect.
in laravel 4 :
you can use Restful Controller like documentation http://laravel.com/docs/controllers#restful-controllers
But
Route::controller() must take two parameters as minimum requirement
first parameter stands for URL respond to ,and second parameter is name of controller
also
you can write third parameter into Route::controller() is an array with names of actions (name of action with HTTP verb )and routes names for this actions
ex:
Route::controller('users','UsersController',array(
'getUsers' =>"listUsers" ,
));
route name for getUsers action is listUsers
Below is a good example to follow for CRUD and general purpose routing
type php arisan controller:make SampleController
edit routes.php and add
Route::resource('sample', 'SampleController');
Then type
php artisan routes to show the newly created routes
I have my own routing rules in routes.php, defined for all the pages that should be accessible via URL, such as mywebsite/blog/ and mywebsite/blog/category/category-name, i.e. the structure of my whole website is covered by my custom routes.
Now, I have a lot of elements that make use of requestAction, such as
$websiteabstract = $this -> requestAction(array(
'controller' => 'assets',
'action' => 'displayHomeAbstract'
));
This gives me an error Error: Controller could not be found, probably because I have not defined a route for /assets/displayHomeAbstract. But why do I have to define a custom route for that, when I explicitly state the name of the controller and the action? Shouldn't that bypass the routing altogether?
Either I have not understand Routing at all. Or do I really have to define ALL the possible routes (even those that are only used by requestAction) in my routes.php? I mean, I don't want to allow users to directly access mywebsite/assets/displayHomeAbstract anyway, only via an Element.
Thank you
EDIT: Here is my routes.php http://pastebin.com/aAKBwNZJ
Please have a look at line 128, this is exactly what I do not want since /assets/displayHomeAbstract is ONLY accessed via requestAction.
EDIT: And this is the element, that makes the request: http://pastebin.com/0tK5dYJk
Okay, after extensive discussion with the devs in IRC, I think I understand this well enough to explain to you:
You do have to define your custom routes for your requestAction in this case. requestAction is emulating a full request. It dispatches a request as if accessed using the string url every time, even when the url provided is an array. The book is referring to how when you have a custom route defined in addition to using the default routes (the last line of routes.php), you can use array urls to be agnostic of those routes. However, these array urls rely on the default routes.php in the /lib/ folder and are used to construct a url string. If you're going to have a custom routing pattern, you have to construct the url strings on your own.
Note: the comments below were from earlier versions of this answer.
The key to your problem is understanding the scope of Cake's routing and how it work.
When you define a route in CakePHP, it isn't just used for mapping URLs to controllers. It's also used by the Router for things like generating link addresses and, in your case, mapping the path supplied to requestAction() to a controller. Behind the scenes, Cake is creating a URL string based on your parameters, and then passes it off to the Router to find the correct controller. Since no such route exists, it fails.
As a solution, I would actually recommend not using a controller for that logic. Depending on what it does, a component or a helper may be a better place.
Look at line 156. You commented out the line that loads CakePHP's default routes.