0

I'm doing a plugin to add likes to posts

I want to create a table on a page in the plugin to show each post and the number of likes

function my_plugin_options() {

    echo '<p>Table of Likes</p>';
    echo '</div>';

    echo '<table>';
  echo '<tr>';
  echo '<td>Post</td>';
  echo '<td>Number of likes</td>';
  echo '</tr>';

    // -- WP_Query -- 

    $like_args = array(
        'post_type' => 'post',
        'order' => 'DES',
        'post_status' => 'publish'
    );

    $like_loop = new WP_Query($like_args);

    if($like_loop->have_posts()):
        while($like_loop->have_posts()):
            $like_loop->the_post();

    // -- WP_Query -- 


    $likes = get_post_meta( $like_loop->post_ID, "_like_amount", true);     

    echo '<tr>';
    echo '<td>';
    the_title();
    echo '</td>';
    echo '<td>';
    $likes;
    echo '</td>';
    echo '</tr>';

    endwhile;
    endif;

    wp_reset_postdata();

    echo '</table>';
}

I have a meta field in each post '_like_amount' that is the number of likes.

How do I use get_post_meta to retrieve the meta field in my WP_Query loop?

I've tried

$likes = get_post_meta( $like_loop->post_ID, "_like_amount", true);

But it fails

3
  • 1
    Can you rephrase what you're asking? What does your code do that's wrong, what do you need it to do? It's very difficult to understand what you're asking, you say how do you use this in WP_Query, but use it to do what exactly? – Tom J Nowell May 26 '14 at 19:40
  • Got it working now by adding global $post and using $post->ID. I have updated the original post code. – user51590 May 26 '14 at 20:14
  • Can you explain what your original issue was, and post the answer as an answer ( don't edit the original code to fix it in the question ) – Tom J Nowell May 26 '14 at 22:39
3

If you will be pulling a lot of posts (or simply want to reduce the number of queries made), I'd recommend re-writing things a little bit.

First, build a filter function to modify the query you are about to make.

function filter_query_add_likes( $clauses, WP_Query $wp_query ) {
    if ( !is_admin() && !$wp_query->is_main_query() ) {
        global $wpdb;

        # Add your wanted meta value in as times_liked
        $clauses['fields'] .= ', IFNULL( meta_like.meta_value, 0 ) as times_liked ';

        # Join the postmeta field based on the post id and the key wanted
        # - this assumes you only have one times_liked meta for each post id!
        $clauses['join'] .= <<<SQL
 LEFT JOIN {$wpdb->prefix}postmeta AS meta_like ON meta_like.post_id = {$wpdb->prefix}posts.ID AND meta_like.meta_key = '_like_amount'
SQL;

    }
    return $clauses;
}

Next, use that filter right before you run your query to get your likes field back in each post.

function my_plugin_options() {
    # Same as what you did, just using heredoc
    echo <<<HTML
<p>Table of Likes</p>
</div>
<table>
<tr>
    <td>Post</td>
    <td>Number of Likes</td>
</tr>
HTML;


    $like_args = array(
        'post_type' => 'post',
        'order' => 'DES',
        'post_status' => 'publish'
    );
    # Set our new filter query to apply for this query
    add_filter('posts_clauses', 'filter_query_add_likes', 10, 2);

    $like_loop = new WP_Query( $like_args );

    # Remove our filter query to avoid touching other queries on accident
    remove_filter('posts_clauses', 'filter_query_add_likes', 10, 2);

    if ( $like_loop->have_posts() ) {
        while ( $like_loop->have_posts() ) {
            # using next_post like this pulls your posts out for easy access
            $current_post = $like_loop->next_post();

            # your times_like (from the filter) can now be accessed without
            # having to do an extra query with get_post_meta()
            $likes = $current_post->times_liked;
            # your title can be pulled right in if wanted
            $title = $current_post->post_title;

            # Draw your column
            echo <<<HTML
<tr>
    <td>{$title}</td>
    <td>{$likes}</td>
</tr>
HTML;

        }
    }

    # End the table
    echo "\r\n</table>";

}

This does a couple of things:

  • You now only use a single query to pull in all results that you want to show
  • You can easily pull whatever you want from the post object, including the number of times the post was liked.
  • If there is no likes count yet on a post, it will receive 0 due to the ISNULL call made when editing the fields clause.

Overall, much faster than using get_post_meta, especially if you are dealing with a lot of posts.

1
  • I just noticed that post meta is actually cached ... so this actually doesn't improve the speed much. I still find it a bit cleaner though ;) – Privateer Sep 18 '15 at 21:36
1

Once your run $like_loop->the_post() the global $post variable is set to the current post in the Loop, so what you want is:

$likes = get_post_meta( $post->ID, "_like_amount", true); 

Or...

$likes = get_post_meta( get_the_ID(), "_like_amount", true); 

... which is a bit more robust in some circumstances.

However, I don't know what you mean by "How do I use this meta field in my WP_Query". The code you provide as a sample has little to do with WP_Query and if you are wanting to include that value in the query arguments you don't explain what conditions you are wanting to query for.

1
  • I'd already tried both your suggestions but they haven't worked. The code provided uses a WP_Query to query the posts - I have added comments where I THINK I'm using a WP_Query. In the loop from the WP_Query I want to use the meta value in _like_amount. – user51590 May 26 '14 at 19:26
1

Original poster indicates this is the solution:

global $post;

$likes = get_post_meta( $post->ID, "_like_amount", true);

The issue was grabbing the current Posts ID

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.