Mostrando el detalle de un post
Creo una ruta en web.php
para mostrar el detalle de un post.
web.php
1
|
Route::get('posts/{post}', [PostController::class, 'show'])->name('posts.show');
|
Creo en método show
en el controllador PostController.php
al que le paso como parámetro un objeto post. Dentro de el recupero los post que pertenecen a la misma categoría que el en la variable $similares
y se los paso junto con la variable $post
a la vista posts.show
.
PostController.php
1
2
3
4
5
6
7
8
9
10
11
|
public function show(Post $post)
{
$similares = Post::where('category_id', $post->category_id)
->where('status', 2)
->where('id', '!=', $post->id)
->latest('id')
->take(4)
->get();
return view('posts.show', compact('post', 'similares'));
}
|
Creo la vista laravel/blog_laravel/resources/views/posts/category.blade.php
. Dentro de ella extiendo la plantilla principal muestro un listado paginado de los posts asociados a la categoría correspondiente.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<x-app-layout>
<div class=" micontainer py-8">
<h1 class=" text-4xl font-bold text-gray-600">{{$post->name}}</h1>
<div class=" text-lg text-gray-500 mb-2">
{{$post->extract}}
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
{{-- Contenido principal --}}
<div class=" lg:col-span-2">
<figure>
<img class=" w-full h-80 object-cover object-center" src="{{Storage::url($post->image->url)}}" alt="">
</figure>
<div class=" text-base text-gray-500 mt-4">
{{$post->body}}
</div>
</div>
{{-- Contenido relacionado--}}
<aside>
<h1 class=" text-2xl font-bold text-gray-600 mb-4">Más en: {{$post->category->name}}</h1>
<ul>
@foreach ($similares as $similar)
<li class=" mb-4">
<a class="flex" href="{{Route('posts.show', $similar)}}">
<img class=" w-40 h-20 object-cover object-center " src="{{Storage::url($similar->image->url)}}" alt="">
<span class=" ml-2 text-gray-600">{{$similar->name}}</span>
</a>
</li>
@endforeach
</ul>
</aside>
</div>
</div>
</x-app-layout>
|
Para poder mostrar el detalle del post debo añadir la ruta al enlace de cada post en el listado de la vista resources/views/posts/index.blade.php
index.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<x-app-layout>
<div class="micontainer py-8">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@foreach ($posts as $post)
<article class=" w-full h-80 bg-cover bg-center @if($loop->first) md:col-span-2 @endif" style="background-image: url({{Storage::url($post->image->url)}})">
<div class=" w-full h-full px-8 flex flex-col justify-center">
<div>
@foreach ($post->tags as $tag)
<a href="" class=" inline-block px-3 h-6 bg-{{$tag->color}}-600 text-white rounded-full">{{$tag->name}}</a>
@endforeach
</div>
<h1 class=" text-4xl text-white leading-8 font-bold">
{{-- Enlace al detalle del post--}}
<a href="{{route('posts.show', $post)}}">
{{$post->name}}
</a>
</h1>
</div>
</article>
@endforeach
</div>
<div class=" mt-4">
{{$posts->links()}}
</div>
</div>
</x-app-layout>
|
Filtrando post por categorías
Creo una ruta en web.php
para mostrar los post por categorías
web.php
1
|
Route::get('category/{category}', [PostController::class, 'category'])->name('posts.category');
|
Creo el método category
en el controlador PostController.php
al que le paso como parámetro un objeto de la clase category
. Dentro de el recupero todos los posts que pertenecen a la categoría y se los paso en la variable $posts
junto con la variable $category
a la vista posts.category
.
PostController.php
1
2
3
4
5
6
|
public function category(Category $category)
{
$posts = Post::where('category_id', $category->id)->where('status', 2)->latest('id')->paginate(5);
return view('posts.category', compact('posts', 'category'));
}
|
Creo la vista laravel/blog_laravel/resources/views/posts/category.blade.php
. Dentro de ella extiendo la plantilla principal muestro un listado paginado de los posts asociados a la categoría correspondiente.
category.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<x-app-layout>
<div class=" max-w-5xl mx-auto px-2 sm:px-6 lg:px-8 py-8">
<h1 class=" uppercase text-center text-3xl font-bold">Categoria: {{$category->name}}</h1>
@foreach ($posts as $post)
<article class="mb-8 bg-white shadow-lg rounded-lg overflow-hidden">
<img class=" w-full h-72 object-cover object-center" src="{{Storage::url($post->image->url)}}" alt="">
<div class="px-6 py-4">
<h1 class=" font-bold text-xl mb-2">
<a href="{{route('posts.show', $post)}}">{{$post->name}}</a>
</h1>
<div class=" text-gray-700 text-base">
{{$post->extract}}
</div>
</div>
<div class="px-6 pt-4 pb-2">
@foreach ($post->tags as $tag)
<a href="" class=" inline-block bg-gray-200 rounded-full px-3 py-1 text-sm text-gray-700 mr-2">{{$tag->name}}</a>
@endforeach
</div>
</article>
@endforeach
<div class=" mb-4">
{{$posts->links()}}
</div>
</div>
</x-app-layout>
|
Para poder acceder a la ruta debo de añadir el enlace en el menú navigation
desarrollado con livewire
. abro el archivo laravel/blog_laravel/resources/views/livewire/navigation.blade.php
y modifico el enlace
navigation.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
|
..............
<!-- barra de menu lg-->
<div class="hidden sm:block sm:ml-6">
<div class="flex space-x-4">
@foreach ($categorias as $categoria)
<!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
<!--<a href="#" class="bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium">Dashboard</a>-->
<a href="{{route('posts.category', $categoria)}}" class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">{{$categoria->name}}</a>
@endforeach
</div>
</div>
.....................
|
Para reutilizar mejor el código voy a llevar el código que utilizo para crear la tarjeta que muestra los post por categorías a un componente anónimo blade
, para ello creo la carpeta resources/views/components
y dentro de ella el componente resources/views/components/card-post.blade.php
.
Dentro de este componente pego el código que me genera la tarjeta de cada post y que se encontraba en category.blade.php
card-post.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<article class="mb-8 bg-white shadow-lg rounded-lg overflow-hidden">
<img class=" w-full h-72 object-cover object-center" src="{{Storage::url($post->image->url)}}" alt="">
<div class="px-6 py-4">
<h1 class=" font-bold text-xl mb-2">
<a href="{{route('posts.show', $post)}}">{{$post->name}}</a>
</h1>
<div class=" text-gray-700 text-base">
{{$post->extract}}
</div>
</div>
<div class="px-6 pt-4 pb-2">
@foreach ($post->tags as $tag)
<a href="" class=" inline-block bg-gray-200 rounded-full px-3 py-1 text-sm text-gray-700 mr-2">{{$tag->name}}</a>
@endforeach
</div>
</article>
|
Llamo al componente creado <x-card-post :post="$post"/>
desde la vista resources/views/posts/category.blade.php
category.blade.php
1
2
3
4
5
6
7
8
9
10
11
|
<x-app-layout>
<div class=" max-w-5xl mx-auto px-2 sm:px-6 lg:px-8 py-8">
<h1 class=" uppercase text-center text-3xl font-bold">Categoria: {{$category->name}}</h1>
@foreach ($posts as $post)
<x-card-post :post="$post"/>
@endforeach
<div class=" mb-4">
{{$posts->links()}}
</div>
</div>
</x-app-layout>
|
Y lo recibo en el componente card-post.blade.php
utilizando la directiva de blade @props(['post'])
.
card-post.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@props(['post'])
<article class="mb-8 bg-white shadow-lg rounded-lg overflow-hidden">
<img class=" w-full h-72 object-cover object-center" src="{{Storage::url($post->image->url)}}" alt="">
<div class="px-6 py-4">
<h1 class=" font-bold text-xl mb-2">
<a href="{{route('posts.show', $post)}}">{{$post->name}}</a>
</h1>
<div class=" text-gray-700 text-base">
{{$post->extract}}
</div>
</div>
<div class="px-6 pt-4 pb-2">
@foreach ($post->tags as $tag)
<a href="" class=" inline-block bg-gray-200 rounded-full px-3 py-1 text-sm text-gray-700 mr-2">{{$tag->name}}</a>
@endforeach
</div>
</article>
|
Ahora ya puedo aplicar este componente anónimo de blade a la plantilla que me muestre los post por etiquetas.
Filtrando post por etiquetas
Lo primero es crear una ruta en web.php
web.php
1
|
Route::get('tag/{tag}', [PostController::class, 'tag'])->name('posts.tag');
|
Luego creo el método tag
en el controlador PostController.php
al que paso como parámetro un objeto tipo tag . Dentro de el recupero coleccion de post publicados que tienen la etiqueta pasada por parametro. Por ultimo devuelvo la vista tag.blade.php
a la que paso las variables $posts
y $tag
.
PostController.php
1
2
3
4
5
6
|
public function tag(Tag $tag)
{
$posts = $tag->posts()->where('status', 2)->latest('id')->paginate(5);
return view('posts.tag', compact('posts', 'tag'));
}
|
Creo la lista resources/views/posts/tag.blade.php
dentro de la cual extiendo la plantilla principal del proyecto y muestro los posts ayudándome del componente anónimo de blade
recién creado para mostrar tarjetas <x-card-post :post="$post"/>
tag.blade.php
1
2
3
4
5
6
7
8
9
10
11
|
<x-app-layout>
<div class=" max-w-5xl mx-auto px-2 sm:px-6 lg:px-8 py-8">
<h1 class=" uppercase text-center text-3xl font-bold">Etiqueta: {{$tag->name}}</h1>
@foreach ($posts as $post)
<x-card-post :post="$post"/>
@endforeach
<div class=" mb-4">
{{$posts->links()}}
</div>
</div>
</x-app-layout>
|
Para completar este filtrado debo añadir las rutas a los enlaces en las vistas index.blade.php
y car-post.blade.php
card-post.blade.php
1
2
3
4
5
|
<div class="px-6 pt-4 pb-2">
@foreach ($post->tags as $tag)
<a href="{{route('posts.tag', $tag)}}" class=" inline-block bg-gray-200 rounded-full px-3 py-1 text-sm text-gray-700 mr-2">{{$tag->name}}</a>
@endforeach
</div>
|
index.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
..............................
@foreach ($posts as $post)
<article class=" w-full h-80 bg-cover bg-center @if($loop->first) md:col-span-2 @endif" style="background-image: url({{Storage::url($post->image->url)}})">
<div class=" w-full h-full px-8 flex flex-col justify-center">
<div>
@foreach ($post->tags as $tag)
<a href="{{route('posts.tag', $tag)}}" class=" inline-block px-3 h-6 bg-{{$tag->color}}-600 text-white rounded-full">{{$tag->name}}</a>
@endforeach
</div>
<h1 class=" text-4xl text-white leading-8 font-bold pt-2">
<a href="{{route('posts.show', $post)}}">
{{$post->name}}
</a>
</h1>
</div>
</article>
@endforeach
..................................
|