Skip to content

Instantly share code, notes, and snippets.

@yankiara
Last active September 6, 2023 19:25
Show Gist options
  • Star 77 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save yankiara/c43da83662a14e7609b4e23f6d82717a to your computer and use it in GitHub Desktop.
Save yankiara/c43da83662a14e7609b4e23f6d82717a to your computer and use it in GitHub Desktop.
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' );
?>
@williammei
Copy link

Nested inside another repeater is not working, I used toolset relationship to connect two posts.
Could you help on this ?

@Jehu
Copy link

Jehu commented Jan 28, 2021

I'm still having issues with this.
Can anyone confirm if they have tried this in v.3.7 and it works?

Yes, here it works with 3.7!

@Kuldas
Copy link

Kuldas commented Feb 9, 2021

Hey guys,

Can you please help me how to modify the code for WooCommerce products?

I need to list all the products in the "pizzy" category and sort them by "menu_order". I tried to modify the code, but Oxygen always throws me a 500 error and it can't be saved.

P.S .: After inserting the code into the "code block" and applying. "Hello world" will not disappear either. Unfortunately, I absolutely don't know where I'm making a mistake.

@mindingear
Copy link

mindingear commented Feb 12, 2021

Thanks for this piece of code, it's half working for me and I can't figure it out, hopefully somebody can help me:

. Using Oxygen 3.7

. I've added the code block before my repeater

. When I initially run the code without the "add_action ( 'pre_get_posts', 'filter_plans' );", it works fine, I can see all the records.

. When I run the code with the "add_action ( 'pre_get_posts', 'filter_plans' );", I can see that the filter works as I can see the rows on the output but none of the fields print out, the rows are blank. I re-created the repeater from scratch and the syntax looks fine to me: [oxygen data='custom_acf_content' settings_path='contacts_min'] -- [oxygen data='custom_acf_content' settings_path='contacts_max']

Any idea why the filters would work but the fields wouldn't print?

Many thanks,

@mindingear
Copy link

Ok, well, I can answer my own questions above, I guess it's an ACF problem as if I insert the field through the "Custom Field/Meta Options" rather than through the "Advanced Custom Field", it works fine.

In short: [oxygen data='meta' key='contacts_max'] works while [oxygen data='custom_acf_content' settings_path='contacts_max'] doesn't.

@albertvisuals
Copy link

Hello!
Thanks for sharing this, that is really helpful!

I have a question, regarding this. I need to put the code block inside a code snippet, as I have WPGrid running and the faces using AJAX, so putting it on the page, won't work correctly.

I have the custom params in the repeater element:
post_type=veranstaltungen&posts_per_page=4&custom_query=true

I then have following in a code snippet:

`function dynamic_category_query999( $query ) {

if ( $query->get( 'custom_query' ) ) {

    $query->set( 'meta_key', 'veranstaltung_zeit_anfangszeitpunkt' );
    $query->set( 'orderby', 'meta_value' );
    $query->set( 'order', 'DESC' );
    $query->set(
        'meta_query',
        [
            [
                'key'     => 'veranstaltung_zeit_endzeitpunkt',
                'value'   => gmdate( 'Y-m-d H:i:s' ),
                'compare' => '<=',
            ],
        ]
    );

}

}
add_action( 'pre_get_posts', 'dynamic_category_query999' );`

The question I now have:
Is it possible to add a speicifc identifier like queryA, queryB, queryC etc. so that I cann apply a specific code snippet to only one specific repeater?

Thanks very much again!

@ilhamhady
Copy link

Hi @ALL, how if I want to include all categories there?

@mark88008
Copy link

Thank you very much. It works very well for me!

@Blikeriker
Copy link

Hi folks! Anybody can help me out, how to query in this way acf relationship post object? I have a custom post type where user can select other posts from acf relationship fields, and i need to put this posts into a repeater. It would be lifesaver. Thanx!

That would be amazing!! :(

@ilhamhady
Copy link

I heard this feature will release on Oxygen 3.8, Amazing!

@Blikeriker
Copy link

Blikeriker commented Mar 30, 2021

Hi folks! Anybody can help me out, how to query in this way acf relationship post object? I have a custom post type where user can select other posts from acf relationship fields, and i need to put this posts into a repeater. It would be lifesaver. Thanx!

I have solved this ....contact me if you still need to know how to do it (so we not troll this post...) -> skp: live:indirect_9

@gdnwebmedia
Copy link

@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

@jasonwilliamsau
Copy link

jasonwilliamsau commented May 22, 2021

for anyone looking for an example for child pages:

CODEBLOCK

<?php
function repeater_dynamic_query( $query ) {  
  $postID = get_the_ID();
  $query->set( 'post_parent', $postID );
}
add_action( 'pre_get_posts', 'repeater_dynamic_query' );
?>

REPEATER

The Repeater Query is set to manual with the following:

post_type=page&no_found_rows=true&order=ASC&orderby=menu_order&posts_per_page=-1

CODEBLOCK

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

@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

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
    ...
}

@grandsite
Copy link

Hello everyone, how can I display all my product categories on the shop archive page with a repeater? Thank you in advance!

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