【WordPress】プラグインを使わずに高評価ボタンと低評価ボタンを実装する

この記事の情報は備忘録的な意味あいが強いため、こういう実装の仕方があるんだなー程度で参考にしたほうが良いと思います。

スポンサーリンク

高評価ボタンと低評価ボタンの仕組み

フィールドを作成して高評価ボタンと低評価ボタンをクリックすると、対応したフィールドの値をAjax経由で増加させます。値の減には対応していません。クリックしたらフィールドの値を増加させるとともにクッキーをセットして、一度評価ボタンをクリックしたらもう一度クリックできないようにします。

今回はクッキー使って制御しますが、本来この手の評価ボタンをクッキーだけで制御することはまずありえないと思います。おそらくログイン機能がないサイトの場合はデータベースに評価データのテーブルを作成し、評価ボタンをクリックしたユーザーの一意の識別子(IPアドレスやクッキーの値)と評価情報を保存するのが一般的でしょう。ですので今回の実装はやはり参考程度にとどめておくべきです。

スポンサーリンク

高評価ボタンと低評価ボタンを実装する

Advanced Custom Fieldsをインストールしてフィールドを作成

  1. Advanced Custom Fields (ACF) – WordPress プラグイン | WordPress.org 日本語」をインストールして「ldbtns」というフィールドグループをつくる(ちなみにldbtnsというのは好きな名前でいい)
  2. フィールドグループを作ったらこのフィールドグループに「高評価ボタン」と「低評価ボタン」フィールドを作成する。ラベルは「高評価ボタン」と「低評価ボタン」にして名前はそれぞれ「like_counter」「dislike_counter」にする(ちなみにラベルや名前はそれぞれわかりやすい名前をつけてもいいですが、後のfunctions.phpやフロントの処理で使用することを念頭においてください)

実際にフィールドを作成した画像↓

記事一覧に評価フィールドを表示

functions.phpに以下のコードを記述すると記事一覧ページで記事に対する高評価の数と低評価の数を確認できるようになります。

/*---------------------------------------------------------------------------
投稿一覧ページにカスタムフィールド追加
 *---------------------------------------------------------------------------*/
function add_custom_field_columns_to_posts_list($columns) {
    $columns['like_counter'] = '高評価';
    $columns['dislike_counter'] = '低評価';
    return $columns;
}
add_filter('manage_post_posts_columns', 'add_custom_field_columns_to_posts_list');

// カスタムフィールドの値を投稿一覧に表示する
function show_custom_field_columns_data_on_posts_list($column_name, $post_id) {
    if ($column_name == 'like_counter') {
        $like_counter = get_post_meta($post_id, 'like_counter', true);
        echo ($like_counter === null) ? "0" : $like_counter;
    } elseif ($column_name == 'dislike_counter') {
        $dislike_counter = get_post_meta($post_id, 'dislike_counter', true);
        echo ($dislike_counter === null) ? "0" : $dislike_counter;
    }
}
add_action('manage_post_posts_custom_column', 'show_custom_field_columns_data_on_posts_list', 10, 2)

functions.phpにコードを記述したあとの記事一覧ページです↓高評価と低評価のカラムが追加され記事に対応した値を確認できるよにしました(ただこちらは一度ページを表示しないと値が表示されません。このときの値はnullになっています。)

single.phpに評価ボタンのコードを記述

single.phpに評価ボタンのコードを記述して記事にアクセスしたときに評価ボタンが表示されるようにします。

以下single.phpの好きな部分に記述(記事下にボタンを配置するのが一般的かと思いますので、コードをみて記事下の部分にコードを記述します)

	//評価ボタン
echo '<div class="ldbtns">';
echo '<button class="like_button" data-id="' . $post->ID . '">';
echo '<i class="material-icons">thumb_up</i>';
echo '<span class="like_counter">';
$like_counter = get_field('like_counter');
echo ($like_counter === null) ? "0" : $like_counter;
echo '</span>';
echo '</button>';
echo '<button class="dislike_button" data-id="' . $post->ID . '">';
echo '<i class="material-icons">thumb_down</i>';
echo '<span class="dislike_counter">';
$dislike_counter = get_field('dislike_counter');
echo ($dislike_counter === null) ? "0" : $dislike_counter;
echo '</span>';
echo '</button>';
echo '</div>';

get_field()はACFの関数ですので、現在の高評価・低評価フィールドの値を取得しています。グーグルマテリアルアイコン対応のテーマをつかっているのでアイコンも使用しました。

functions.phpで高評価ボタンと低評価ボタンをおしたときに値を増加させる処理を記述

/*---------------------------------------------------------------------------
高評価フィールドのカウントを増やす
 *---------------------------------------------------------------------------*/
function like_count_up(){
  $postID = $_POST['postID'];
  $count = get_field('like_counter',$postID);
  update_post_meta( $postID, 'like_counter', $count + 1, $count );
  die();
}
add_action( 'wp_ajax_like_count_up', 'like_count_up' );
add_action( 'wp_ajax_nopriv_like_count_up', 'like_count_up' );
/*---------------------------------------------------------------------------
低評価フィールドのカウントを増やす
 *---------------------------------------------------------------------------*/
