In my Laravel application, I have created url: like "www.example.com/rent/property-for-rent/45"
but here, I want to remove id from the last and concatenate id with my 2nd parameter that is, "property for rent" like : "www.example.com/rent/property-for-rent-45".
In the Controller function get 3 parameters
public function single_properties(Request $request, $property_purpose, $slug, $id)
In the Blade file
{{url(strtolower($property->property_purpose).'/'.$property->property_slug)}}
In the Web.php File
Route::get('{property_purpose}/{slug}/{id}', 'PropertiesController#single_properties');
I have tried to reduce parameter from the function, blade and route, but didn't work for me.
can anyone please help me out, I am poorly trapped in it,
you can simply do it like this:
public function singleProperties(Request $request, $property_purpose, $slug, $id)
{
// old url: example.com/rent/property-for-rent/45
// new url: example.com/rent/property-for-rent-45
$newUrl = $property_purpose . '/' . $slug . '-' . $id;
return view('your.view.blade', [
'new_url' => $newUrl,
]);
}
And in your blade call {{ $new_url }}
You can do in a simple way. As the URL is like this:-
www.example.com/rent/property-for-rent-45
Url structure for route will be like: /rent/slug-id
Means id is concatenated with slug. so laravel will consider it as full string as slug only. We will define this and later in controller will extract id from the slug.
So in routes/ web.php you can define like:-
In the Web.php File
Route::get('{property_purpose}/{slug}','PropertiesController#single_properties');
In the Blade file
{{url(strtolower($property->property_purpose).'/'.$property->property_slug-$property->property_id)}}
In Controller File You an define like:-
Here Slug variable you have to parse using known PHP function. As with the information, you know id is coming in last after - symbol. So you can explode slug variable and take the id coming last after -
public function singleProperties(Request $request, $property_purpose, $slug)
{
$slugarr=explode('-',$slug);
$id=$slugarr[count($slugarr)+1];// As index starts from 0, for getting last you have to this
//Now you got the $id you can fetch record you want this id
}
Related
Specifically, I want one class, or method, to be taking care of what's going to be in my <title> tag in app.blade.php file (the file included on every page).
You can do this with laravel sessions, firstly you can add a session variable lets say on login like this
Session::put('title', $value);
Now you can change this every time you switch the page via controller, just add this to every request and change the title as you please, and finally in your blades you can just do this
<title>{{ Session::get('title') ?? 'Login' }}</title>
I ended up using and #section('title') in every blade where I need to specify the title.
Option 1:
Generally, I use this:
In my app.blade.php
<title> {{ $title ? $title.' - ' ? '' }} website-name </title>
And in the controller files I used to return the $data array instead of the compact method:
$data['title'] = 'My title';
return view('view.name', $data);
This will automatically consider the title if you add it to your controller else it will display the website name. No need to add the "<title>" tag in every blade file.
Option 2:
Make __construct method in the controller class file.
public function __construct( Request $request )
{
$route_basename = basename(URL::current());
$this->data['title'] = \Str::title(str_replace('-', ' ', $route_basename));
}
Note: if you are using _ as the separation in the route then replace '-' with '_' in the str_replace() function.
The above code will convert your Last route segment in to the title. Example: you have admin/categories then you got the Categories as the title.
Now you need to return $this->data in the view method.
public function index()
{
// If you want to send any other data in the index view.
$this->data['categories'] = Categories::all(); // optional
return view('admin.categories.index', $this->data);
}
If you are go for the 2nd option then you don't need to declare $data['title'] in every method.
But in some cases we have id as the last route segment or any other thing that not belongs to the title at that time just overwrite the $this->data['title'] in that method or function.
I am trying to make my URL more SEO friendly on my Laravel application by replacing the ID number of a certain object by the name on the URL when going to that specific register show page. Anyone knows how?
This is what I got so far and it displays, as normal, the id as the last parameter of the URL:
web.php
Route::get('/job/show/{id}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
Controller method
public function show($id){
$job = Job::findOrFail($id);
return view('website.job')->with(compact('job'));
}
Blade page where there is the link to that page
{{$job->name}}
You can overwrite the key name of your Job model:
public function getRouteKeyName()
{
return 'name';
}
Then in your route simply use {job}:
Route::get('/job/show/{job}', ...);
And to call your route:
route('website.job.show', $job);
So your a tag would look like this:
{{ $job->name }}
Inside your controller, you can change the method's signature to receive the Job automatically:
public function show(Job $job)
{
return view('website.job')
->with(compact('job'));
}
For more information, look at customizing the key name under implicit binding: https://laravel.com/docs/5.8/routing#implicit-binding
You need simply to replace the id by the name :
Route::get('/job/show/{name}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
In the controller action:
public function show($name){
//Make sure to replace the 'name' string with the column name in your DB
$job = Job::where('name', $name)->first();
return view('website.job')->with(compact('job'));
}
Finally in the blade page :
{{$job->name}}
2 options:
1) one is like #zakaria-acharki wrote in his comment, by the name of the job and search by the name for fetching the data
2) the second is to do it like here in stackoverflow
to build the url with the id/name
in this way you will make sure to fetch and show the relevant job object by the unique ID
the route:
Route::get('/job/show/{id}/{name}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
in the controller, update the check if the name is equal to the job name (in case it was changed) to prevent duplicate pages url's
public function show($id, $name){
$job = Job::findOrFail($id);
// check here if( $job->name != $name ) {
// redirect 301 to url with the new name
// }
return view('website.job')->with(compact('job'));
}
in the blade.php :
{{$job->name}}
I have set up pagination and it's working correctly. But i am not able to redirect to the current page.
E.g: If i invoke update method on currencies?page=2. I will redirect to the currencies instead of currencies?page=2.
Controller - index function
public function index()
{
$currencies = Currency::paginate(5);
return view('admin.currencies.index')
->withCurrencies($currencies);
}
Controller - Edit function
public function edit($id)
{
$currency = Currency::findOrFail($id);
return view('admin.currencies.edit')
->withCurrency($currency);
}
Controller - Update function
public function update(Request $request, $id)
{
$currency = Currency::findOrFail($id);
$currency->name = $request->name;
$currency->rate = $request->rate;
$currency->save();
return redirect()->route('currencies.index')->with('message', 'Done');
}
Views
{{ $currencies->links() }}
Check out the documentation here https://laravel.com/docs/5.5/pagination#paginator-instance-methods
You can either keep track of the page number (from referral URL if update is on different page or from query param) and pass that along in your update function like this instead of redirecting to a route.
//$page = grab page number from the query param here.
return redirect('currencies?page='.$page);
or you can also modify your index controller where you pass the page number as optional param and if null default to page 1 and if present pass that in.
$results->url($page)
Good luck.
In case someone has to do redirection to current, or any page and works with named routes.
Tested: Laravel 5
Some assumptions out of the way.
route:
$this->get('/favourite/{columnSorted?}/{sortOrder?}', 'Favourites#index')->name('favourite.list');
assumed project url in browser:
columnSorted: 'title'
sortOrder: desc
http://yoursite.net/favourite/title/desc?page=3
Now, named route redirect to page 3.
As you can see in route above, columnSorted and sortOrder are dynamic (? after param in route, e.g.: {sortOrder?}).
What it means, is that route can have both, just one or none of them.
If you wish to pass them to param array in route, you can do something like this:
/*prep redirect to, where user was params*/
$routeParams = [];
$q = '?';
if ($request->columnSorted)
{
$routeParams['columnSorted'] = $request->columnSorted;
}
if ($request->sortOrder)
{
$routeParams['sortOrder'] = $request->sortOrder;
$q = '';
}
if ($request->page)
{
$routeParams[] = $q . 'page=' . $request->page;
}
return redirect()->route('favourite.list', $routeParams);
Note above that '$q' parameter.
Last (and only last) route parameter $q must not pass '?', or constructed route from named route will have double '??' looking like:
http://yoursite.net/favourite/title/desc??page=3
... and redirect will fail.
Page number you can get from request:
$request->get('page');
// or
$request->page
... and pass it to method that will do redirect.
You must add a query string parameter to the route.
return redirect()
->route('currencies.index', ['page' => $request->get('page', 1)])
->with('message', 'Done');
in my controller in my show function in laravel i want the get the id that shows in browser show when i browse it it shows like this
http://localhost:8000/admin/invoices/1
i want to get that "1" and use it in show controller like below
public function show(Invoice $invoice)
{
$clients = Invoice::with('user','products')->get();
$invoice_id = 1;
$invoices = Invoice::with('products')->where('id', '=', $invoice_id)->firstOrFail();
return view('admin.invoices.show', compact('invoice','invoices'),compact('clients'));
}
and put it instead of $invoice_id so when every my client visit this page only sees the related invoice products . thanks you for help
If you're actually getting an instance of Invoice passed to your show method then it likely means you have Route-Model Binding set up for your project. Laravel is looking at the defined route and working out that the ID part (1) should map to an instance of Invoice and is doing the work to grab the record from the database for you.
The Invoice object passed through should refer to an item in your database with the ID of 1, so to get the ID that was mapped in the route you can simply just do:
public function show(Invoice $invoice)
{
echo $invoice->id; // This should be 1
Laravel supports route model binding out of the box these days, but in earlier versions you had to set it up in app/Providers/RouteServiceProvider.php. If you don't want it, try replacing your show method signature with this:
public function show($id)
{
echo $id; // Should be 1
By removing the type-hint you're simply expecting the value that was given in the route parameter and Laravel won't try to resolve it out of the database for you.
Simple way you may try this.
//Define query string in route
Route::get('admin/invoice/{id}','ControllerName#show')
//Get `id` in show function
public function show(Invoice $invoice,$id)
{
$invoice_id = $id;
}
Try using $invoiceId
public function show(Invoice $invoice, $invoiceId)
{
$clients = Invoice::with('user','products')->get();
$invoices = Invoice::with('products')->findOrFail($invoiceId);
return view('admin.invoices.show', compact('invoice','invoices'),compact('clients'));
}
do this if you want to get the url segment in controller.
$invoice_id = request()->segment(3);
if you want this in view
{{ Request::segment(3) }}
Goodluck!
Usually happens when giving a route name different from the controller name
Example:
Route::resource('xyzs', 'AbcController');
Expected:
Route::resource('abcs', 'AbcController');
I need a little help and I can’t find an answer. I would like to replicate a row from one data table to another. My code is:
public function getClone($id) {
$item = Post::find($id);
$clone = $item->replicate();
unset($clone['name'],$clone['price']);
$data = json_decode($clone, true);
Order::create($data);
$orders = Order::orderBy('price', 'asc')->paginate(5);
return redirect ('/orders')->with('success', 'Success');
}
and i got an error :
"Missing argument 1 for
App\Http\Controllers\OrdersController::getClone()"
.
I have two models: Post and Order. After trying to walk around and write something like this:
public function getClone(Post $id) {
...
}
I got another error
Method replicate does not exist.
Where‘s my mistake? What wrong have i done? Maybe i should use another function? Do i need any additional file or code snippet used for json_decode ?
First of all, make sure your controller gets the $id parameter - you can read more about how routing works in Laravel here: https://laravel.com/docs/5.4/routing
Route::get('getClone/{id}','YourController#getClone');
Then, call the URL that contains the ID, e.g.:
localhost:8000/getClone/5
If you want to create an Order object based on a Post object, the following code will do the trick:
public function getClone($id) {
// find post with given ID
$post = Post::findOrFail($id);
// get all Post attributes
$data = $post->attributesToArray();
// remove name and price attributes
$data = array_except($data, ['name', 'price']);
// create new Order based on Post's data
$order = Order::create($data);
return redirect ('/orders')->with('success', 'Success');
}
By writing
public function getClone(Post $id)
you are telling the script that this function needs a variable $id from class Post, so you can rewrite this code like this :
public function getClone(){
$id = new Post;
}
However, in your case this does not make any sence, because you need and integer, from which you can find the required model.
To make things correct, you should look at your routes, because the url that executes this function is not correct, for example, if you have defined a route like this :
Route::get('getClone/{id}','YourController#getClone');
then the Url you are looking for is something like this :
localhost:8000/getClone/5
So that "5" is the actual ID of the post, and if its correct, then Post::find($id) will return the post and you will be able to replicate it, if not, it will return null and you will not be able to do so.
$item = Post::find($id);
if(!$item){
abort(404)
}
Using this will make a 404 page not found error, meaning that the ID is incorrect.