Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Use dynamic queries with Oxygen's repeater
/* I'll put here different examples of dynamic query for Oxygen repeater :
* - Use one of the following repeater_dynamic_query definitions
* in code block just BEFORE the repeater
* - Set the repeater custom query settings : post type, number of posts, order...
* - Add the remove_action in a code block AFTER the repeater
*/
/****************************************************************************************************
* Display related posts for any CPT with taxonomy:
* - Filter query to prevent altering queries inside the repeater items,
* - Retrieve post category slug : I have only one for each post, so I just take first element
* (You might need to add error tests, of course, if you don't accept empty results,
* for instance if you forgot to set post category.)
* - Set tax_query arg with category slug
* - Set random order
* - Exclude current post
* - Deactivate pagination
*/
/* Code block just BEFORE the repeater */
<?php
function repeater_dynamic_query( $query ) {
global $post;
if ( $query->query['post_type'][0] == 'post' ) {
$cat = wp_get_post_terms( $post->ID , 'category', array( 'fields' => 'slugs' ) )[0];
$query->set( 'tax_query', array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $cat,
'include_children' => false
)
) );
$query->set( 'orderby', 'rand' );
$query->set( 'post__not_in', array($post->ID) );
$query->set( 'no_found_rows', true );
}
}
add_action( 'pre_get_posts', 'repeater_dynamic_query' );
?>
/*
* REPEATER: use custom query and set post type to "post" or any cpt slug,
* number of posts per page as you wish,
* and replace "category" by your cpt taxonomy slug if needed
*/
/* Code block just AFTER the repeater */
<?php
remove_action( 'pre_get_posts', 'repeater_dynamic_query' );
?>
/****************************************************************************************************
* Display only sticky posts with repeater:
* - Get only sticky posts
* - Deactivate pagination
*/
/* Code block just BEFORE the repeater */
<?php
function repeater_dynamic_query( $query ) {
if ( $query->query['post_type'][0] == 'post' ) {
$query->set( 'post__in', get_option( 'sticky_posts' ) );
$query->set( 'no_found_rows', true );
}
}
add_action( 'pre_get_posts', 'repeater_dynamic_query' );
?>
/*
* REPEATER: use custom query and set post type to "post",
* number of posts per page and order as you wish,
* AND DO NOT UNCHECK "Ignore sticky posts"
*/
/* Code block just AFTER the repeater */
<?php
remove_action( 'pre_get_posts', 'repeater_dynamic_query' );
?>
/****************************************************************************************************
* Display posts by year:
*/
/* Code block just BEFORE the repeater */
<?php
function custom_query_by_year( $query ) {
if ( $query->query['post_type'][0] == 'YOUR_POST_SLUG' ) {
$query->set('date_query', [ [ 'year' => '2021' ] ] );
}
}
add_action( 'pre_get_posts', 'custom_query_by_year' );
?>
/*
* REPEATER
*/
/* Code block just AFTER the repeater */
<?php
remove_action( 'pre_get_posts', 'custom_query_by_year' );
?>
@shmaltz
Copy link

shmaltz commented May 23, 2021

@yankiara Thanks for this awesome snippet!

I am trying to place product carousels on a product color archive page. Basically, for every category that has products with a certain color, I want to create a carousel with those products. For example, if I am on the "green" color attribute archive page, and products with attribute color:green are in categories Shirts, Pants and Shoes, I want to display a product carousel for each of those categories.

I imagine having to create a repeater with a carousel inside, but I'm not sure how I would dynamically set the query of the carousel inside the repeater. Any ideas?

@gdnwebmedia
Copy link

gdnwebmedia commented Jun 4, 2021

@mdsims086 I haven't got it working with the relationship field...

I also have a CPT (custom_webinars) and within a custom field (webinar_speakers) related to a CPT (custom_webinar_speak) --- the page is loading all speakers instead of showing only those related to the webinar. I am using the Oxygen Repeater (with custom query pulling custom_webinar_speak) and added the following code without any luck:

  if ( $query->query['post_type'][0] == 'custom_webinars' ) {
    $query->set( 'meta_query', array(
                                array(
                                  'key' => 'webinar_speakers', //name of custom field
                                  'value' => get_the_ID(),
                                  'compare' => 'LIKE'
                                )
                              ) );

    $query->set( 'no_found_rows', true );
  }
}
add_action( 'pre_get_posts', 'dynamic_category_query' );```

Thanks in advance

It works now! This is what I did, I'm sure there is a other ways but wanted to share my findings.

BEFORE THE REPEATER
`<?php
/*
custom_webinar_speak -- CPT holding all the speakers
custom_webinars -- CPT from webinars
webinar_speakers -- field from custom_webinars linking both CPT
*/

