본문으로 건너뛰기

공개 블로그 화면

공개 블로그 화면은 로그인하지 않은 방문자도 볼 수 있는 영역입니다.

담당 컨트롤러는 다음 파일입니다.

app/Http/Controllers/PostController.php

글 목록 흐름

방문자가 / 또는 /posts에 접속하면 index()가 실행됩니다.

public function index()
{
$posts = Post::where('is_published', true)
->with('category')
->latest('published_at')
->paginate(10);

$categories = Category::withCount(['posts' => function ($query) {
$query->where('is_published', true);
}])->orderBy('name')->get();

$activeCategory = null;

return view('posts.index', compact('posts', 'categories', 'activeCategory'));
}

글 목록 쿼리 해석

Post::where('is_published', true)

공개 글만 가져옵니다.
비공개 글은 관리자 화면에서는 보이지만 방문자 화면에는 보이지 않습니다.

->with('category')

글에 연결된 카테고리 정보를 함께 가져옵니다.
이렇게 하면 목록에서 $post->category->name을 사용할 수 있습니다.

->latest('published_at')

발행일 기준 최신순으로 정렬합니다.

->paginate(10)

한 페이지에 10개씩 보여줍니다.

카테고리 필터 흐름

방문자가 카테고리 버튼을 누르면 /categories/{slug}로 이동합니다.

public function category(string $slug)
{
$activeCategory = Category::where('slug', $slug)->firstOrFail();

$posts = Post::where('is_published', true)
->where('category_id', $activeCategory->id)
->with('category')
->latest('published_at')
->paginate(10);

$categories = Category::withCount(['posts' => function ($query) {
$query->where('is_published', true);
}])->orderBy('name')->get();

return view('posts.index', compact('posts', 'categories', 'activeCategory'));
}

여기서 중요한 코드는 이것입니다.

Category::where('slug', $slug)->firstOrFail();

slug에 맞는 카테고리를 찾습니다.
없으면 Laravel이 자동으로 404 페이지를 보여줍니다.

->where('category_id', $activeCategory->id)

해당 카테고리에 속한 글만 가져옵니다.

카테고리 글 수

목록 위에는 카테고리 버튼과 글 개수가 표시됩니다.

Category::withCount(['posts' => function ($query) {
$query->where('is_published', true);
}])

이 코드는 각 카테고리마다 공개 글 수를 posts_count로 붙여줍니다.

Blade에서는 이렇게 출력합니다.

{{ $category->posts_count }}

글 목록 Blade

글 목록 화면 파일은 다음입니다.

resources/views/posts/index.blade.php

이 화면은 두 가지 상황에서 재사용됩니다.

상황$activeCategory
전체 글 목록null
카테고리별 글 목록선택된 Category 객체

카테고리가 선택되었을 때만 제목과 설명을 보여줍니다.

@if($activeCategory)
<h1>{{ $activeCategory->name }}</h1>
<p>{{ $activeCategory->description }}</p>
@endif

글 상세 흐름

방문자가 글 제목을 누르면 /posts/{slug}로 이동합니다.

public function show(string $slug)
{
$post = Post::where('slug', $slug)
->where('is_published', true)
->with(['category', 'tags'])
->firstOrFail();

return view('posts.show', compact('post'));
}

중요한 점은 where('is_published', true)입니다.
비공개 글은 URL을 직접 알아도 볼 수 없습니다.

글 상세 Blade

상세 화면 파일은 다음입니다.

resources/views/posts/show.blade.php

글 제목은 안전하게 출력합니다.

{{ $post->title }}

본문은 HTML로 저장되어 있으므로 그대로 출력합니다.

{!! $post->content !!}
HTML 출력 주의

{!! !!}는 HTML을 이스케이프하지 않고 그대로 출력합니다.
관리자만 글을 작성하는 현재 구조에서는 편리하지만, 일반 사용자 입력을 받게 되면 XSS 보안 처리가 필요합니다.