0

Not sure the best way to describe this, but basically I am defining a variable ($cat) which chooses a taxonomy based on a number defined just before the query is called, but as the number is defined AFTER the args I can't figure out how to get it to work. I know I could just duplicate the whole query for each taxonomy I want, but I was hoping there was a less character-heavy way to do this.

Current code:

//cat changer (using a settings page so non-dev colleagues can switch taxonomies on the homepage)
if ( $cat == 1 ) { $sector = get_option('b4_settings_homepage_category_1')[0]; }
if ( $cat == 2 ) { $sector = get_option('b4_settings_homepage_category_2')[0]; }
if ( $cat == 3 ) { $sector = get_option('b4_settings_homepage_category_3')[0]; }
if ( $cat == 4 ) { $sector = get_option('b4_settings_homepage_category_4')[0]; }
if ( $cat == 5 ) { $sector = get_option('b4_settings_homepage_category_5')[0]; }
if ( $cat == 6 ) { $sector = get_option('b4_settings_homepage_category_6')[0]; }
if ( $cat == 8 ) { $sector = get_option('b4_settings_homepage_category_7')[0]; }
if ( $cat == 9 ) { $sector = get_option('b4_settings_homepage_category_8')[0]; }
if ( $cat == 10 ) { $sector = get_option('b4_settings_homepage_category_9')[0]; }
if ( $cat == 11 ) { $sector = get_option('b4_settings_homepage_category_10')[0]; }
if ( $cat == 12 ) { $sector = get_option('b4_settings_homepage_category_11')[0]; }
if ( $cat == 13 ) { $sector = get_option('b4_settings_homepage_category_12')[0]; }
if ( $cat == 14 ) { $sector = get_option('b4_settings_homepage_category_13')[0]; }
//that 'get_option' outputs as the plain ID of the taxonomy

//args & query
$args_cat = array( 
   'post_type' => $post_types,
   'posts_per_page' => 3,
   'fields' => 'ids',
   'post__not_in' => array( $feat_ids, $latest_ids, $trend_ids ),
   'tax_query' => array( 
      'relation' => 'AND',
      array(
         'taxonomy' => 'sector',
         'field' => 'id',
         'terms' => $sector
      )
   )
);
$cat_query = new WP_Query( $args_cat );

//choosing the category and hoping to run the query with it (not working)
$cat = 1;
while ( $cat_query->have_posts() ) { 
   $cat_query->the_post();
   get_template_part( 'template-parts/posts/content', get_post_type() );
   wp_reset_postdata();
}

So it's like I'm wanting it to go back up to the top of the page and choose the cat based on the number, then run the query with that option, but I just can't figure it out. Running it as-is returns 'terms' => NULL. Do I need a reset or a return or something?

Any help greatly appreciated.

By the way, I know I could do it like this for each tax/query:

