Skip to content

Instantly share code, notes, and snippets.

@Log1x
Last active October 13, 2024 11:58
Show Gist options
  • Save Log1x/d45d69fe3b943768457fb3e9945416e5 to your computer and use it in GitHub Desktop.
Save Log1x/d45d69fe3b943768457fb3e9945416e5 to your computer and use it in GitHub Desktop.
Post Search component example using Acorn v4 and Livewire 3
@extends('layouts.app')
@section('content')
<x-hero title="Welcome to Sage" />
<x-container>
<livewire:post-search lazy />
</x-container>
@endsection
<div>
<input
wire:model.live="search"
type="text"
placeholder="Search for a post..."
class="w-full p-3 text-lg border border-gray-300 rounded"
>
@empty($posts)
<div class="mt-4">
No posts found.
</div>
@endempty
@if ($posts)
<div class="mt-4">
Showing <b>{{ $range }}</b> posts out of <b>{{ $totalPosts }}</b> total{{ $search ? " for {$search}." : '.' }}
</div>
<ul class="mt-4 space-y-2">
@foreach ($posts as $post)
<li>
<a href="{{ $post['url'] }}" class="text-lg text-blue-500 hover:text-blue-600">
{{ $post['title'] }}
</a>
</li>
@endforeach
</ul>
@if ($hasPrevious || $hasNext)
<div class="flex justify-between mt-4">
@if ($hasPrevious)
<button
wire:click="previousPage"
class="px-4 py-2 mt-4 text-white bg-blue-500 rounded hover:bg-blue-600"
>
&larr; Previous
</button>
@endif
@if ($hasNext)
<button
wire:click="nextPage"
class="px-4 py-2 mt-4 ml-auto text-white bg-blue-500 rounded hover:bg-blue-600"
>
Next &rarr;
</button>
@endif
</div>
@endif
@endif
</div>
<?php
namespace App\Livewire;
use Livewire\Attributes\Url;
use Livewire\Component;
use WP_Query;
class PostSearch extends Component
{
/**
* The posts.
*/
public array $posts = [];
/**
* The WordPress query.
*/
protected ?WP_Query $query;
/**
* The post range.
*/
public string $range = '';
/**
* The search query.
*/
#[Url('query')]
public string $search = '';
/**
* The page.
*/
#[Url]
public int $page = 1;
/**
* The total posts.
*/
public int $totalPosts = 0;
/**
* The total pages.
*/
public int $totalPages = 1;
/**
* The amount of posts to show per page.
*/
protected int $amount = 5;
/**
* Render the component.
*
* @return \Illuminate\View\View
*/
public function render()
{
$this->query = new WP_Query([
'post_type' => 'post',
'post_status' => 'publish',
'paged' => $this->page,
'posts_per_page' => $this->amount,
's' => $this->search,
]);
$this->totalPages = $this->query->max_num_pages ?? 1;
$this->totalPosts = $this->query->found_posts ?? 0;
$this->page = min(max(1, $this->page), $this->totalPages);
$start = ($this->page - 1) * $this->amount + 1;
$end = min($this->totalPosts, $this->page * $this->amount);
$this->range = "{$start}-{$end}";
$this->posts = $this->query ? collect($this->query->posts)
->map(fn ($post) => [
'title' => get_the_title($post),
'url' => get_permalink($post),
])->all() : [];
return view('livewire.post-search', [
'hasPrevious' => $this->page > 1,
'hasNext' => $this->page < $this->totalPages,
]);
}
/**
* Go to the next page.
*/
public function nextPage()
{
$this->page = min($this->totalPages, $this->page + 1);
}
/**
* Go to the previous page.
*/
public function previousPage()
{
$this->page = max(1, $this->page - 1);
}
}
@chrillep
Copy link

chrillep commented Feb 2, 2024

This i very nice, compact and clean. Well done sir! 🥇

Have you tried livewire with gutenberg and if so, do they play nice?

@Log1x
Copy link
Author

Log1x commented Feb 3, 2024

I messed around a little bit inside of custom metaboxes inside of /wp-admin/ but not with the actual editor.

@rob
Copy link

rob commented Mar 29, 2024

This is amazing.

@chrillep
Copy link

chrillep commented Sep 26, 2024

@Log1x have you thought about how to handle the global WP_Query since the acorn endpoints will have all is* values false.
Whilst on first load some may be true.

  +is_single: false
  +is_preview: false
  +is_page: false
  +is_archive: false
  +is_date: false
  +is_year: false
  +is_month: false
  +is_day: false
  +is_time: false
  +is_author: false
  +is_category: false
  +is_tag: false
  +is_tax: false
  +is_search: false
  +is_feed: false
  +is_comment_feed: false
  +is_trackback: false
  +is_home: false
  +is_privacy_policy: false
  +is_404: false
  +is_embed: false
  +is_paged: false
  +is_admin: false
  +is_attachment: false
  +is_singular: false
  +is_robots: false
  +is_favicon: false
  +is_posts_page: false
  +is_post_type_archive: false

first load

  +is_tax: true

acorn endpoints from same page the result is basicly new WP_Query()

  +is_tax: false

right now im gonna store the ones i need i just wanted to know if had any good thoughts :)

Cheers and keep up the good work ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment