Rest-Easy
Rest-Easy copied to clipboard
Retrieving posts from category with ACF content intact
Hey, I'm reaching out for help more so than submitting an issue here!
I'd like to: • Retrieve all posts from a specific category and include each post's ACF content (not as meta if I can help it).
Basically, I have a bunch of project posts, all with a 'featured' category that I'd like to feature on my FrontPage.
I would normally write something like:
<?php
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'cat' => 3
);
$kyles_query = new WP_Query( $args );
if ( $kyles_query->have_posts() ) {
while ( $kyles_query->have_posts() ) {
$kyles_query->the_post();
$fields = get_fields();
}
wp_reset_postdata();
} else {
// no posts found
}
I'm wondering how I could achieve this with a custom Rest Easy filter or any other suggested method? Thanks a million!
Hey! There are two parts I see to this question:
- First, you're looking to add some posts from a specific category to the front page, which you could do like this:
function serialize_front_page_posts($post_data){
// ignore if not front page
if($post_data->ID != get_option('page_on_front')) {
return $post_data;
}
// your $args, with 'cat' changed to 'category' for get_posts
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'category' => 3
);
// get posts in category
$front_page_posts = get_posts($args);
// save results in top-level property called "frontPagePosts"
$post_data['frontPagePosts'] = array();
// attach serialized post data
foreach($front_page_posts as $front_page_post) {
$post_data['frontPagePosts'][] = apply_filter('rez_serialize_post', $front_page_post);
}
return $post_data;
}
add_filter('rez_serialize_post', 'serialize_front_page_posts');
Give that a try in your rest-easy-filters.php
file and see if it works - I haven't tested this code specifically but the general idea is there!
- Second, you're looking to include ACF content in those retrieved posts, which you could do like this (attaches all ACF data as a top-level property called
acf
on a serialized page/post):
/*
* Serialize ACF content with get_field to respect ACF custom formatting
*/
function serialize_custom_acf_content($post_data){
// check to make sure we have ACF installed
if (!function_exists('get_fields')){
return $post_data;
}
// get ACF fields attached to target post
$acf_fields = get_fields($post_data['ID']);
// prep to save serialized fields
$post_data['acf'] = array();
if( !empty($acf_fields) ){
// serialize ACF fields
foreach( $acf_fields as $name => $value ){
$post_data['acf'][$name] = $value;
}
}
return $post_data;
}
add_filter('rez_serialize_post', 'serialize_custom_acf_content');
We actually just added this second function to the Vuepress boilerplate here, so if you're using a new-ish version you should already be good to go! If not, you can just paste the code above into src/functions/rest-easy-filters.php
and it should work fine.
Let me know if there's any problems there and thanks for reaching out!
Thanks Sander, I'm getting closer thanks to your help! To get it working, I had to adjust like so:
Custom Filter
function serialize_front_page_posts($post_data){
// ignore if not front page
if( !is_front_page() ) {
return $post_data;
}
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'category' => 3
);
$front_page_posts = get_posts($args);
$post_data['frontPagePosts'] = array();
foreach($front_page_posts as $front_page_post) {
$post_data['frontPagePosts'][] = apply_filters('rez_serialize_post', $front_page_post);
}
return $post_data;
}
add_filter('rez_build_loop_data', 'serialize_front_page_posts');
Using add_filter('rez_build_loop_data', ...
instead of add_filter('rez_serialize_post', ...
Would this be good practice in doing so?
Result: ACF array
I can see my ACF content via [meta]
and attachedMedia
but am I missing something to think this should live within the acf
array?
That absolutely works! I personally usually think of the loop
as a pure array of serialized post objects, rather than an object with properties, so I'd lean toward putting frontPagePosts
in rez_serialize_post
instead of rez_build_loop_data
. Was the rez_serialize_post
filter not working, or was there a different reason for putting the posts in the loop data? Either way, though, it should get the job done!
You're definitely not wrong in thinking that ACF content should live in the acf
property - I'm not sure why it wouldn't serialize after pasting the serialize_custom_acf_content
function in and adding it to the rez_serialize_post
filter. Can you var_dump
$acf_fields
after this line:
// get ACF fields attached to target post
$acf_fields = get_fields($post_data['ID']);
and see what you get from that? Thanks!
Hmm I assumed the same, It wouldn't work when putting frontPagePosts
in rez_serialize_post
but rez_build_loop_data
does.
Just noticed that I'm getting an Uncaught TypeError: _store2.default.state.loop.map is not a function at CacheCrawler.onNewPage
.. Does this make sense to you?
Var Dump
bool(false) bool(false) bool(false) bool(false)
Although, if I go and assign an ACF to the home/front page then this data will actually show/repeat within the acf:
of each of my frontPagePosts
...
Thanks for your help Sander, sorry to drag out! 🤔
Not a problem at all, happy to help! 😄
-
The rez_serialize_post issue - Are you able to serialize any data in
rez_serialize_post
? If so, are you able to serialize data specifically for the front page? You can test those out by pasting these lines intofunctions/rest-easy-filters.php
:
function test_serialization($post_data){
$post_data['test_generic'] = 'works';
return $post_data;
}
add_filter('rez_serialize_post', 'test_serialization');
function test_serialization_front_only($post_data){
$front_id = get_option('page_on_front');
if($post_data['ID'] == $front_id || $post_data->ID == $front_id){
$post_data['test_front'] = 'works';
}
return $post_data;
}
add_filter('rez_serialize_post', 'test_serialization_front_only');
Any page you load should then have the test_generic
field set to works
in the result, and the front page should have both test_generic
and test_front
set to works
. If neither or both of those are happening, we've got an issue with serialize_post filters and can go from there!
-
The cache-crawler issue - That's a bug on our end, adding an issue to the Vuepress repo to fix! It shouldn't affect anything in this situation, though.
-
The empty ACF fields - Are the values for those fields empty on the posts in question? If not, I'd recommend
echo
ing the ID inserialize_custom_acf_content
to make sure it's looking in the correct post:
function serialize_custom_acf_content($post_data){
// check to make sure we have ACF installed
if (!function_exists('get_fields')){
return $post_data;
}
echo $post_data['ID'];
echo $post_data->ID;
// etc...
Let me know if any of those shed any more light on the issue!
@mrkylemac Any luck with this? Just wanted to check in!
Hey Sander!
I'm unable to serialize any data using add_filter('rez_serialize_post', 'serialize_front_page_posts');
Using rez_build_loop_data
and rez_build_site_data
work though.
If I test the serialization using rez_build_loop_data
with the lines of code you provide, I definitely see test_generic
but no result with test_front
on the homepage.
I'm still quite confused, apologies!
Apologies on our end! I'm not quite sure why this isn't working either, but I'll look some more into it at the start of next week - it might be a symptom of a bigger issue so it'll be good to learn more about. Is there any chance you have a public repo for the site you're working on? No problem if not, but it might be useful. Thank you!
No worries Sander, I’ve managed to find a temporary fix.
But, next week let me make my repo public just incase this happens to be a bigger issue..
Thanks again!
On Sat, 29 Sep 2018 at 4:55 am, Sander Moolin [email protected] wrote:
Apologies on our end! I'm not quite sure why this isn't working either, but I'll look some more into it at the start of next week - it might be a symptom of a bigger issue so it'll be good to learn more about. Is there any chance you have a public repo for the site you're working on? No problem if not, but it might be useful. Thank you!
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/funkhaus/Rest-Easy/issues/32#issuecomment-425533169, or mute the thread https://github.com/notifications/unsubscribe-auth/ADGhGEo4dw-FrXXsDuholkNN0JfA44Ceks5ufnCdgaJpZM4WthXC .
--
• Mr Kyle Mac Brand, Interaction & Web Development +61 (0) 473 431 067
Mitchell House, Lvl 5, Studio #505 358 Lonsdale St, Melbourne, Victoria 3000 Australia
www.mrkylemac.com Instagram http://www.instagram.com/mrkylemac.work, Twitter http://www.twitter.com/mrkylemac, Dribbble http://www.dribbble.com/mrkylemac