I'm writing new theme for my blog. And I want to make some kind of post rating using custom fields.

There are two fields: 'good-post' and 'bad-post'. And after each post I placed two buttons. Yep, 'Good post' and 'Bad post'. On buttons I placed onclick event that calls this AJAX function:

function ajaxIncGoodPost(tempUrl)  {
    var postID = $("good-post").attr("rel");

    type: "POST",
    url : tempUrl+"/rating.php",
    data: "opinion=good&postID="+postID,
    success: function(msg){
    alert( "Спасибо за вашу хорошую оценку!" );

It calls this function in rating.php:

$postID = $_REQUEST['postID']; 

if ( $_REQUEST['opinion'] == 'good' ) {
    $good_post = get_post_meta($postID, 'good-post');

    function inc_good_post() {
        update_post_meta($postID, 'good-post', $good_post); 

So every click on this button calls function that increments 'good-post' value and stores it in the field. But here comes the problem. After click on the button success messege of AJAX function pops up, but value of custom field doesn't changes.

I thought this happens because there is no such fields in my old posts, but according to Wordpress Codex upadate_post_meta() checks if such field exists and if not calls add_post_meta() which creates field. But this doesn't heepen either.

At this point I can't find any mistake. If you have any guesses about this problem please share it!


First off, you should consider using using the building WordPress functionality rather than linking straight to a PHP file. Anyone could game that very easily and artificially vote up posts.

To use the wordpress ajax functionality, send your ajax request to yoursite.com/wp-admin/admin-ajax.php, and use standard plugin hooks system.

Tollmanz's response is right on: your update post meta and get post meat calls aren't working because the WordPress environment is not loaded in rating.php. Another reason to use admin-ajax.php to handled your response.

Here's an example:

add_action( 'wp_ajax_nopriv_wpse26789_action', 'wpse26789_ajax_cb' );
add_action( 'wp_ajax_wpse26789_action', 'wpse26789_ajax_cb' );
function wpse26789_ajax_cb()
    // Verify the nonce to make sure the request came from an actual page...
    if( !isset( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'wpse26789_nonce' ) ) die( '-1' );

    $post_id = isset( $_REQUEST['post_id'] ) ? absint( $_REQUEST['post_id'] ) : 0;

    if( ! $post_id ) die( '-1' );

    $counter = get_post_meta( $post_id, 'good_post', true );
    $counter = absint( $counter );

    if( $counter )
        $counter = 1;

    update_post_meta( $post_id, 'good_post', $counter );
    echo $counter;

Then your front end could would have to change a little bit.

Here's a function you could drop inside the loop on your single.php file:

function wpse26789_good_bad()
    global $post;
    $count = get_post_meta( $post->ID, 'good_post', true );
    <p id="wpse26789_click">Click Here to Vote this Post up</p>
    <p>This post has <span id="wpse26789_count"><?php echo strip_tags( $count ); ?></span> votes</p>

Eg. somewhere in single.php insert wpse26789_good_bad() or insert the code from the function into single.php (except for the global $post) anywhere inside the loop.

Then you'll need to change up your javascript a bit. I've just hooked into wp_head here to add the javascript to the <head> section of any singular post.

add_action( 'wp_head', 'wpse26789_head' );
function wpse26789_head()
    if( ! is_singular() ) return;
    $post_id = get_queried_object_id();
    <script type="text/javascript">
        var wpse26789_data = {
            action: 'wpse26789_action',
            post_id: '<?php echo absint( $post_id ); ?>',
            nonce: '<?php echo wp_create_nonce( 'wpse26789_nonce' ); ?>',
            jQuery( '#wpse26789_click' ).click(function(){
                    '<?php echo site_url( 'wp-admin/admin-ajax.php' ); ?>', 
                    function( data ){
                        if( '-1' != data )
                            jQuery( 'span#wpse26789_count' ).html( data );
                            alert( 'Your Message!' );

As a plugin: http://pastie.org/2423993

  • Thank you very much @Christopher! With your examples it was much easier for me to understand articles mentioned in codex. And after a bit of reading I ended up with pair of nice looking and working post rating buttons. – Nikita Kasyanov Aug 26 '11 at 14:54
  • unfortunately I was wrong. It doesn't work properly on posts without that custom field. update_post_meta(#post_id, 'good-post', $counter) doesn't create custom field 'good-post' if it doesn't exist. This is my code from functions.php: link – Nikita Kasyanov Aug 27 '11 at 17:00

My best guess at this without seeing more code and seeing that you are routing your AJAX request to a separate PHP file is that your "rating.php" is not loaded in the WordPress environment, meaning that functions like get_post_meta and update_post_meta are not available to you at the time you try to use them. WordPress implements an excellent system for making AJAX calls within the WordPress environment. Take a look at this article as a start: http://codex.wordpress.org/AJAX_in_Plugins.

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.