1

I'm trying to create a shortcode that runs a custom query based on Yoast's primary category meta key.

The goal is to pull posts with the same meta key value of the post being displayed and show 4 more in the sidebar.

So far, everything is working but the query isn't getting posts with the same value.

I added an echo of the meta key value to make sure it was getting it, and it is.

Here's my code:

function primary_category_query_shortcode( $atts ) {
    $atts = shortcode_atts( $defaults, $atts, 'primary_category_query' );

    $my_meta = get_post_meta ( $id, '_yoast_wpseo_primary_category', true);

// WP_Query arguments
$args = array (
    'posts_per_page'         => '4',
    'meta_query'             => array(
        array(
            'key'       => '_yoast_wpseo_primary_category',
            'value'     => '$my_meta',
        ),
    ),
);

    echo get_post_meta( get_the_ID(), '_yoast_wpseo_primary_category', true);  

// The Query
$query = new WP_Query( $args );

// The Loop
if ( $query->have_posts() ) { ?>

    <section class="recent-posts clear">

    <?php while ( $query->have_posts() ) : $query->the_post() ; ?>

    <article id="post-<?php the_ID(); ?>" <?php post_class( 'left' ); ?>>

    <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
        <?php the_title(); ?>
    </a>

    </article>

    <?php endwhile; ?>

    </section>

    <?php } else {
        echo 'Sorry, no more found.';
    }

    /* Restore original Post Data */
    wp_reset_postdata();
}
?>```

8
  • So no error, it's just pulling incorrect posts? In the DB, in post_meta, can you confirm that the _yoast_wpseo_primary_category is being assigned to posts? Also, above this line echo get_post_meta( get_the_ID(), '_yoast_wpseo_primary_category', true); can you add a var_dump( $id ); and beneath that line var_dump( $my_meta ); so we can verify what's there? Want to make sure neither of those are empty. Apr 18, 2020 at 0:00
  • adding the single quote marks turns this '$my_meta' into a string, you want to use the variable direct: 'value' => $my_meta
    – Michael
    Apr 18, 2020 at 2:02
  • @TonyDjukic It's not pulling any posts currently. I pulled up the database and I'm confused by the results. link It seems like it's only being applied to 2 posts (if I'm reading right, I don't spend much time in databases), but I've assigned that meta to 6 posts and it's not showing the value I expected. Here's a picture of the output link since adding var_dump. "29" is the echo of the category ID I'm looking to pull from. Sorry if I'm missing something obvious, I'm new to queries obviously. And thank you!
    – Christina
    Apr 19, 2020 at 21:27
  • @Michael Thank you! Still learning. :)
    – Christina
    Apr 19, 2020 at 21:28
  • Good catch Michael, I completely missed that. Apr 19, 2020 at 21:51

1 Answer 1

1

Based on our chat in the comments here's what I came with. Please advise if it works.

<?php
function primary_category_query_shortcode( $post, $atts ) {
    //global $post;  //Uncomment this global if it still doesn't work.
    $atts = shortcode_atts( $defaults, $atts, 'primary_category_query' );
    $my_meta = get_post_meta ( $post->ID, '_yoast_wpseo_primary_category', true );
    // WP_Query arguments
    $args = array (
        'posts_per_page'         => '4',
        'meta_query'             => array(
            array(
                'key'       => '_yoast_wpseo_primary_category',
                'value'     => $my_meta
            ),
        ),
    );
    // All this would do is echo the ID of the category, correct?  Just for testing?
    //echo get_post_meta( get_the_ID(), '_yoast_wpseo_primary_category', true);  
    // The Query
    $query = new WP_Query( $args );
    // The Loop
    if ( $query->have_posts() ) { ?>
        <section class="recent-posts clear">
        <?php while ( $query->have_posts() ) : $query->the_post() ; ?>
            <article id="post-<?php the_ID(); ?>" <?php post_class( 'left' ); ?>>
                <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
                    <?php the_title(); ?>
                </a>
            </article>
        <?php endwhile; ?>
        </section>
    <?php } else {
        echo 'Sorry, no more found.';
    }
    /* Restore original Post Data */
    wp_reset_postdata();
}
?>

An explanation, what I suspect may be happening is that your attempt to get the Yoast Primary Category isn't succeeding because, based on your var_dump() you're not getting the post ID, it's coming back as NULL. So instead we'll include the $post in the function() and if that still doesn't work, we'll use global $post; to make sure it's being referenced. (That would be the second line, just uncomment it if it doesn't work without it.)

I've also commented out the echo get_post_meta( get_the_ID(), '_yoast_wpseo_primary_category', true ); because that would, in theory, just echo out the ID number of the category. So I assumed you had that in there for testing.

5
  • That was it! Thank you so much. I tried it as-is and got the unrelated posts back, so uncommented global and it's working. (And yes, the post meta echo was just for testing.) And thanks for the explanation too, very helpful as I'm learning all this!
    – Christina
    Apr 21, 2020 at 11:19
  • You’re very welcome. Sorry my reply was so delayed yesterday. Welcome to the community. 😊 Apr 21, 2020 at 12:18
  • Mind if I ask a follow-up question? :D This is working perfectly on my own site. But every other site I try to install it on gives me a warning: 'Warning: Invalid argument supplied for foreach() in ... /wp-includes/shortcodes.php on line 574' Here are lines 571 to 580: 'function shortcode_atts( $pairs, $atts, $shortcode = '' ) { $atts = (array) $atts; $out = array(); foreach ( $pairs as $name => $default ) { if ( array_key_exists( $name, $atts ) ) { $out[ $name ] = $atts[ $name ]; } else { $out[ $name ] = $default; } }' Pulling my hair out. :)
    – Christina
    May 21, 2020 at 19:54
  • Your foreach is $pairs as $name => $default but the code in my answer is $defaults. If when transferring the code over to other sites you shorted $defaults to $default that could be causing the problem. May 21, 2020 at 19:59
  • Just checked that and it does have '$defaults' I just now copied and pasted the code exactly as it was from the working one to one of the sites it's giving me the warning on just to double check everything. I hoped it was a plugin conflict, but I disabled all other plugins and reverted to twenty nineteen, still got it. :/
    – Christina
    May 21, 2020 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.