functions.php
// いいね機能
add_action('wp_ajax_nopriv_get_like_count', 'get_like_count');
add_action('wp_ajax_get_like_count', 'get_like_count');
function get_like_count() {
if (!isset($_POST['post_id'])) {
wp_die('Post ID is missing');
}
$post_id = intval($_POST['post_id']);
$likes = get_post_meta($post_id, 'likes_count', true);
$likes = $likes ? (int)$likes : 0;
wp_send_json(array('likes' => $likes));
}
add_action('wp_head', 'my_ajaxurl');
function my_ajaxurl() {
echo '<script type="text/javascript">
var ajaxurl = "' . admin_url('admin-ajax.php') . '";
</script>';
}
add_action('wp_ajax_nopriv_process_like_cookie', 'process_like_cookie');
add_action('wp_ajax_process_like_cookie', 'process_like_cookie');
function process_like_cookie() {
if (!isset($_POST['post_id'])) {
wp_die('Post ID is missing');
}
$post_id = intval($_POST['post_id']);
$likes = get_post_meta($post_id, 'likes_count', true);
$likes = $likes ? (int)$likes : 0;
error_log("Initial likes for post {$post_id}: {$likes}");
// Check if cookie exists
if (isset($_COOKIE['liked_' . $post_id])) {
// Cookie exists, user has already liked this post, so we "unlike" it
if ($likes > 0) {
$likes--;
update_post_meta($post_id, 'likes_count', $likes);
setcookie('liked_' . $post_id, '', time() - 3600, '/'); // Remove the cookie
error_log("User unliked post {$post_id}, new likes: {$likes}");
} else {
error_log("User tried to unlike post {$post_id}, but likes are already 0");
}
} else {
// No cookie, user hasn't liked this post, so we "like" it
$likes++;
update_post_meta($post_id, 'likes_count', $likes);
setcookie('liked_' . $post_id, 'yes', time() + 86400 * 30, '/'); // 30 days
error_log("User liked post {$post_id}, new likes: {$likes}");
}
echo $likes;
wp_die();
}
header.php
< link の記載が連続してあるので、その後ろに以下を追加。
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet">
同じように <script の記載が連続してあるので、その後ろに以下を追加。
<script>
jQuery(document).ready(function($) {
function updateLikeButton(post_id) {
var $likeIcon = $('.like-button[data-postid="' + post_id + '"]').find('i');
if (getCookie('liked_' + post_id)) {
$likeIcon.removeClass('far').addClass('fas');
} else {
$likeIcon.removeClass('fas').addClass('far');
}
}
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length === 2) return parts.pop().split(";").shift();
}
$('.like-button').each(function() {
var post_id = $(this).data('postid');
updateLikeButton(post_id);
});
$('.like-button').on('click', function(e) {
e.preventDefault();
var $likeButton = $(this);
var post_id = $likeButton.data('postid');
var $likeCount = $('#like-count-' + post_id);
var currentCountText = $likeCount.text();
var is999Plus = currentCountText === '999+';
var currentCount = parseInt(currentCountText);
var buttonOffset = $likeButton.offset();
var buttonHeight = $likeButton.outerHeight();
var wasLiked = getCookie('liked_' + post_id);
if ($likeButton.data('processing')) {
return;
}
$likeButton.data('processing', true);
$.ajax({
type: "POST",
url: ajaxurl,
data: {
action: "process_like_cookie",
post_id: post_id,
},
success: function(response) {
var newCount = parseInt(response);
updateLikeButton(post_id);
if (newCount > 999) {
$likeCount.text('999+');
} else {
$likeCount.text(newCount);
}
if (newCount > currentCount && newCount > 999) {
$likeCount.animate({
fontSize: '1.8rem'
}, 500, function() {
$(this).animate({
fontSize: '1.6rem'
}, 500);
});
}
if (!wasLiked) {
$('#like-message').css({
'position': 'absolute',
'top': (buttonOffset.top + buttonHeight + 5) + 'px',
'left': buttonOffset.left + 'px',
'display': 'block'
}).fadeIn(500).delay(2000).fadeOut(500, function() {
$(this).css('display', 'none');
});
}
$likeButton.data('processing', false);
}
});
});
});
</script>
style.css
.like-button i {
color: #FF2F40;
}
.like-button {
font-size: 24px;
background: none; /* 背景色を透明に */
border: none; /* 枠線を削除 */
padding-left: 20px;
padding-right: 0px;
margin: 10px; /* マージンを削除 */
color: inherit; /* ボタンのテキスト色を親要素から継承 */
}
.like-button:hover {
cursor: pointer; /* マウスカーソルをポインターに変更 */
opacity: 0.7; /* ホバー時にボタンを少し透明にする */
}
/* いいねされた時のメッセージ */
#like-message {
display: none;
position: absolute; /* 固定位置から絶対位置に変更 */
background-color: #ff8793; /* ピンク色 */
color: white;
padding: 10px 20px;
border-radius: 5px;
z-index: 1000;
font-size: 16px;
}
functions.phpで強制読み込みを実施
footer.php
htmlの閉じタグの直前に以下を追加
(ブログによってカスタマイズする場合はメッセージを変える)
<div id="like-message" style="display: none;">ありがとうございます!</html>
single.php
<?php the_content(); ?>
のすぐ下に
<?php
echo '<button class="like-button" data-postid="'.get_the_ID().'">';
echo '<i class="far fa-heart"></i>';
echo '</button>';
?>
<span id="like-count-<?php echo get_the_ID(); ?>"></span>
<script>
var postId = <?php echo get_the_ID(); ?>;
var initialLikeCount = <?php echo get_post_meta(get_the_ID(), 'likes_count', true) ?: 0; ?>;
</script>
<script src="<?php echo get_template_directory_uri(); ?>/like-count.js?v=<?php echo filemtime(get_template_directory() . '/like-count.js'); ?>"></script>
以上