function dynamic_category_query( $query ) {

//get Pods object for current post
$pod = pods( 'custom_webinars', get_the_id() );

//get the value for the relationship field
$related = $pod->field( 'webinar_speakers' );

if ( ! empty( $related ) ) {
foreach ( $related as $rel ) {
// add the ID for each related speaker as an array
$post_ids[] = $rel[ 'ID' ];
}
}
$query->set( 'post__in', $post_ids );
$query->set( 'no_found_rows', true );
}
add_action( 'pre_get_posts', 'dynamic_category_query' );
?>`

REPEATER
repeater as a custom query pulling all the speakers (custom_webinar_speak)

AFTER REPEATER
<?php remove_action( 'pre_get_posts', 'repeater_dynamic_query' ); ?>

Thank you for all the previous comments in this thread, they were very helpful. much appreciated!

@mark88008
Copy link

mark88008 commented Jun 11, 2021

I got it also running using it for products from WooCommerce:

<?php function repeater_dynamic_query( $query ) { global $post; if ( $query->query['post_type'][0] == 'product' ) { $cat = wp_get_post_terms( $post->ID , 'product_cat', array( 'fields' => 'slugs' ) )[0]; $query->set( 'tax_query', array( array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $cat, 'include_children' => false ) ) ); $query->set( 'orderby', 'rand' ); $query->set( 'post__not_in', array($post->ID) ); $query->set( 'no_found_rows', true ); } } add_action( 'pre_get_posts', 'repeater_dynamic_query' ); ?>

@HmCody
Copy link

HmCody commented Aug 20, 2021

Thanks so much for posting this! It was exactly what I needed to get my repeaters working the way they should.

@lohint
Copy link

lohint commented Aug 31, 2021

Is it alive here?
I'm total, total noob. I use Meta Box for custom stuff. For starters I just need to obtain a variable, which contains correct post_id for each post inside of a repeater. Once I've got this, there is a big chance that Meta Box helper function or, if I'm lucky, MB Views shortcode, will take care of the rest. Without setting nothing else, but CPT I need to work with, MB helper function gets page ID as $post_id parameter. Repeater reads custom posts name, ID and everything I can set via WP default parameters, but when it comes to custom fields, it shows nothing or i.e. for date type fields current date. How would the BEFORE code look like, if I need just the post_id of posts inside repeater? CPT slug 'podujeti' or something. Thanks

partially SOLVED
It is a problem of Oxygen backend. Frontend shows the data pulled by rwmb helpers in code block just fine. Still struggling with using shortcodes to do the same thing.

@captainhook
Copy link

captainhook commented Aug 31, 2021

but when it comes to custom fields, it shows nothing or i.e. for date type fields current date.

You're definitely not selecting the correct field…

@lohint
Copy link

lohint commented Aug 31, 2021

I did some experiments. This put into repeater field echoes page ID, not repeater field post ID:

MB helper function rwmb_get_value( $field_id, $args, $post_id ); then returns $field_id of incorrect $post_id. As I understand, I need to give $post_id argument correct value, then this basic query should work for custom fields.

@ali3412
Copy link

ali3412 commented Aug 31, 2021

Why does my code output all posts when it shouldn't output anything?

<?php

function repeater_dynamic_query( $query ) {

	$current_id = get_queried_object_id();
	$query_ids = get_term_meta( $current_id, 'дополнительная_информация', true );
	
	global $post;
	if ( $query->query['post_type'][0] == 'add_cat_info' ) {

    $query->set( 'post__in', $query_ids );
    $query->set( 'no_found_rows', true );
  }
}
add_action( 'pre_get_posts', 'repeater_dynamic_query' );

?>

@alexsoluweb
Copy link

alexsoluweb commented Jan 30, 2022

Hey guys, any tips would be appreciate on this please.

When using pre_get_posts action hook inside oxygen repeater (any custom query):

when updating $query->set('something', 'value'), it does not update his object property $this->found_posts.

This is a really strange behavior....or i missing something ...

  function my_pre_get_post($query){
    ...
    $query->set('somefilter', 'value');
    $query->found_posts // 0 why is that? There is post showing up on the front end
    ...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment