I'm working on a site I have inherited and having a little trouble routing to a controller.
When I visit the URL www.domain.com/banners/statistics, it won't return anything.
I also noted that when I try and link to this page via Banner Statistics this also gives me an error on my home page.
Routes.php
Route::resource('banners', 'BannerController');
Route::get('banners/{banners}/activate', 'BannerController#activate');
Route::get('banners/{banners}/deactivate', 'BannerController#deactivate');
Route::get('banners/{banners}/delete', 'BannerController#delete');
Route::get('banners/{banners}/preview', 'BannerController#preview');
Route::any('banners/{banners}/cropresize', 'BannerController#cropresize');
Route::get('banners/statistics', 'BannerController#statistics');
BannerController.php
public function create()
{
$data['title'] = 'Create Banner';
$data['disciplines'] = Discipline::lists('name', 'id');
return View::make('admin.banners.create', $data);
}
public function statistics()
{
return View::make('admin.banners.statistics');
}
The resource controller provides you multiple routes.
Including :
GET /resource/{resource} redirecting to the show action of your controller.
List of all created routes : http://laravel.com/docs/controllers#resource-controllers
So when you call
banners/statistics
Laravel think you want to call the show action with "statistics" as a parameter.
To avoid this, you can put all your custom routes above your resource controller route.
Route::get('banners/{banners}/activate', 'BannerController#activate');
Route::get('banners/{banners}/deactivate', 'BannerController#deactivate');
Route::get('banners/{banners}/delete', 'BannerController#delete');
Route::get('banners/{banners}/preview', 'BannerController#preview');
Route::any('banners/{banners}/cropresize', 'BannerController#cropresize');
Route::get('banners/statistics', 'BannerController#statistics');
Route::resource('banners', 'BannerController');
This way Laravel will call your custom route before the routes created by your resource controller.
You can also use only and except if you don't need some of the resource controller routes.
Route::resource('banners', 'BannerController',
array('except' => array('show')));
Related
I'm trying to create a custom route. The must be in this format: http://localhost:8000/home-back-to-school but instead I get a 404 not found error. http://localhost:8000/posts/home-back-to-school works, but that's not what I'm trying to get working.
My routes on web.php are defined as: Route::resource('posts',PostsController::class);
I modified the Route Service Provider by adding the code below:
parent::boot();
Route::bind('post',function($slug){
return Post::published()->where('slug',$slug)->first();
});
The published scope is defined in the Post Model file(Post.php) as:
public function scopePublished()
{
return $this->where('published_at','<=',today())->orderBy('published_at', 'desc');
}
I've done previously with laravel 5.x, now struggling with laravel 8.x
Link to the Documentation: Laravel 8 Documentation
You should define a custom route since you don't want to use the resourceful route for this method.
In your web.php
// Keep all your resource routes except the 'show' route since you want to customize it
Route::resource('posts', PostsController::class)->except(['show']);
// Define a custom route for the show controller method
Route::get('{slug}', PostsController::class)->name('posts.show');
In your PostController:
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
In your Post model:
// Tell Laravel your model key isn't the default ID anymore since you want to use the slug
public function getRouteKeyName()
{
return 'slug';
}
You may have to fix your other Post routes to make them work with this change since you are now using $post->slug instead of $post->id as the model key.
Read more about customizing the model key:
https://laravel.com/docs/8.x/routing#customizing-the-default-key-name
You should also remove the code you have in the boot method and use the controller instead.
Finally, make sure your post slug is always unique for obvious reason.
Note:
You may run into problems if your other routes are not related to the Post model.
Imagine if you have a route called example.com/contact-us. Laravel has no way to "guess" if this route should be sent to the PostController or the ContactController. contact-us could be a Post slug or it could be a static route to your contact page. That's why it's generally a good idea to start your urls with the model name. In your case, it would be a good idea for your Post route to start with "/posts/" like this: http://example.com/posts/your-post-slug. Otherwise you may run into all sorts unexpected routing issues.
Don't fight the framework: Always follow best practices and naming conventions when you can.
I still can't understand why I can't point my blade to the custom function I made in my controller. I create a route like this,
Route::get('/orders/storeInitialItems', 'OrdersController#storeInitialItems')->name('orders.storeInitialItems');
and in my controller I have this,
public function storeInitialItems()
{
return view('orders.storeInitialItems');
}
but when I run the page, storeInitialItems.blade.php, the error seems calling the show() function of my controller.
Why is that happening?
update
Complete routes for ORDERS
Route::get('/orders','OrdersController#index')->name('orders.index');
Route::get('/orders/create', 'OrdersController#create')->name('orders.create');
Route::post('/orders', 'OrdersController#store')->name('orders.store');
Route::get('/orders/{order}/edit', 'OrdersController#edit')->name('orders.edit');
Route::post('/orders/{order}', 'OrdersController#update')->name('orders.update');
Route::delete('/orders/{order}', 'OrdersController#destroy')->name('orders.delete');
Route::resource('orders', 'OrdersController');
Route::put('orders/{order}/pub', 'OrdersController#publish')->name('orders.publish');
Route::put('orders/{order}/cancel', 'OrdersController#cancel')->name('orders.cancel');
Route::put('orders/{order}/delivered', 'OrdersController#delivered')->name('orders.delivered');
Route::get('/orders/storeInitialItems', 'OrdersController#storeInitialItems')->name('orders.storeInitialItems');
Route::get('/orders/{order}/delivery', 'OrdersController#viewdeliveryItems')->name('orders.delivery');
Route::get('/orders/acceptDelivery', 'OrdersController#acceptDelivery')->name('orders.acceptDelivery');
Add your orders.storeInitialItems route
Route::get('/orders/storeInitialItems', 'OrdersController#storeInitialItems')->name('orders.storeInitialItems');
before,
Route::resource('orders', 'OrdersController');
or add some extra path with your storeInitialItems
Route::get('/orders/storeInitialItems/add-some-extra-path', 'OrdersController#storeInitialItems')->name('orders.storeInitialItems');
I'm trying to capture the intended url in my LoginController so I can execute some logic in a showLoginForm() method I added to the controller so I can send the user to a specific view based on the intended URL.
I've tried the following and I cannot get it to work:
public function showLoginForm()
{
$intededUrl Session::put('url.intended', URL::full());
// my base application url is http://www.websites.com:8080
if (starts_with($intededUrl, url('/admin'))) // i want all routes that begin with http://www.websites.com:8080/admin to go here
return view('auth.login');
return view('themes.'.env('APP_THEME', 'mango').'.auth.login'); // but it keeps taking me here
}
I'm using Laravels starts_with() method to try and match the start of the url string.
I just figured it out. I needed Session::get('url.intended');
I am attempting to create a route in Laravel for a dynamic URL to load a particular controller action. I am able to get it to route to a controller using the following code:
Route::get('/something.html', array('uses' => 'MyController#getView'));
What I am having trouble figuring out is how I can pass a variable from this route to the controller. In this case I would like to pass along an id value to the controller action.
Is this possible in Laravel? Is there another way to do this?
You are not giving us enough information, so you need to ask yourself two basic questions: where this information coming from? Can you have access to this information inside your controller without passing it via the routes.php file?
If you are about to produce this information somehow in your ´routes.php´ file:
$information = WhateverService::getInformation();
You cannot pass it here to your controller, because your controller is not really being fired in this file, this is just a list of available routes, wich may or may not be hit at some point. When a route is hit, Laravel will fire the route via another internal service.
But you probably will be able to use the very same line of code in your controller:
class MyController extends BaseController {
function getView()
{
$information = WhateverService::getInformation();
return View::make('myview')->with(compact('information'));
}
}
In MVC, Controllers are meant to receive HTTP requests and produce information via Models (or services or repositores) to pass to your Views, which can produce new web pages.
If this information is something you have in your page and you want to sneak it to your something.html route, use a POST method instead of GET:
Route::post('/something.html', array('uses' => 'MyController#getView'));
And inside your controller receive that information via:
class MyController extends BaseController {
function getView()
{
$information = Input::get('information');
return View::make('myview')->with(compact('information'));
}
}
I read the docs on the Laravel website, Stack Overflow, and Google but still don't understand the difference between Route::resource and Route::controller.
One of the answers said Route::resource was for crud. However, with Route::controller we can accomplish the same thing as with Route::resource and we can specify only the needed actions.
They appear to be like siblings:
Route::controller('post','PostController');
Route::resource('post','PostController');
How we can choose what to use? What is good practice?
RESTful Resource controller
A RESTful resource controller sets up some default routes for you and even names them.
Route::resource('users', 'UsersController');
Gives you these named routes:
Verb Path Action Route Name
GET /users index users.index
GET /users/create create users.create
POST /users store users.store
GET /users/{user} show users.show
GET /users/{user}/edit edit users.edit
PUT|PATCH /users/{user} update users.update
DELETE /users/{user} destroy users.destroy
And you would set up your controller something like this (actions = methods)
class UsersController extends BaseController {
public function index() {}
public function show($id) {}
public function store() {}
}
You can also choose what actions are included or excluded like this:
Route::resource('users', 'UsersController', [
'only' => ['index', 'show']
]);
Route::resource('monkeys', 'MonkeysController', [
'except' => ['edit', 'create']
]);
API Resource controller
Laravel 5.5 added another method for dealing with routes for resource controllers. API Resource Controller acts exactly like shown above, but does not register create and edit routes. It is meant to be used for ease of mapping routes used in RESTful APIs - where you typically do not have any kind of data located in create nor edit methods.
Route::apiResource('users', 'UsersController');
RESTful Resource Controller documentation
Implicit controller
An Implicit controller is more flexible. You get routed to your controller methods based on the HTTP request type and name. However, you don't have route names defined for you and it will catch all subfolders for the same route.
Route::controller('users', 'UserController');
Would lead you to set up the controller with a sort of RESTful naming scheme:
class UserController extends BaseController {
public function getIndex()
{
// GET request to index
}
public function getShow($id)
{
// get request to 'users/show/{id}'
}
public function postStore()
{
// POST request to 'users/store'
}
}
Implicit Controller documentation
It is good practice to use what you need, as per your preference. I personally don't like the Implicit controllers, because they can be messy, don't provide names and can be confusing when using php artisan routes. I typically use RESTful Resource controllers in combination with explicit routes.
For route controller method we have to define only one route. In get or post method we have to define the route separately.
And the resources method is used to creates multiple routes to handle a variety of Restful actions.
Here the Laravel documentation about this.
i'm using Laravel 8 in my project
and in my route file web.php
i add this route
Route::controller(SitesController::class)->group(function() {
Route::get('index', 'index')->name('index');
}
in the Route::controller group we pass controller name we will use
inside the group we define the route we'll use as below syntax
Route::method-used('prefix in the URL', 'function used in the specified controller ')->name(); if the name not used in your code just delete it