I have increasingly been leaning heavily toward the “run all logic in the controller, pass only data to Blades” approach. It “feels better” but it can also make it much easier to track down logic issues, since you need only look through your controllers (your views can’t be the source of logic errors if they run no logic). It takes a little more effort initially, but I generally feel much more comfortable when I compile data in my controllers and pass my Blades only what they need. This also has the effect of making Blades much more readable.
In general, I don’t pass the raw results of WordPress queries directly to my Blades, expect if those queries are very simple (i.e. a title). For instance, the controller for my blog index processes the posts appearing on the archive like this (I’m using Sage’s filters for my controller instead of soberwp/controller
, but the principle is more or less the same):
/** @var $wp_query \WP_Query */
global $wp_query;
$data['posts'] = false;
if ($wp_query->post_count > 0) {
$data['posts'] = array_map(function ($post) {
/** @var $post \WP_Post */
$video = \Samrap\Acf\Acf::field(KEY__FEATURED_VIDEO, $post)->default(false)->get();
return array(
'image' => wp_get_attachment_image(
get_post_thumbnail_id($post->ID),
'post_featured_image_400',
false,
array(
'class' => 's-news__archive__postImage'
)
),
'title' => $post->post_title,
'date' => date_format(DateTime::createFromFormat('Y-m-d H:i:s', $post->post_date), 'M. j, Y'),
'excerpt' => Murmur\WP\Excerpt::getByCharacters($post, 150, '...'),
'link' => array(
'url' => get_permalink($post->ID),
'text' => 'Read More',
'class' => 's-news__archive__postLink',
),
'video' => $video,
);
}, $wp_query->posts);
}
My archive.blade.php
looks like this:
@extends('layouts.app')
@section('content')
@if($posts)
<ul class="s-news__archive__postList t-clear-list">
@foreach($posts as $post)
@include('partials.news.index-post-block', $post)
@endforeach
</ul>
@endif
@endsection
And the partial it calls looks like this:
<li class="s-news__archive__post">
<a href="{{$link['url']}}" class="s-news__archive__postImageWrapper o-imageBlock">
{!! $image !!}
@if($video)
<div class="o-imageBlock__playIcon">
<svg class="a-icon" width="70" height="70">
<use xlink:href="#play-icon"></use>
</svg>
</div>
@endif
</a>
<div class="s-news__archive__postContent">
<h3 class="s-news__archive__postHeading">{{$title}}</h3>
<div class="s-news__archive__postMeta style-emphasis">Posted {{$date}}</div>
<div class="s-news__archive__postExcerpt">{!! $excerpt !!}</div>
@include('partials.m-arrowLink', $link)
</div>
</li>
I feel like this approach is the most in-line with how Sage/Blade “wants” you to go at it, because it has a clear separation between views and logic, and your data is clear and descriptive.