Generate post slug and route on Laravel 5.5 - php

I'm creating a blog post with Laravel 5.5. Here I want to auto-generate accessible slug for a post upon saving. What I did here was:
'slug' => str_slug(request('title'))
It generates the slug value but the page url is not working. For e.g if I click 127.0.0.1:8000/title it should redirect me.
Controller
public function save(Request $request, Post $post)
{
$post= new Post;
$post->title = request('title');
$post->slig => str_slug(request('title'));
$post->save();
}
Route
Route::post('/', 'PostsController#save')->name('add_post');

we store the title and replace every space to dash '-' to auto-generate accessible slug for a post upon saving on this steps :
i use this code on controller
public function store(Request $request){$post->slug = str_replace(' ','-',strtolower($post->title));}
and on
public function show($slug)
{
//
$post=Post::where('slug',$slug)->first();
return view('posts.show', compact('post'));
}
and edit post link like this
link

I would look at using one of the Sluggable packages. https://packagist.org/?q=sluggable I have used the one by Spatie before and it works well.
Once you create your new entity/model and you then have a slug you will need to create a route to a controller which looks up the entity using the slug field.
$thing = Thing::whereSlug($request->get('slug'))->firstOrFail();

Related

Laravel CRUD - Update doesn't work - doesn't make changes

Everything works great in CRUD, except for update.
My Controller:
public function update(Request $request, $id)
{
$post = Post::findOrFail($id);
$post->update($request->all());
return redirect('/posts');
}
To answer this you need to know if that id is coming through properly.
Do a dump($id); This will show you if it's null or something unexpected.
I'd then wrap the $post in logic to rule out nulls or bad data.
Technically if you are doing a post from the front your id will usually be
$request->id this being sent from a hidden input on the front.
I'd also use a first() because everything coming to this function should already be created and not be null since you're populating this from the database.
$post = Post::where('id', $request->id)->first();
Next do a dump on $post dump($post); this will show you the post info.
If you don't have any post info you have trouble and will require more troubleshooting.
Then you can just do your save process, I personally like to to do a 1 to 1 save to make sure all values from the request are being properly handled. So it would be..
$post->column_name = $request->input_name;
$post->save();
return back()->with ('status', 'Record Updated!');
Then on the front you can display that status from session to show it was updated.
One caveat using mass update is that you should make sure that the fields you are updating are fillable in the model.
You need check your model at the first it should be something like this:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Crud extends Model
{
protected $fillable = [
'first_name', 'lastame', 'id',
];
}
then you have to use
dd('$post')
to see what you have then you can create your update like this:
public function update(Request $request, $id)
{
$post = Post::findOrFail($id);
$post->update($request->all());
return redirect('/posts')->with('success', 'Data is successfully updated');;
}

how to get a post id using post link in laravel

Am trying to update a record in my database using an update button that is linked to a page where the update form is located but each time I click on the button, I get a 404 error (I think maybe the problem is that the page could not read the id of the requested post).
This is my route
Route::get('/pages/update/{id}','CallsController#edit');
Route::post('/pages/update/{id}','CallsController#update');
My CallsController
public function edit($id)
{
// $calls = Call::where('user_id', auth()->user()->id)->where('id', $id)->first();
// return view('pages.assignCall', compact('calls', 'id'));
$calls = Call::find($id);
return view('pages.assignCall')->with('calls', $calls);
}
public function update(Request $request, $id)
{
$calls = new Call();
$data = $this->validate($request, [
'call_details'=>'required',
]);
$data['id'] = $id;
$calls->updateCall($data);
return redirect('pages.pendingCalls');
}
I also have update.blade.php in the pages folder inside my views.
This is my update button
<a href="{{asset('/pages/update')}}>update</a>
You should not use the asset helpers to generate urls, but the url helpers. Also, you have to pass the id of the item you want to update. Because this is missing, you get a 404.
You should do something like this:
update
You can use laravel name route. If you use name route then your route should look like this
Route::get('/pages/update/{id}','CallsController#edit')->name('pages.update.view');
Route::post('/pages/update/{id}','CallsController#update')->name('pages.update');
And your update button should look like this
update

Trying to make SEO friendly urls without using database

