94 lines
2.9 KiB
PHP
94 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Enums\PostStatus;
|
|
use App\Models\Category;
|
|
use App\Models\Post;
|
|
use App\Models\Tag;
|
|
use Illuminate\Contracts\View\View;
|
|
use Illuminate\Http\Response;
|
|
|
|
class BlogController extends Controller
|
|
{
|
|
public function index(): View
|
|
{
|
|
$posts = Post::published()
|
|
->with(['category', 'tags', 'user'])
|
|
->latest('published_at')
|
|
->paginate(10);
|
|
|
|
return view('blog.index', [
|
|
'posts' => $posts,
|
|
'title' => config('app.name').' — AI Tools Directory & Blog for Developers',
|
|
'description' => 'Discover and compare AI tools, plus in-depth articles on AI-assisted development, automation, and building with AI agents.',
|
|
'canonical' => route('blog.index'),
|
|
]);
|
|
}
|
|
|
|
public function show(Post $post): View
|
|
{
|
|
abort_unless($post->status === PostStatus::Published && $post->published_at?->isPast(), 404);
|
|
|
|
$post->load(['category', 'tags', 'user']);
|
|
|
|
return view('blog.show', [
|
|
'post' => $post,
|
|
'title' => $post->meta_title ?: $post->title,
|
|
'description' => $post->meta_description ?: $post->excerpt_or_summary,
|
|
'canonical' => route('blog.show', $post),
|
|
'image' => $post->featured_image ? asset('storage/'.$post->featured_image) : null,
|
|
'type' => 'article',
|
|
]);
|
|
}
|
|
|
|
public function category(Category $category): View
|
|
{
|
|
$categoryIds = $category->children()->pluck('id')->push($category->id);
|
|
|
|
$posts = Post::published()
|
|
->whereIn('category_id', $categoryIds)
|
|
->with(['category', 'tags', 'user'])
|
|
->latest('published_at')
|
|
->paginate(10);
|
|
|
|
return view('blog.category', [
|
|
'category' => $category,
|
|
'posts' => $posts,
|
|
'title' => $category->meta_title ?: $category->name.' — '.config('app.name'),
|
|
'description' => $category->meta_description ?: $category->description,
|
|
'canonical' => route('blog.category', $category),
|
|
]);
|
|
}
|
|
|
|
public function tag(Tag $tag): View
|
|
{
|
|
$posts = $tag->posts()
|
|
->published()
|
|
->with(['category', 'tags', 'user'])
|
|
->latest('published_at')
|
|
->paginate(10);
|
|
|
|
return view('blog.tag', [
|
|
'tag' => $tag,
|
|
'posts' => $posts,
|
|
'title' => '#'.$tag->name.' — '.config('app.name'),
|
|
'description' => 'Posts tagged with '.$tag->name.'.',
|
|
'canonical' => route('blog.tag', $tag),
|
|
]);
|
|
}
|
|
|
|
public function feed(): Response
|
|
{
|
|
$posts = Post::published()
|
|
->with('user')
|
|
->latest('published_at')
|
|
->limit(20)
|
|
->get();
|
|
|
|
$xml = view('blog.feed', ['posts' => $posts])->render();
|
|
|
|
return response($xml, 200)->header('Content-Type', 'application/rss+xml; charset=UTF-8');
|
|
}
|
|
}
|