$sector = get_option('b4_settings_homepage_category_1')[0];
$args_cat = array( 
   'post_type' => $post_types,
   'posts_per_page' => 3,
   'fields' => 'ids',
   'post__not_in' => array( $feat_ids, $latest_ids, $trend_ids ),
   'tax_query' => array(
      'relation' => 'AND',
      array( 
         'taxonomy' => 'sector',
         'field' => 'id',
         'terms' => $sector
      )
   )
);
$cat_query = new WP_Query( $args_cat );
while ( $cat_query->have_posts() ) {
$cat_query->the_post(); 
etc etc

But I really don't want to have that query replicated a bunch of times if it can be avoided...

4
  • Hey there! You can move the query to a function and call it with an argument. That way you won't have to copy-paste the query code. However, I'm not sure I get the whole picture, so maybe that won't work. Commented Nov 8, 2021 at 16:35
  • Thank you. I've gotten marginally closer by defining the categories as $sector[1], $sector[2] etc. then using 'terms' => $sector[$i] in the args, so just need to figure out how I can write $i = int later on in the code and have the query still work. Beginner at php so never made a function before, I'll look into it. Commented Nov 8, 2021 at 17:06
  • I see that the names of the options don't correspond to the category numbers. Is that intended or a typo? Check $cat == 8 - it points to the 7th category. Commented Nov 8, 2021 at 17:42
  • Ah that was just a typo, but shouldn't make a difference at this stage. Thank you for pointing it out though! Commented Nov 10, 2021 at 9:55

4 Answers 4

1

Combining Petar's function and Tiago's shortened option syntax, this works:

In template:

//once, in header:
$i = 0;

//anytime I want to run the query:
$i++;
$cat_query = prefix_get_wp_query($i);
 while ( $cat_query->have_posts() ) {
  $cat_query->the_post();
  get_template_part( 'template-parts/posts/content', get_post_type() );
  wp_reset_postdata();
}

In functions:

function prefix_get_wp_query( $i ) {
 if ( $i > 0 ) { 
  $cat = "b4_settings_homepage_category_".$i;
  $sector = get_option($cat)[0];
 }
 $cat_args = [
  'post_type'      => $post_types,
  'posts_per_page' => 3,
  'fields'         => 'ids',
  'post__not_in'   => [ $feat_ids, $latest_ids, $trend_ids ],
  'tax_query'      => [
   'relation' => 'AND',
    [ 'taxonomy' => 'sector',
      'field'    => 'id',
      'terms'    => $sector
    ]
   ]
  ];
  return new WP_Query( $cat_args );
}

Thanks very much!!

1
  • this function doesnt need the if inside, this because if the $i is <= to 0 will return an error once will not recognise the variable $sector. so or it uses the $cat_args inside the if() and has an else{} to the less or equal than 0, or the if isnt necessary, because $i will always be greater than 0 you can take out the if and leave only the two lines that are in this moment inside of the if. Commented Nov 11, 2021 at 13:48
0

To reduce code repetition, you could introduce a function. The below code example is a reworked version of the code you provided, but it uses a function. If you want to use this for category 2, simply call the function with the argument 2.

Please note, that you'll need to declare the variables you're using at the beginning of the function. Also - the get_option function, could return more than just an array, which would cause a notice.

$cat_query = prefix_get_wp_query(1);
while ( $cat_query->have_posts() ) {
    $cat_query->the_post();
    get_template_part( 'template-parts/posts/content', get_post_type() );
    wp_reset_postdata();
}

function prefix_get_wp_query( $cat ) {
    // declare $post_types, $feat_ids, $latest_ids and $trend_ids below this line

    //cat changer (using a settings page so non-dev colleagues can switch taxonomies on the homepage)
    if ( $cat == 1 ) { $sector = get_option('b4_settings_homepage_category_1')[0]; }
    if ( $cat == 2 ) { $sector = get_option('b4_settings_homepage_category_2')[0]; }
    if ( $cat == 3 ) { $sector = get_option('b4_settings_homepage_category_3')[0]; }
    if ( $cat == 4 ) { $sector = get_option('b4_settings_homepage_category_4')[0]; }
    if ( $cat == 5 ) { $sector = get_option('b4_settings_homepage_category_5')[0]; }
    if ( $cat == 6 ) { $sector = get_option('b4_settings_homepage_category_6')[0]; }
    if ( $cat == 8 ) { $sector = get_option('b4_settings_homepage_category_7')[0]; }
    if ( $cat == 9 ) { $sector = get_option('b4_settings_homepage_category_8')[0]; }
    if ( $cat == 10 ) { $sector = get_option('b4_settings_homepage_category_9')[0]; }
    if ( $cat == 11 ) { $sector = get_option('b4_settings_homepage_category_10')[0]; }
    if ( $cat == 12 ) { $sector = get_option('b4_settings_homepage_category_11')[0]; }
    if ( $cat == 13 ) { $sector = get_option('b4_settings_homepage_category_12')[0]; }
    if ( $cat == 14 ) { $sector = get_option('b4_settings_homepage_category_13')[0]; }
    //that 'get_option' outputs as the plain ID of the taxonomy

    //args & query
    $args_cat = array(
        'post_type'      => $post_types,
        'posts_per_page' => 3,
        'fields'         => 'ids',
        'post__not_in'   => array( $feat_ids, $latest_ids, $trend_ids ),
        'tax_query'      => array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'sector',
                'field'    => 'id',
                'terms'    => $sector
            )
        )
    );

    return new WP_Query( $args_cat );
}
1
  • Thanks Petar. I tried this but it didn't work. Tried moving the order in which things are defined as well (as I was getting 'undefined variable' warnings) but no luck yet. I'm trying to do it like this at the moment: $cat[1] = [ 'tax_query' => [ 'relation' => 'AND', [ 'taxonomy' => 'sector', 'field' => 'id', 'terms' => get_option('b4_settings_homepage_category_1')[0] ] ] ]; $i = 0; and then the query as $i++; $cat_query = new WP_Query( wp_parse_args( $cat[$i], $cat_args ) ); but am obviously barking up the wrong tree as still not working. Commented Nov 10, 2021 at 11:50