I'm building my first Laravel app. I have posts that belongs to different categories.
I'm trying to make SEO friendly urls /categories/category_name for categories without saving a 'slug' in database.
Here is what I came with so far:
My category model:
class Category extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
public function getSlugAttribute(): string
{
return str_slug($this->name);
}
public function getUrlAttribute(): string
{
return action('CategoriesController#index', [$this->id, $this->slug]);
}
}
My category controller
class CategoriesController extends Controller
{
public function index($id, $slug = '')
{
$posts = Category::findOrFail($id)->posts;
return view('index', compact('posts'));
}
}
My route:
Route::get('/categories/{slug}', 'CategoriesController#index')->name('category');
With {{ $post->category->url }} I get something like http://localhost/category/1?alpha but it works and display the appropriate posts. Route is returning an error.
How I get ride of the id? and make the route works?
Thank you in advance for your help!
I'm assuming that you have a human readable category name (ex My Category) and you are converting that to a slug in your URLs (ex my-category).
A naive approach to doing this would be to attempt to reverse the slug and lookup the category by name, but there are use-cases where this won't work.
class CategoriesController extends Controller
{
public function index($slug)
{
$name = ucwords(str_replace('-', ' ', $slug));
$posts = Category::where('name', '=', $name)->first()->posts;
return view('index', compact('posts'));
}
}
The problem with that approach is there are cases where information is lost when converting the name to a slug, for example if the proper category name contains a hyphen, the hyphen becomes a space when converting the resulting slug.
You can approach this a different way, without storing the slug, by modifying your route:
Route::get('/categories/{category}/{slug}', 'CategoriesController#index')->name('category');
In this case, you pass both the ID and the slug in the URL. You can either fetch the category from the ID or use route model binding to fetch it automatically. This technically means you can pass any string as the slug and it will still work. You can handle this by determining the actual slug and redirecting to the canonical URL if the end user provides an incorrect slug.
class CategoriesController extends Controller
{
public function index(Category $category, $slug)
{
if(str_slug($category->name) != $slug) {
// Redirect to the canonical URL
}
$posts = $category->posts;
return view('index', compact('posts'));
}
}
A benefit of keeping both the ID and the slug in the URL is you get redirection for free: If the category name changes, the new URL will work and the old URL will automatically redirect to the new one.
Side note: If you look the URL for his question you'll notice this is the approach StackOverflow uses.
I don't think this is possible. The reason behind is that you will need to search for the category using the slug but is not stored in the database, so you will need to convert the slug to its original value.
For example, if you have a category named "Modern art", the slug would look something like modern-art. If you pass that slug to your controller, you need to convert it back to "Modern art" to be able to retrieve the category by its name. But maybe the real name was "Modern Art" or "Modern art!" or something else.
I recommend you storing the slug in the database.

Resource route (edit ) redirecting to 404 page laravel

I've created a resource
Route::resource('page-category', 'PageCategoryController',['except'=>['create'] ]);
code in view:
Edit
and my edit method in PageCategoryController.php
public function edit($id)
{
$pcategory = PageCategory::find($id);
return view('admin.page-category.show')->withPcategory($pcategory);
}
when i click the button in the view it redirectes to my 404 view. When i hover over the button the link is like http://localhost:8000/page-category//edit . When i manually insert id number in link http://localhost:8000/page-category/1/edit it does takes me to edit page.
Try this according to routing guide on https://laravel.com/docs/5.4/controllers#resource-controllers
Edit
What if your controller becomes:
public function edit($id) {
$pcategory = PageCategory::find($id);
return view('admin.page-category.show')->compact('pcategory');
}
So this will send the $pcategory, in this case your page category with the id ($id), to your view.
From there you'll be able access to your route page-category.edit by sending it the id of the page category: $pCategory->id just like you did.

Laravel 4: Add Database Record and Redirect to Edit View with New Record ID

Brand new to Laravel!
As my title states I would like to be able to immediately redirect from storing a database record to its edit view.
I have a controller called PlannerController. Within this controller I have the standard store() and edit($id) methods. Here is the code for my store() method:
public function store()
{
$newIncome = new Income('fin_income');
$newIncome->user_id = '1';
$newIncome->income_id = Input::get('categories');
$newIncome->income_desc = "Test YO!";
$newIncome->income_date = date('Y-m-d');
$newIncome->amount = Input::get('amount');
$newIncome->save();
return Redirect::route('planner.edit');
}
When I redirect to the planner.edit view (the edit($id) controller method) I have not been able to figure out how to carry over the fin_income.id field, which is auto_incremented upon addition to the database. When I do the redirect like this, my redirect url is /planner/{planner}/edit.
Obviously I need something extra in the store() method but what is the best way to go about this?
have you tried:
return Redirect::route('planner.edit', ['id' => $newIncome->id]);
after you save() on the model, the auto incremented value will be set on your primary key property.

Categories