I'm creating a masonry post grid of animals. I plan to filter the the visible posts by toggling classes. The classes would in turn would be the post's.
I'm using an MVC theme and would like to get all my data within the Controller, and not have to do multiple queries within the theme loop.
I'm thinking something this:
<?php
namespace App\Controllers;
use Sober\Controller\Controller;
class PageOurAnimals extends Controller
{
protected $acf = true;
public function animals() {
$args = [
'posts_per_page' => -1,
'post_type' => 'portfolio',
'post_status' => 'publish',
'order_by' => 'date',
'order' => 'DESC',
];
return array_map(function($post) {
$post->terms = [];
// Maps terms to posts (doesn't work)
array_map(function($term) {
if (isset($term)) {
array_push($post->terms, $term->slug);
}
}, wp_get_post_terms($post->ID, 'category'));
}, get_posts($args));
}
}
.
{-- Blade Template --}
@foreach($animals as $i => $animal)
<div class="cell {{ implode(' ', $animal->terms }}">
<div class="animal animated rollin">
<figure class="zoom zoom__container animal__figure">
{!!
get_the_post_thumbnail($animal->ID, 'medium', [
'title' => $animal->post_title,
'class' => 'zoom__image'
])
!!}
<div class="animal__overlay"></div>
</figure>
<div class="animal__caption">
<span class="animal__name">
{{ $animal->post_title }}
</span>
</div>
</div>
</div>
@endforeach
Edit: I looked up the documentation and found array_map doesn't modify the original array, and what I actually want is array_walk()
.
I've updated the the code to what is below, but it is still returning an empty array.
$posts = get_posts($args);
array_walk($posts, function(&$post, $index) {
$terms = wp_get_post_terms($post->ID, 'category');
if (isset($terms)) {
$post->terms = [];
array_walk($terms, function(&$term, $term_index) {
// die(print_r($term));
if (isset($term->slug)) {
array_push($post->terms, $term->slug);
}
});
}
});
return $posts;
I'm creating a masonry post grid of animals. I plan to filter the the visible posts by toggling classes. The classes would in turn would be the post's.
I'm using an MVC theme and would like to get all my data within the Controller, and not have to do multiple queries within the theme loop.
I'm thinking something this:
<?php
namespace App\Controllers;
use Sober\Controller\Controller;
class PageOurAnimals extends Controller
{
protected $acf = true;
public function animals() {
$args = [
'posts_per_page' => -1,
'post_type' => 'portfolio',
'post_status' => 'publish',
'order_by' => 'date',
'order' => 'DESC',
];
return array_map(function($post) {
$post->terms = [];
// Maps terms to posts (doesn't work)
array_map(function($term) {
if (isset($term)) {
array_push($post->terms, $term->slug);
}
}, wp_get_post_terms($post->ID, 'category'));
}, get_posts($args));
}
}
.
{-- Blade Template --}
@foreach($animals as $i => $animal)
<div class="cell {{ implode(' ', $animal->terms }}">
<div class="animal animated rollin">
<figure class="zoom zoom__container animal__figure">
{!!
get_the_post_thumbnail($animal->ID, 'medium', [
'title' => $animal->post_title,
'class' => 'zoom__image'
])
!!}
<div class="animal__overlay"></div>
</figure>
<div class="animal__caption">
<span class="animal__name">
{{ $animal->post_title }}
</span>
</div>
</div>
</div>
@endforeach
Edit: I looked up the documentation and found array_map doesn't modify the original array, and what I actually want is array_walk()
.
I've updated the the code to what is below, but it is still returning an empty array.
$posts = get_posts($args);
array_walk($posts, function(&$post, $index) {
$terms = wp_get_post_terms($post->ID, 'category');
if (isset($terms)) {
$post->terms = [];
array_walk($terms, function(&$term, $term_index) {
// die(print_r($term));
if (isset($term->slug)) {
array_push($post->terms, $term->slug);
}
});
}
});
return $posts;
I guess you have a problem with variable scopes in here.
array_walk($terms, function(&$term, $term_index) {
// die(print_r($term));
if (isset($term->slug)) {
array_push($post->terms, $term->slug);
}
});
In this part of your code, you use anonymous function and inside of it you use $post
variable. But it is a different variable than the one from few lines back - you're in different function now.
But you can simplify that code a lot:
$posts = get_posts($args);
array_walk($posts, function(&$post, $index) {
$terms = wp_get_post_terms($post->ID, 'category');
if ( ! empty($terms) && ! is_wp_error($terms) ) {
$post->terms = [];
foreach ($terms as $term) {
$post->terms[] = $term->slug;
}
}
});
return $posts;
And even easier, if you know some "magic" WP functions like wp_list_pluck
$posts = get_posts($args);
array_walk($posts, function(&$post, $index) {
$terms = wp_get_post_terms($post->ID, 'category');
$post->terms = []; // Prevents error on blade template's implode()
if ( ! empty($terms) && ! is_wp_error($terms) ) {
$post->terms = wp_list_pluck( $terms, 'slug' );
}
});
return $posts;
PS. You have some errors in your $args too.
$args = [
'posts_per_page' => -1,
'post_type' => 'portfolio',
'post_status' => 'publish',
'order_by' => 'date',
'order' => 'DESC',
];
It should be orderby
instead of oder_by
.