Skip to content

Commit fc6bcc5

Browse files
authored
Adds related posts section to posts.show (#364)
1 parent 1bae4b2 commit fc6bcc5

4 files changed

Lines changed: 53 additions & 0 deletions

File tree

app/Http/Controllers/PostController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public function show(Post $post): View
1818

1919
return view('posts.show', [
2020
'post' => $post,
21+
'relatedPosts' => $post->relatedPosts(),
2122
]);
2223
}
2324
}

app/Http/Controllers/PostPreviewController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public function __invoke(Request $request, Post $post): View
1919

2020
return view('posts.show', [
2121
'post' => $post,
22+
'relatedPosts' => collect(),
2223
]);
2324
}
2425
}

app/Models/Post.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use App\Models\Concerns\Tweetable;
99
use Illuminate\Database\Eloquent\Builder;
1010
use Illuminate\Database\Eloquent\Casts\Attribute;
11+
use Illuminate\Database\Eloquent\Collection;
1112
use Illuminate\Database\Eloquent\Factories\HasFactory;
1213
use Illuminate\Database\Eloquent\Model;
1314
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -175,6 +176,31 @@ public function toSitemapTag(): Url
175176
->setPriority(0.1);
176177
}
177178

179+
/**
180+
* Get related posts based on shared tags.
181+
*
182+
* @return Collection<int, Post>
183+
*/
184+
public function relatedPosts(): Collection
185+
{
186+
if ($this->tags->isEmpty()) {
187+
return self::query()
188+
->wherePublished()
189+
->where('id', '!=', $this->id)
190+
->latest('published_at')
191+
->limit(3)
192+
->get();
193+
}
194+
195+
return self::query()
196+
->wherePublished()
197+
->where('id', '!=', $this->id)
198+
->withAnyTags($this->tags)
199+
->latest('published_at')
200+
->limit(3)
201+
->get();
202+
}
203+
178204
/**
179205
* The attributes that should be cast.
180206
*

resources/views/posts/show.blade.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,30 @@
2121
<section class="markup images-centered border-neutral-700 border-t pt-8">
2222
@markdown($post->text ?? '')
2323
</section>
24+
25+
@if($relatedPosts->isNotEmpty())
26+
<section class="border-neutral-700 border-t pt-8 mt-8">
27+
<h3 class="text-xl text-neutral-200 font-medium mb-6">Related Posts</h3>
28+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
29+
@foreach($relatedPosts as $relatedPost)
30+
<a href="{{ route('posts.show', $relatedPost) }}" class="block group">
31+
@if($relatedPost->getFirstMedia('thumbnail'))
32+
<img
33+
src="{{ $relatedPost->getFirstMedia('thumbnail')->getUrl('thumbnail') }}"
34+
alt="{{ $relatedPost->title }}"
35+
class="w-full h-40 object-cover rounded-lg mb-3"
36+
>
37+
@else
38+
<div class="w-full h-40 bg-neutral-800 rounded-lg mb-3 flex items-center justify-center">
39+
<span class="text-neutral-500 text-sm">No image</span>
40+
</div>
41+
@endif
42+
<h4 class="text-neutral-200 group-hover:text-ocean transition-colors">{{ $relatedPost->title }}</h4>
43+
<span class="text-sm text-neutral-400">{{ $relatedPost->published_at->format('d M Y') }}</span>
44+
</a>
45+
@endforeach
46+
</div>
47+
</section>
48+
@endif
2449
</div>
2550
</x-app-layout>

0 commit comments

Comments
 (0)