56. Mostrar mis posts creados

En este capítulo aprenderás cómo mostrar los posts creados en tu proyecto de Laravel. Aprenderás a utilizar la sintaxis de consultas de Eloquent para recuperar los datos de la base de datos, y cómo pasar los datos recuperados a las vistas para mostrarlos en la interfaz de usuario. Además, aprenderás a paginar los resultados para mejorar el rendimiento y la experiencia del usuario, y a ordenar y filtrar los resultados para mostrarlos de manera personalizada. Al final del capítulo, tendrás una comprensión completa de cómo recuperar y mostrar posts creados en Laravel, lo que te permitirá mostrar y administrar fácilmente el contenido de tu blog.


10 comentarios

Inicia sesión para comentar

Comentarios:

  • Adrian Linares

    Adrian Linares hace 5 días

    Hola a todxs. Excelente todo el contenido, muy claro y perfectamente entendible. Muchas gracias. Quisiera hacerles una consulta, tengo este error que ocurre cuando intenta traerme la lista de posts.

    Symfony \ Component \ ErrorHandler \ Error \ FatalError

    PHP 8.1.25  y Laravel 10.48.24

    Cannot declare class App\Http\Livewire\Admin\PostsIndex, because the name is already in use

    Por lo que estuve googleando y consultando a las IAs, pueden ser que me este equivocando en el namespace, asi lo tengo ahora en el archivo PostsIndex.php

    namespace App\Http\Livewire\Admin;

    use Livewire\Component;

    use App\Models\Post;

    use Livewire\WithPagination;

    Gracias a todos por sus respuestas. 

    Saludos.

    • Adrian Linares hace 5 días

      Buenas, por si a algunx le sirve. Busque en la docs de Livewire y parece que para versiones de Laravel 10+ se usa el namespace App\Livewire, en la misma jerarquia que Http y no dentro de esta última. 

      Saludos.

  • Javier Andres Gómez

    Javier Andres Gómez hace 9 meses

    En versiones recientes de livewire al wire:model se debe agregar .live para que funcione wire:model.live="search"

    Referencia de los modificadores: https://livewire.laravel.com/docs/wire-model

    • Victor Arana Flores hace 9 meses

      Hola Javier, así es. Gracias por el aporte.

    • Sergio ┏(-_-)┛┗(-_- )┓┗(-_-)┛ hace 4 meses

      Gracias, por la ayuda

  • Walter

    Walter hace 2 años

    ? 8° Configuración de la vista del componente de Livewire 

    Editamos el archivo resources/views/livewire/admin/posts-index.blade.php

     

    Agregamos el input para filtrar los post y le agregamos el atributo wire_model="search" para usarlo en el filtro:

    <div class="card">
    
    	<div class="card-header">
    		<input wire:model="search" class="form-control" 
    			placeholder="Ingrese el nombre de un post">
    	</div>
    	
    	@if ($posts->count())
    	
    	<div class="card-body">
    		<table class="table table-striped">
    			<thead>
    				<tr>
    					<th>Id</th>
    					<th>Name</th>
    					<th colspan="2"></th>
    				</tr>
    			</thead>
    			<tbody>
    				@foreach ($posts as $post)
    				<tr>
    					<td>{{ $post->id }}</td>
    					<td>{{ $post->name }}</td>
    					<td with="10px">
    						<a 
    							class="btn btn-primary btn-sm" 
    							href="{{ route('admin.posts.edit', $post) }}"
    						>Editar</a>
    					</td>
    					<td with="10px">
    						<form 
    							action="{{ route('admin.posts.destroy', $post) }}"
    							method="POST"
    						>
    							@csrf
    							@method('DELETE')
    							<button 
    								type="submit" 
    								class="btn btn-danger btn-sm"
    							>Eliminar</button>
    						</form>
    					</td>
    				</tr>
    				@endforeach
    			</tbody>
    		</table>
    	</div>
    	
    	<div class="card-footer">
    		{{ $posts->links() }}
    	</div>
    	
    	@else
    		<div class="card-body">
    			<strong>No hay ningún registro...</strong>
    		</div>
    	@endif
    	
    </div>

     

  • Walter

    Walter hace 2 años

    ? 7° Configuración de la vista index.blade.php con componente de Livewire

    @extends('adminlte::page')
    
    @section('title', 'Coders Free')
    
    @section('content_header')
    	<h1>Listado de Posts</h1>
    @stop
    
    @section('content')
    	@livewire('admin.posts-index')
    @stop
    
    @section('css')
    	<link rel="stylesheet" href="/css/admin_custom.css">
    @stop
    
    @section('js')
    	<script> console.log('Hi!'); </script>
    @stop

     

  • Walter

    Walter hace 2 años

    ? 6° Creamos un componente de Livewire

    php artisan make:livewire Admin/PostsIndex

    Se crea un nuevo archivo en app/Http/Livewire/Admin/PostsIndex.php

    <?php
    namespace App\Http\Livewire\Admin;
    
    use Livewire\Component;
    use App\Models\Post;
    use Livewire\WithPagination;
    
    class PostsIndex extends Component
    {
    	use WithPagination;
    	
    	protected $paginationTheme = "bootstrap";
    	
    	public $search;
    	
    	public function updatingSearch()
    	{
    		$this->resetPage();
    	}
    	
    	public function render()
    	{
    		$posts = Post::where('user_id', auth()->user()->id)
    			->where('name', 'LIKE', '%' . $this->search . '%')
    			->latest('id')
    			->paginate();
    		
    		return view('livewire.admin.posts-index', compact('posts'));
    	}
    }

    Básicamente lo que hace este componente es renderizar el archivo de vista que se encuentra en resources/views/livewire/admin/posts-index.blade.php

     

  • Walter

    Walter hace 2 años

    ? 5° Configuración del menú sidebar

    Editamos el array 'menu' en el archivo config/adminlte.php para agregar las opciones de Blog:

    ...
    	['header' => 'OPCIONES DE BLOG'],
    	[
    		'text' => 'Lista de posts',
    		'route' => 'admin.posts.index',
    		'icon' => 'fas fa-fw fa-clipboard'
    	],
    	[
    		'text' => 'Crear nuevo post',
    		'route' => 'admin.posts.create',
    		'icon' => 'fas fa-fw fa-file'
    	],
    ...

    Y habilitamos livewire para utilizarlo dentro de la plantilla AdminLTE:

    	'livewire' => true,
    ];

     

  • Walter

    Walter hace 2 años

    ? 4° Creación de las vistas

    Creamos la carpeta posts en resources/views/admin/ y dentro creamos los archivos de vistas:

    • index.blade.php
    • show.blade.php
    • create.blade.php
    • edit.blade.php

    Copiamos en cada uno la estructura del archivo resources/views/admin/index.blade.php

    @extends('adminlte::page')
    
    @section('title', 'Coders Free')
    
    @section('content_header')
    	<h1></h1>
    @stop
    
    @section('content')
    	<p></p>
    @stop
    
    @section('css')
    	<link rel="stylesheet" href="/css/admin_custom.css">
    @stop
    
    @section('js')
    	<script> console.log('Hi!'); </script>
    @stop

     

  • Walter

    Walter hace 2 años

    ? 3° Configuración de los métodos del Controlador

     

    Configuramos el método index:

    public function index()
    {
    	$posts= Post::all();
    	return view('admin.posts.index', compact('posts'));
    }

     

    Configuramos el método create:

    public function create()
    {
    	return view('admin.posts.create');
    }

     

    Configuramos el método show:

    public function show(Post $post)
    {
    	return view('admin.posts.show', compact('post'));
    }

     

    Configuramos el método edit:

    public function edit(Post $post)
    {	
    	return view('admin.posts.edit', compact('post'));
    }

     

    Configuramos el método store:

    public function store(Request $request)
    {
    	$request->validate([
    		'name' => 'required',
    		'slug' => 'required|unique:tags'
    	]);
    	$post = Post::create($request->all());
    
    	return redirect()->route('admin.posts.edit', compact('post'))
    		->with('info', 'El post se creó con éxito');
    }

     

    ? Debemos habilitar la asignación masiva en el modelo Post en app/Models/Post.php:

    <?php
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
    	use HasFactory;
    
    	protected $fillable = ['name', 'slug'];
    }

     

    Configuramos el método update:

    public function update(Request $request, Post $post)
    {
    	$request->validate([
    		'name' => 'required',
    		'slug' => "required|unique:tags,slug,$post->id",
    	]);
    	$post->update($request->all());
    
    	return redirect()->route('admin.posts.edit', compact('post'))
    		->with('info', 'El post se actualizó con éxito');
    }

     

    Configuramos el método destroy:

    public function destroy(Post $post)
    {
    	$post->delete();
    
    	return redirect()->route('admin.posts.index')
    		->with('info', 'El post se eliminó con éxito');
    }

     

  • Walter

    Walter hace 2 años

    ? 2° Configuración del Controlador

    <?php 
    namespace App\Http\Controllers\Admin;
     
    use App\Http\Controllers\Controller; 
    use Illuminate\Http\Request; 
    use App\Models\Post; 
    
    class PostController extends Controller 
    { 
    	public function index() {} 
    	public function create() {} 
    	public function store(Request $request) {} 
    	public function show(Post $post) {} 
    	public function edit(Post $post) {} 
    	public function update(Request $request, Post $post) {} 
    	public function destroy(Post $post) {} 
    }

     

  • Walter

    Walter hace 2 años

    ? 1° Creación de Rutas

    Creamos un controlador para las 7 rutas necesarias:

    php artisan make:controller Admin/PostController -r

    Se crea el controlador en app/Http/Controllers/Admin/PostController.php

     

    Editamos el archivo routes/admin.php para usar el controlador recién creado:

    <?php
    use Illuminate\Support\Facades\Route;
    
    use App\Http\Controllers\Admin\HomeController;
    use App\Http\Controllers\Admin\CategoryController;
    use App\Http\Controllers\Admin\TagController;
    use App\Http\Controllers\Admin\PostController;
    
    Route::get('', [HomeController::class, 'index'])->name('admin.home');
    
    Route::resource('categories', CategoryController::class)
    	->names('admin.categories');
    
    Route::resource('tags', TagController::class)
    	->names('admin.tags');
    	
    Route::resource('posts', PostController::class)
    	->names('admin.posts');