Roots Discourse

Using controllers to create a CPT loop with arguments

Hello!

I’m curious as to if it’s possible to add custom post type loop as a controller, which takes an argument to determine which post type the loop is looking for?

For example, here is what I’ve tried:

/* TemplateAktiviteter.php */

class TemplateAktiviteter extends Controller
{
    public function kursLoop($postType)
    {
        $kurs_items = get_posts([
            'post_type' => $postType,
            'posts_per_page' => 9,
        ]);

        return array_map(function ($post) {
            return apply_filters('the_content', $post->post_content);
        }, $kurs_items);
    }
}
/* template-aktiviteter.blade.php */
@foreach($kurs_loop('kurs') as $kurs_item)
  {!! $kurs_item !!}
@endforeach
@php(wp_reset_postdata())

This is not working, with the following error message:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function App\Controllers\TemplateAktiviteter::kursLoop(), 0 passed in soberwp/controller/src/Controller.php on line 191 and exactly 1 expected in Controllers/TemplateAktiviteter.php:9

I’m curious as to if it is possible to create such a loop? It would allow me to work much more DRY :slight_smile:

Regular functions just return a variable with data. Use a static method instead:

/* TemplateAktiviteter.php */

class TemplateAktiviteter extends Controller
{
    public static function kursLoop($postType = 'kurs')
    {
        $kurs_items = get_posts([
            'post_type' => $postType,
            'posts_per_page' => 9,
        ]);

        return array_map(function ($post) {
            return apply_filters('the_content', $post->post_content);
        }, $kurs_items);
    }
}
/* template-aktiviteter.blade.php */
@foreach(TemplateAktiviteter::kursLoop() as $kurs_item)
  {!! $kurs_item !!}
@endforeach
@php(wp_reset_postdata())

Thanks a lot!! This solved my problem. I made a slight change to your code that made it work the way I want it to, I changed the following:
public static function kursLoop($postType)
and
@foreach(TemplateAktiviteter::kursLoop('kurs') as $kurs_item)

Thanks!!!

Ok, I’m running into a problem here which I’m not sure how to solve.

Everything works perfectly, except for getting the permalink from the loop this way. I get all the other fields right, such as title and content, however the permalink is the same as the main page the loop is on.

This is my TemplateAktiviterer.php:

class TemplateAktiviteter extends Controller
{
    public static function kursLoop($postType)
    {
        $items = get_posts([
            'post_type' => $postType,
            'posts_per_page' => 9,
        ]);

        return array_map(function ($post) {
            return [
                'content' => apply_filters('the_excerpt', $post->post_content),
                'title' => apply_filters('get_the_title', $post->post_title),
                'permalink' => apply_filters('get_the_permalink', $post->permalink),
            ];
        }, $items);
    }
}

And this is the code I’m calling in the template partial:

<article @php(post_class())>
  <header>
    <h2 class="entry-title"><a href="{!! $item['permalink'] !!}">{!! $item['title'] !!}</a></h2>
  </header>
  <div class="entry-summary">
    {!! $item['content'] !!}
  </div>
</article>

This is the foreach loop I’m running:

  @foreach(TemplateAktiviteter::kursLoop('kurs') as $item)
    @include('partials.content-aktiviteter')
  @endforeach
  @php(wp_reset_postdata())

Any ideas on how I could solve it?

EDIT:::
OK, solved it.
'permalink' => apply_filters('permalink', get_permalink($post)),

Thanks for the help!

1 Like

Adding an image to the post array:

controller:
‘thumbnail’ => apply_filters(‘get_the_post_thumbnail_url’, get_the_post_thumbnail_url($post)),

content template:
img class=“img-fluid” src="{!! $item[‘thumbnail’] !!}"