function dislike_count_up(){
  $postID = $_POST['postID'];
  $count = get_field('dislike_counter',$postID);
  update_post_meta( $postID, 'dislike_counter', $count + 1, $count );
  die();
}
add_action( 'wp_ajax_dislike_count_up', 'dislike_count_up' );
add_action( 'wp_ajax_nopriv_dislike_count_up', 'dislike_count_up' );

記事に対応した評価ボタンの数を1増やします。add_action() 関数によって wp_ajax_xxx と wp_ajax_nopriv_xxx が登録されることで、WordPressはログイン済みユーザーと非ログインユーザーの両方でAjaxリクエストが発生した際に、このアクションフックを介して指定されたコールバック関数が呼び出します。このあとに実際にAjaxリクエストを送信する部分のフロント処理を実装しますが、ようするに評価ボタンをクリックするとAjax経由でfunctions.phpで定義した関数を実行するということです。こうすることによってページの更新なしで評価ボタンの値を増加させることができます。

WordPressのAjaxに関してはこのwp_ajax_xxxというフックをつかうことによってAjax通信を実現させますが、具体的にはWordPressでAjax通信を行う場合は「/wp-admin/admin-ajax.php」にリクエストを送って指定のアクションを実行するのが一般的です。

WordPressでAjax通信する一般的なやり方が知りたい場合は以下のサイトが参考なると思います↓
WordPressでAjaxを使う方法 – https://agohack.com/ajax-on-wordpress/

フロントの実装

フロントを実装します。名前はなんでもいいのですがとりあえずわたしは「my-ajax.js」というファイルを作りました。

$(document).ready(function() {
    $('.like_button, .dislike_button').each(function() {
        var $button = $(this);
        var postID = $button.data('id');
        if (Cookies.get('liked_post_' + postID) || Cookies.get('disliked_post_' + postID)) {
            $('.like_button, .dislike_button').prop('disabled', true);
            return false; // eachループを抜ける
        }
    });
});

$(document).on('click', '.like_button:not([disabled]), .dislike_button:not([disabled])', function() {
    var $target = $(this);
    var count = Number($target.find('.like_counter, .dislike_counter').html()) + 1;
    var postID = $target.data('id');
    if (Cookies.get('liked_post_' + postID) || Cookies.get('disliked_post_' + postID)) {
        // クッキーが存在する場合は何もしない
        alert('すでに投票済みです');
        return false;
    }
    if ($target.hasClass('like_button')) {
        // いいねボタンがクリックされた場合
        Cookies.set('liked_post_' + postID, 'true', {
            expires: 365
        });
        jQuery.ajax({
            url: ad_url.ajax_url,
            type: 'POST',
            data: {
                'action': 'like_count_up',
                'postID': postID
            },
            success: function(data) {
                $('.like_counter').html(count);
            }
        });
    } else if ($target.hasClass('dislike_button')) {
        // 低評価ボタンがクリックされた場合
        Cookies.set('disliked_post_' + postID, 'true', {
            expires: 365
        });
        jQuery.ajax({
            url: ad_url.ajax_url,
            type: 'POST',
            data: {
                'action': 'dislike_count_up',
                'postID': postID
            },
            success: function(data) {
                $('.dislike_counter').html(count);
            }
        });
    }
    $('.like_button, .dislike_button').prop('disabled', true); // 両方のボタンを無効化する
    return false;
});

クリックしたらボタンに対応したアクション(さっきfunctions.phpで定義したアクション)呼び出して評価ボタンの値を増加させます。クリックしたときにクッキーをセットして、次にユーザーがページに訪問したときにクッキーがあったらボタンをクリックできないようにします。

WordPressでJSファイルを読み込む

本来ならばこちらをさきに定義しておくべきかもしれません。WordPressでJSファイルを読み込む方法は「wp_enqueue_scripts」を使うのが一般的です。

function my_enqueue() {
  // 特定のページのみで読み込む(ここでは、スラッグ「sample-page」という固定ページにアクセスすると読み込まれる)
  if (is_single() || is_page()) {
    // Ajaxの処理を書いたjsの読み込み
    wp_enqueue_script( 'ajax-script', get_stylesheet_directory_uri().'/my-ajax.js', array('jquery'), null, true );
    // 「ad_url.ajax_url」のようにしてURLを指定できるようになる
    wp_localize_script( 'ajax-script', 'ad_url',array( 'ajax_url' => admin_url( 'admin-ajax.php') ) );    
  }
}
add_action( 'wp_enqueue_scripts', 'my_enqueue' );

さきほど定義した「my-ajax.js」を読み込むようにしています。また「admin-ajax.php」にリクエストを送れるようにもしました。

まとめ

ここまでみてきましたがWordPressでプラグインを使わずに評価ボタンを実装しようとすると、少し煩雑になります。また今回はクッキーで制御しているので一般的な実装とも言えないと思います。ただこういうやり方があるのかと参考になる部分もあるかもしれないのでとりあえず備忘録的に書いてみました。簡単にいえばAjax経由で指定のアクションを実行してフィールドの値を増加させているだけです。

コメント

タイトルとURLをコピーしました