Hi,
I have a custom post called “speakers” and i want to display in archive page divided by letter.
So i created Speaker composer, archive-speakers.blade.php and content-speakers.blade
This is the code from content-speakers:
<article @php(post_class("col-2 mb-3"))>
<header>
<a href="{{ get_permalink() }}">{!! **$thumbnail**!!}</a>
<h2 class="entry-title">
<a href="{{ get_permalink() }}">
{!! **$title** !!}
</a>
</h2>
</header>
<div class="entry-summary">
{!! **$aziendaRuolo** !!}
</div>
</article>
This is Speakers.php
namespace App\View\Composers;
use Roots\Acorn\View\Composer;
class Speaker extends Composer
{
protected static $views = [
'partials.archive-speakers',
'partials.page-header-archive-speakers',
'partials.content-speakers',
'partials.content-single-speakers',
];
public function override()
{
return [
'title' => $this->title(),
...
'thumbnail' => $this->thumbnail(),
'linkedin' => $this->linkedin(),
'aziendaRuolo' => $this->aziendaRuolo(),
...
];
}
public function title()
{
if ($this->view->name() !== 'partials.page-header-archive-speakers') {
return get_the_title();
}
if (is_archive()) {
return "Gli speaker";
}
return get_the_title();
}
public function thumbnail()
{
($featured_image = get_the_post_thumbnail(get_the_ID(), 'thumbnail', array( 'class' => 'img-fluid mb-4' ))) ? $featured_image : '<span class="placeholder"></span>';
return $featured_image;
}
/**
* Returns the role and company
*
* @return string
*/
public function aziendaRuolo()
{
return $this->getRuolo() . ' ' . $this->getAzienda();
}
private function getRuolo()
{
return get_field('ruolo');
}
private function getAzienda()
{
return get_field('azienda');
}
very simple.
For displaing speakers divided by letter in archive-speakers i have to override the Loop so i made this query (code ref: here)
archive-speakers.blade.php
@extends('layouts.app')
@section('content')
@includeFirst(['partials.page-header-archive-' . get_post_type(), 'partials.page-header-archive'])
@if (! have_posts())
<x-alert type="warning">
{!! __('Sorry, no results were found.', 'sage') !!}
</x-alert>
{!! get_search_form(false) !!}
@endif
@php($by_letter = array())
<?php
function fill_by_letter_array( $by_letter ) {
$keys = range('a', 'z');
$values = array_fill(0, count($keys), array());
$empty = array_combine($keys, $values);
return wp_parse_args( $by_letter, $empty);
}
?>
@while(have_posts()) @php(the_post())
@php($letter = substr(get_the_title(), 0, 1))
@if( ! isset($by_letter[$letter]) )
@php($by_letter[$letter] = array())
@endif
@php($by_letter[$letter][] = get_post(get_the_ID()))
@endwhile
@php(ksort($by_letter))
@php(wp_reset_postdata())
<div class="row">
<p style="border-top: 1px solid #DCDADE;"></p>
<div id="search-result" class="col-10" data-bs-spy="scroll" data-bs-target="#speaker-list" data-bs-offset="0" data-bs-smooth-scroll="true" tabindex="0">
@foreach($by_letter as $letter => $posts)
<div>
<h5 class="ps-4 mb-3" style="text-transform: uppercase"><?php echo $letter; ?></h5>
@if(! empty($posts) )
@foreach( $posts as $post )
**@php(setup_postdata($post))**
@includeFirst(['partials.content-' . get_post_type(), 'partials.content'], ['$post' => $post])
@endforeach
@endif
</div>
@endforeach
</div>
</div>
{!! get_the_posts_navigation() !!}
@endsection
@section('sidebar')
@include('sections.sidebar')
@endsection
It’s seems to work but when i call setup_postdata($post) and Composer “title” or “thumbnail” function are called by content-speakers.blade.php it always print first title/thumbnail.
Basically it seems that the_post() from main loop doesn’t change.
I hope I have explained well even if I doubt