I have this function, where i get my categories base on their slug
public function postcategoryposts($slug){
$category = PostCategory::where('slug','=',$slug)->firstOrFail();
return view('front.postcategory-posts', compact('category'));
}
Currently i'm getting my each category posts in blade like:
#foreach($category->posts as $post)
{{$post->title}}
#endforeach
until here everything is normal, the problem is how to divide my posts into pages? I am not able to use:
$category = PostCategory::where('slug','=',$slug)->paginate(10);
because I'm using
firstOrFail();
any idea?
You need to add a function to your model to get posts and then paginate.
In your controller
public function postcategoryposts($slug)
{
$category = PostCategory::where('slug','=',$slug)->firstOrFail();
$posts = $category->getPaginatedPosts(10);
return view('front.postcategory-posts', compact('posts'));
}
In your model
// PostCategory model
public function getPaginatedPosts($limit = 10)
{
// Get category posts using laravel pagination method
return Post::where('category_id', '=', $this->id)->paginate($limit);
}
In your blade view
<div class="container">
#foreach ($posts as $post)
{{ $post->title }}
#endforeach
</div>
{{ $posts->render() }}
More informations about Laravel pagination here
Hope it's helps you :)
Related
Am trying to display all the category in the database on single post blade, however, am also display five out the category in the database as my navigation menu. I am not sure maybe its the loop I am using as I keep getting five categories instead of all categories.
public function index()
{
return view('index')->with('title', Setting::first()->site_name)
->with('categories', Category::take(5)->get())
->with('first_post', Post::orderBy('created_at', 'desc')->first())
->with('second_post', Post::orderBy('created_at', 'desc')->skip(1)->take(1)->get()->first())
->with('third_post', Post::orderBy('created_at', 'desc')->skip(2)->take(1)->get()->first())
->with('wordpress', Category::find(4))
->with('laravel', Category::find(3))
->with('settings', Setting::first());
}
Here is the code for my single post controller
public function singlePost($slug)
{
$post = Post::where('slug', $slug)->first();
$next_id = Post::where('id', '>', $post->id)->min('id');
$prev_id = Post::where('id', '<', $post->id)->max('id');
return view('single')->with('post', $post)
->with('title', $post->title)
->with('settings', Setting::first())
->with('categories', Category::all())
->with('next', Post::find($next_id))
->with('prev', Post::find($prev_id))
->with('tags', Tag::all())
->with('first_post', Post::orderBy('created_at', 'desc')->first())
->with('second_post', Post::orderBy('created_at', 'desc')->skip(1)->take(1)->get()->first())
->with('third_post', Post::orderBy('created_at', 'desc')->skip(2)->take(1)->get()->first());
}
This is how I passed the value in the single.blade.php
#foreach($categories as $category)
<div class="post-category-wrap">
<div class="category-post-item">
<!-- <span class="post-count">168</span> -->
<a href="{{route('category.single', ['id' => $category->slug])}}" class="category-title">{{$category->name}}
<i class="seoicon-right-arrow"></i>
</a>
</div>
</div>
#endforeach
I think you should change the var name in index query for 'categories'. Something like
->with('categories_to_navigation', Category::take(5)->get()).
If the view single.blade.php extend index.blade.php this var names are being overwritten.
Here's the controller file code:
public function viewpost($url)
{
$url ='articles/'.$url;
if(count(posts::where('url', '=', $url)->first())<>1) {
return redirect()->back();
}
$posts = posts::all();
return view('viewpost')->with([
'posts' => posts::all(),
'post' => posts::where('url', '=', $url)->first()
]);
}
The normal URL of a post is supposed to be website.com/articles/name-of-post-here. In the sidebar, the posts are now being displayed as website.com/articles/articles/name-of-post-here
Example of a live post:
https://collegeconnect.ph/articles/how-to-improve-your-study-habits
Also, some of the posts have the status of "trashed" in the database. How can I only display posts with the stats of "active"?
My view code:
#foreach($posts as $post)
<p><img style="width:100px;" src="{{asset('thumbnails/'.$post->thumbnail)}}" class="responsive"><br>
{{substr(($post->title),0,88)}}..</p>
</tr>
#endforeach
Your making 4 database calls in your example, Better to just get the data once from the DB and work with the data.
Also I would be getting post id, Allot cleaner. But if you want name you can change id to name.
in routes/web.php
Route::get('/articles/{url}', 'Auth\HomeController#viewpost');
in Controller
public function viewpost($url){
$url = 'articles/'.$url;
$posts = posts::where('post_status', '')->get();
$post = $posts->where('url', $url)->first()
if ( empty($post) )
return redirect()->back();
return view('viewpost')->with('post', $post)->with('posts', $posts);
Then in view $post will be available eg
<h1>{{ $post->title }}</h1>
Then in the foreach $posts loop in the view change it to
<img style="width:100px;" src="{{asset('thumbnails/'.$post->thumbnail)}}" class="responsive">
I was trying to paginate some data with Query builder with the following query.
public function productSearch(Request $request)
{
$name = $request->name;
$products = DB::table('products')
->where('name', 'LIKE', "%$name%")
->paginate(4);
return view('product',compact('products');
}
But when I tried to show the pagination in the view page with the following line
{{ $products->links() }}
It shows
Method links does not exist
What could the possible error be since the pagination does not show?
2 types to print pagination link in laravel -
Try with -
use Illuminate\Support\Facades\DB;
public function productSearch(Request $request)
{
$name = $request->name;
$products = DB::table('products')
->where('name', 'LIKE', "%$name%")
->paginate(4);
return view('product',['products' => $products]);
}
In View -
<div class="container">
#foreach($products as $product)
<h4>{{ $product['name'] }}</h5> <br>
#endforeach
</div>
1st type to defined laravel pagination link -
{{ $products->links() }}
And 2nd type to defined laravel pagination link -
{{ $products->render(); }}
Note - Also you missed in your code -> return view('product',compact('products')); in return view('product',compact('products');
Here is your solution.
Just change your return view option
return view('product')->with('products', $products);
Hope this helps you.
Change to :
return view('product',compact('products'));
In View page try :
{{$products->render()}}
In your Controller:
return view('product',compact('products');
In your View:
#foreach($products as $product)
{{ $product->name }}
#endforach
{{ $products->links() }}
try with:
{{ $products->render() }}
I am a beginner in laravel so please excuse me if this is a simple question
I am trying to pass a db variable through my url so e.g blog?=category
It displays all results but when i change the url to blog/category1 it doesn't display anything.
DB Fields:id,category, name
1 category1 test
This is in my routes:
Route::get( '/blog', 'BlogController#index' );
Route::get('/', 'HomeController#index');
Route::get('blog/{category}', function($category = null)
{
// get all the blog stuff from database
// if a category was passed, use that
// if no category, get all posts
if ($category)
$posts = Post::where('category', '=', $category);
else
$posts = Post::all();
// show the view with blog posts (app/views/blog.blade.php)
return View::make('blog.index')
->with('posts', $posts);
});
BlogController
class BlogController extends BaseController {
public function index()
{
// get the posts from the database by asking the Active Record for "all"
$posts = Post::all();
// and create a view which we return - note dot syntax to go into folder
return View::make('blog.index', array('posts' => $posts));
}
}
This is my view layout:
#extends('base')
#section('content')
#foreach ($posts as $post)
<h2>{{ $post->id }}</h2>
<p>{{ $post->name }}</p>
#endforeach
#stop
Thanks
You need to add ->get() after your Eloquent query to fetch the results.
Route::get('blog/{category}', function($category = null)
{
// get all the blog stuff from database
// if a category was passed, use that
// if no category, get all posts
if ($category)
$posts = Post::where('category', '=', $category)->get();
else
$posts = Post::all();
// show the view with blog posts (app/views/blog.blade.php)
return View::make('blog.index')->with('posts', $posts);
});
I would like to be able to display different content depending on which variable is called in the url.Ignoring the fact $slug is slug, let's say it's a post id instead so if $id is active then show just the post else if $month is active show all posts from that month elseif $month and $id = null show all. That's what I'm trying to achive
Routes.php
Route::get('blog/{slug}', ['as' => 'blog.slug', 'uses' => 'BlogController#getSlug']);
Route::get('blog/{month}', ['as' => 'blog.slug', 'uses' => 'BlogController#getSlug']);
BlogController.php
<?php
class BlogController extends BaseController {
public function BlogIndex()
{
//get the posts from the database by asking the Active Record for "all"
$blogs = Blog::all();
$blogs = DB::table('blogs')->paginate(3);
// and create a view which we return - note dot syntax to go into folder
return View::make('pages.blog', array('blogs' => $blogs));
}
public function ShowbySlug($slug)
{
$blogs = Blog::where('slug', '=', $slug)->get();
// show the view with blog posts (app/views/pages/blog.blade.php)
return View::make('pages.blog')
->with('slug', $slug)
->with('blogs', $blogs);
}
public function ShowbyMonth($month)
{
$blogs = Blog::where('month', '=', $month)->get();
// show the view with blog posts (app/views/pages/blog.blade.php)
return View::make('pages.blog')
->with('month', $month)
->with('blogs', $blogs);
}
}
blog.blade.php
#foreach ($blogs as $blog)
#if(isset($blogs))
<div class="blog-outer-wrap">
<img src="images/blog/{{ $blog->img}}">
<div class="blog-header">{{ $blog->header }}</div>
<div class="blog-text">{{ $blog->content }}</div>
<a href="{{ URL::route('blog.slug', [$blog->slug]) }}">
</div>
#elseif(isset($slug))
<div class="blog-outer-wrap">
<img src="images/blog/{{ $blog->img}}">
<div class="blog-header">{{ $blog->header }}</div>
<div class="blog-text">{{ $blog->content }}</div>
</div>
#endif
#endforeach
You really can't do that, because you just declared the same route twice. When you say a route is blog/{slug}, slug is only a placeholder. It's exactly the same¹ as blog/{month}. All it says is: "I expect blog/ followed by anything." It doesn't matter if you call your anything slug or month. That is, the parameters do not add up.
What you can do is, if you consider slug is always a string and month is always a number (or the name of the month²), is to apply where clauses to your route parameters, like so:
// Route for all blog posts
Route::get('blog', 'BlogController#showAll');
// Route for all blog posts in a month; only numbers as parameters
Route::get('blog/{month}', 'BlogController#showByMonth')
->where('month', '[0-9]+');
// Route for all blog posts by title; anything else as parameters
Route::get('blog/{slang}', 'BlogController#showBySlang');
And on your controller, define three methods, one for each route:
public function showAll() {
$blogs = Blog::all();
return View::make('pages.blog')
->with('blogs', $blogs);
}
public function showByMonth($month) {
$blogs = Blog::where('month', $month)
->get();
return View::make('pages.blog')
->with('blogs', $blogs);
}
public function showBySlug($slug) {
$blogs = Blog::where('slug', $slug)
->get();
return View::make('pages.blog')
->with('blogs', $blogs);
}
¹ Unless you're using some more advanced routing features, but that's not really the point here.
² It is doable with the where clause, but it would be ugly if you wanted to consider all upper/lower case combinations. E.g: ([Jj][Aa][Nn][Uu][Aa][Rr][Yy]|[Ff][Ee][Bb][Rr][Uu][Aa][Rr][Yy]|...)