Best approach for retrieving data from within a loop of posts with Blade?

So having stuck with trusty Sage 8, I’ve taken the plunge to finally get to grips with Sage 9. Everything makes total sense… apart from some of the Blade aspects. I guess these are more general Blade concepts as apposed to Sage specifics but I wondered how people approach the following.

Keeping with the idea of removing logic from views, what is the best approach for retrieving data from within a loop of posts i.e. for specific data relating to those posts. For a bit of context, I’m using a ACF relationship field which returns several posts. I’m then looping through those posts but I’m not sure how to get AFC fields out of those posts.

Here’s what I have so far:

Controller partial

<?php

namespace App;

trait Fields
{
    /**
    * Return all AFC field for the given page
    *
    * @return array
    */
    public function fields()
    {
        return get_fields();
    }
}

Controller for view

<?php

namespace App;

use Sober\Controller\Controller;

class afc_fields extends Controller
{
    use Fields;
}

Simplified view/partial

<div class="quick-links">

    @php $posts = $fields['quick_links']; @endphp

    @if($posts)

        @foreach($posts as $post)

            <div class="quick-links--block">

                {{ $post->post_title }}

                <img src="{{ $post_fields['scrolling_images'][0]['sizes']['large'] }}">

                <a href="@php echo get_the_permalink($post->ID) @endphp" class="button">Visit page</a>

            </div>
            
        @endforeach

    @endif

</div>

As you can see, I’m reliant on some @php tags at the moment. What’s the best way to get this data into the view partial?

+1 for an answer :sweat_smile: for example, with blade (and sober controller?) system, how can i modify main wp_query depending on page slug i’m on ? Can i use ‘pre_get_posts()’ for eg. ?

I posted up how I’m working in the end in this thread: ACF variables in blade template. Not specific to your query but more an answer to my original post.

In regards to your question, you would write that logic in your controller or you could create a new app/whatever.php file, write your code as you would in a standard WordPress functions.php file and then make sure to include your new file in resources/functions.php, specifially in the below block:

array_map(function ($file) use ($sage_error) {
    $file = "../app/{$file}.php";
    if (!locate_template($file, true, true)) {
        $sage_error(sprintf(__('Error locating <code>%s</code> for inclusion.', 'sage'), $file), 'File not found');
    }
}, ['helpers', 'setup', 'filters', 'admin', 'directives', 'whatever.php']);
1 Like

The ACF variables in blade template thread that @nathobson posted has lots of techniques. Good read.

You are on the right track. Plus there are probably a half-dozen ways to skin this cat, depends on your style. And sometimes there is just no way around throwing in a few @php directives here and there.

My preferences on using @php is to sometimes not use them.

// Instead of this
//  <a href="@php echo get_the_permalink($post->ID) @endphp" class="button">Visit page</a>
<a href="<?= get_the_permalink($post->ID) ?>" class="button">Visit page</a>

Use the self-enclosed version of @php (note the absence of a semi-colon at end of statement)

// Instead of this
// @php $posts = $fields['quick_links']; @endphp
@php( $posts=$fields['quick_links'] )

And sometimes combine a set and if together

// Instead of this
// @php $posts = $fields['quick_links']; @endphp
//    @if($posts)
@if( @php( $posts=$fields['quick_links'] ) )
1 Like