I am working on a school project. while working on a schools detail page I am facing an issue with the URL. My client needs a clean URL to run AdWords. My school detail page URL: http://edlooker.com/schools/detail/4/Shiksha-Juniors-Ganapathy. But he needs it like http://edlooker.com/Shiksha-Juniors-Ganapathy. If anyone helps me out it will be helpful, thanks in advance.
You need to define this route after all routes in your web.php (if laravel 5.x) or in routes.php (if it is laravel 4.2).
Route::get('{school}','YourController#getIndex');
And your controller should be having getIndex method like this,
public function getIndex($school_name)
{
print_r($school_name);die; // This is just to print on page,
//otherwise you can write your logic or code to fetch school data and pass the data array to view from here.
}
This way, you don't need to use the database to get URL based on the URL segment and you can directly check for the school name in the database and after fetching the data from DB, you can pass it to the school details view. And it will serve your purpose.
Check Route Model Binding section in docs.
Customizing The Key Name
If you would like model binding to use a database column other than id when retrieving a given model class, you may override the getRouteKeyName method on the Eloquent model:
/**
* Get the route key for the model.
*
* #return string
*/
public function getRouteKeyName()
{
return 'slug';
}
In this case, you will have to use one front controller for all requests and get data by slugs, for example:
public function show($slug)
{
$page = Page::where('slug', $slug)->first();
....
}
Your route could look like this:
Route::get('{slug}', 'FrontController#show');
Related
In a Laravel 5.8 app i want my url's to be in Dutch, however, for consistency and just general easier use, i want to name everything else by their English names. Eloquent will ( as far as i know ) only pass me the proper vars if my Model, Controller, table etc. are all named the same.
Right now, i have a route named /backend/facturen which in English would be /backend/invoices. I have tried using names routes, however, i found that this wasn't what i was looking for.
My route:
Route::resource('/backend/facturen', 'InvoicesController');
My show method inside the InvoicesController:
public function show(Invoice $invoice) {
return view('backend.invoice.show', compact('invoice'));
}
The database table is named 'invoices'.
The only way so far i have got this to work is by renaming my route to:
Route::resource('/backend/invoices', 'InvoicesController');
But, of course, this is not a solution to my problem.
I would like to see all data from the invoices show up on my ( Dutch ) /facturen route.
Resource controllers by default look for a variable with the same name as the (last part of the) URL, so renaming the URL changes that variable as well.
But you can tell Laravel to use a different name:
Route::resource('/backend/facturen', 'InvoicesController')->parameters([
'facturen' => 'invoice'
]);
You could also get the variable itself from the id, without using the laravel magic to correctly detecting the variable from the url:
public function show($id) {
$invoice = Invoice::findOrFail($id);
return view('backend.invoice.show', compact('invoice'));
}
No, you have registered a route pointing to the URL /backend/facturen, to name it, use the name function:
Route::resource('/backend/facturen', 'InvoicesController')->name('backend.invoice.show');
Even then, it won't show that route, when using the view function you need to pass the path to your template, not the route.
I am having some trouble with my application when trying to create the user profiles. Here is the issue:
I am trying to create a view called userprofile.blade.php which will output any given users profile (based on id or username...doesn't really matter right now). Each profile page will show name, description, location, profile pic, and the given users posts. I used Laravel's Make:auth command to create the necessary authentication, customized the authentication forms, and then migrated all the columns I needed in my database.
My create and update methods work just fine (registering new users and updating their information). All the information is saved correctly in the database. However, I can only access it in my views with {{Auth::user()->}}. Whenever I try to use the Model in my Controller to access the data I need, it doesn't work. It seems to me as though I need to separate Laravel's default 'User' model with a custom model which I would call 'Account' or something along those lines.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\User;
use App\Recipe;
class UserController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth', ['except' => [
'index', 'show'
]]);
}
public function index(){
$user = User::find($id);
return view('user.userprofile')->with('user');
}
I only included the index method from my UserController to keep it simple. It breaks down and tells me that 'id' in $user = User::find($id); is an undefined variable. That tells me that it isn't accessing my database table.
My question is, should I create a new fresh model that isn't mixed up with authentication to handle all the user profile information? If so, how do I access my current database table 'users' from this new model?
Please let me know if I need to clarify things for you guys. I'm not very experienced and I understand if my question is fuzzy. Thanks so much for your time!! I really appreciate any help I can get!
Hello and welcome to developing with Laravel!
You're on the right track - you need to identify which user's profile you're viewing, retrieve it from the database, and pass it to the Blade view. You don't need a new model or anything, though! Just need to complete what you've started.
You should start by defining a route parameter in your route, that will capture the dynamic data you want from the URL. Let's use the numeric ID for now. If you want a URL that looks like example.com/user/439, your route should look something like Route::get('user/{id}', 'UserController#index');.
Once you have that, the id parameter will get passed to your controller's method. Define it as a method parameter, and it'll be usable: public function index($id) { ... }
I think you can take it from there. :)
I'm building a shopping app using Laravel where each product's URL must be kept concise.
Instead of using the following permalink structure: (which is common, but unfavorable)
www.example.com/products/{product-slug}
I want to use this permalink structure:
www.example.com/{product-slug}
In order to accomplish this, I'm using an implicit route model binding in my routes file:
Route::get( '{product}', function ( App\Product $product ) {
return view( 'product' ); // this works, but is not what I want
});
And I am overriding the lookup behavior in my Product model:
class Product extends Model
{
public function getRouteKeyName()
{
return 'slug'; // use the 'product.slug' column for look ups within the database
}
}
Now, according to Laravel's documentation:
Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name.
(View Source)
So I know that Laravel will match the {product} variable to a product stored within my database, or return a 404 response if one is not found.
And this all makes sense to me...
However...
Each product page is unique, so after the route matches a {product}, that {product} object needs to be passed to a controller for further processing.
So how do I pass this route to a controller, if I want to keep my implicit model binding?
Point the route to a controller function.
This would be your route (I named the controller ProductController and pointed it to show function, but you can rename both to your liking):
Route::get( '{product}', 'ProductController#show');
And this would be in your ProductController:
public function show(Request $request, \App\Product $product)
{
// Do stuff with $product
// Return view and pass it the $product variable
return view('product', compact('product'));
}
To answer my own question, I think I've found a great solution that combines my initial approach and devk's response:
Credits to Arjun's Blog for the idea.
As it turns out, you can also perform implicit model binding within a controller by passing an Eloquent model as a dependency:
/* App/Http/Controllers/ProductController.php */
/**
* Get the Product object.
*
* #param App\Models\Product
*/
public function show( Product $product )
{
return view( 'product', compact( 'product' ) );
}
Even though we are now referencing the model using a controller, Laravel will still automatically resolve the model. In fact, this behavior is clearly defined within the documentation:
Laravel automatically resolves Eloquent models defined in routes or
controller actions whose type-hinted variable names match a route
segment name.
(View Source)
I must have missed those words when I read it the first time...
Now, in order to set up the {product-slug} route (in the way I wanted to), you must set up your model and route definitions like so:
/* App/Models/Product.php */
class Product extends Model
{
/**
* Get the route key for the model.
*
* #return string
*/
public function getRouteKeyName()
{
return 'slug';
}
}
As mentioned earlier, overriding the getRouteKeyName() method will make Laravel search for a product using it's slug column in the database instead of its id column (which is the default).
/* routes/web.php */
Route::get( '{product}', 'ProductController#show' );
In our routes file, we still name our parameter {product} (instead of {product-slug}) because the name of the parameter must match the name of the Eloquent model.
Using this configuration, requests made on:
www.example.com/{product-slug}
will return a product page if the provided {product-slug} matches one stored inside the database. If a product is not found, a 404 Not Found response will be returned instead.
However, because we are binding this route to the base path /, this means that every URL requested by a client will be passed through this configuration.
To avoid this problem, make sure that your route definitions are in proper order within your routes file (from greatest to least precedence), and use validation when conflicts occur.
I have difficults to create a supplementing Resource in a controller laravel and insert it in the web.php for the routing.
I would to implement a search functions, in an Articles controller .Beyond the authomatic generated function like (index, show...) i have created another one:
public function search($title){
$articles = Article::findOrFail($title);
return $articles;
}
And I have added it in the web.php for the routing:
Route::resource('articles/{title}', 'ArticleController#search');
When I try to test this search, it doesn't work. All the implicit controller go well, I have problem only with this selfmade function.
How can I solve this issue?
thanks
You need to add another route before resource one to make it work:
Route::get('articles/{title}', 'ArticleController#search');
You also want to change the query if you want to find an article by it's slug, for example:
$article = User::where('slug', $title)->first();
I'm designing a system where I need to create a comment that leaves a comment on a specific user's page.
Currently in my employercommentscontroller I have the create function
public function create($id)
{
$user = User::where('employee_id', $id)->get();
return view('comments.create', compact('user'));
}
Here is the route to this controller file
Route::resource('/reviews', 'EmployerCommentsController');
This is so that I can display information about the user that the comment is being left about. When I go to the url.
When I visit /reviews/create/2, I get a notfoundhttpexception. What do I need to change to be able to pass just the ID to my create method?
You may use:
Route::get('/reviews/create/{id}', 'EmployerCommentsController#create');
For further information: https://laravel.com/docs/5.1/routing
If you don't want to create additional routes and you want to use standard RESTful controller, you can just create link with GET parameter:
Write a comment
And then get this parameter in controller:
public function create()
{
$id = request()->input('id');