0

if your second code works correctly, just do this

$option = "b4_settings_homepage_category_".$cat;
$sector = get_option($option)[0];

this will make your option with the cat variable, for example b4_settings_homepage_category_7 , is the same as the if statment but more elegant. also your first code probably isnt working just because the $cat variable should be before the if statments, not after.

so the inteire code should be:

$cat = 7;
$option = "b4_settings_homepage_category_".$cat;
$sector = get_option($option)[0];
$args_cat = array(
   'post_type' => $post_types,
   'posts_per_page' => 3,
   'fields' => 'ids',
   'post__not_in' => array( $feat_ids, $latest_ids, $trend_ids ),
   'tax_query' => array(
      'relation' => 'AND',
      array(
         'taxonomy' => 'sector',
         'field' => 'id',
         'terms' => $sector
      )
   )
);
$cat_query = new WP_Query( $args_cat );
while ( $cat_query->have_posts() ) {
    $cat_query->the_post();
    // etc etc
}
2
  • 1
    Thank you! It's the $cat variable being after the if statement which is causing the problem really, as the page is set up like: 1. queries, args, if statements -> 2. page content with variables. So I guess it needs to be a combination of your solution (which is lovely and clean, thank you!) + a function... Commented Nov 11, 2021 at 12:04
  • great! :), the if statement needs to have the variable that is checking firstly indicated. Also you can replace your if statements by the two lines of the first code indicated in this answer, works as well and its more dynamic, this to say that if you had 5 000 options, imagine..., I strongly believe this solution should work perfectly, just need to add the rest of the code in the while loop on the line that has the // etc etc Commented Nov 11, 2021 at 12:29
0

your right answer could find an issue, when $i is less or equal to zero will trow an error, that $sector is being used by the first time, so one way to prevent that is

function prefix_get_wp_query( $i ) {
 if ( $i > 0 ) { 
  $cat = "b4_settings_homepage_category_".$i;
  $sector = get_option($cat)[0];
  $cat_args = [
  'post_type'      => $post_types,
  'posts_per_page' => 3,
  'fields'         => 'ids',
  'post__not_in'   => [ $feat_ids, $latest_ids, $trend_ids ],
  'tax_query'      => [
   'relation' => 'AND',
    [ 'taxonomy' => 'sector',
      'field'    => 'id',
      'terms'    => $sector
    ]
   ]
  ];
  return new WP_Query( $cat_args );
 } else {
  return 0;
 }
}

if you know it will always be greater than 0, the if can be simply removed

function prefix_get_wp_query( $i ) {
  $cat = "b4_settings_homepage_category_".$i;
  $sector = get_option($cat)[0];
  $cat_args = [
  'post_type'      => $post_types,
  'posts_per_page' => 3,
  'fields'         => 'ids',
  'post__not_in'   => [ $feat_ids, $latest_ids, $trend_ids ],
  'tax_query'      => [
   'relation' => 'AND',
    [ 'taxonomy' => 'sector',
      'field'    => 'id',
      'terms'    => $sector
    ]
   ]
  ];
  return new WP_Query( $cat_args );
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.