Из-за большого обилия рубрик у меня появилась идея сделать возможность добавлять их в "Избранное" для быстрого доступа к ним с любой страницы. Добавлять рубрики в "Избранное" я захотел через ajax, но столкнулся с проблемой полного отсутствия знания java script, jquery и вообще это темный лес для меня.
Тогда я отправился в google но ничего похожего не нашел и решил делать все сам.
Внимание! Как я уже писал jquery я не знаю и все что написано ниже - копи-паст отдельных частей с разных источников и подгонка под нужный функционал. Я не исключаю того что что-то можно реализовать проще, красивее и т.п. если будут предложения по улучшению - с радостью внесу изменения тут и у себя на сайте.
Первое что нам надо сделать - страницу с категориями, на которой мы выведем все категории доступные для добавления в "Избранное"
примечание: я не буду давать код вывода категорий, это не трудно найти в гугле. Да и у меня это не просто вывод категорий, а еще и подсчет суммарного кол-ва просмотров и скачиваний постов в категории.
Перед циклом вывода категорий нам надо получить ID всех категорий, которые пользователь уже добавил в избранное. Как понятно из кода (или если не понятно) избранные категории будут храниться в мета-поле пользователя закодированные в json (по другому я не придумал как)
($user_ID - это глобальная переменная, в которой ID текущего пользователя (вроде работает только с wp-recall))
<?php global $user_ID; // Берем все избранное у пользователя. Проверять есть ли там добавляемая категория // будем в цикле $user_featured = get_user_meta( $user_ID, 'featured_cat_id', true ); ?>
А этот код будет уже внутри цикла вывода категорий ($game['ID'] - это ID текущей категории в цикле)
<?php
// Проверяем если что-то в избранном у пользователя
if($user_featured) {
//Т.к. в избранном что-то есть, значит надо проверить - есть ли текущая категория цикла в избранном
if(($key = array_search($game['ID'], $user_featured)) !== FALSE){
// $game['ID'] - это id текущей категории в цикле. Если этот id есть в $user_featured - значит
// мы выводим текст удалить, а в class добавим "remove" что бы стилем выделить эту кнопку
$text = "Удалить";
$remove = "remove";
} else {
// Если искомого id нет в избранном - значит выводим текст добавить, а класс "remove" не присваиваем
$text = "Добавить";
$remove = "";
}
} // Если ничего нет, значит предлагаем только добавить
else {
$text = "Добавить";
$remove = "";}
?>
<div class="favorite-add-game <?php echo $remove; ?>" data-game-id="<?php echo $game['ID'];?>">
<?php echo $text; ?>
</div>
Теперь нам нужно добавить скрипт, который будет реагировать на клик создаваемой кнопки и отправлять ajax запрос с id этой кнопки (где указана категория) на добавление в избранное (или удаление) - обработчик всего этого ниже, после кода скрипта.
<script type="text/javascript" >
jQuery(document).ready(function(){
// При клике по блоку с классом "favorite-add-game" выполняем функцию
jQuery(".favorite-add-game").click(function(){
//Добавляем нашей кнопке класс "progress" что бы во время ожидания ответа показывать кружочек
jQuery(this).toggleClass("progress");
// Записываем в переменную element текущий объект по которому был клик
var element = this;
// Записываем в переменную game_id значение атрибута data-game-id из элемента по которому был клик
var game_id = jQuery(this).data('game-id');
// отправляем ajax запрос
jQuery.post("/wp-admin/admin-ajax.php", {
// my_action - уникальный id который так же мы вписываем в обработчике (следующий блок кода)
// add_action wp_ajax_my_action - который, как я понял, нужен что бы
// wordpress понял какую функцию запустить (в нашем случае это будет my_action_callback)
action : 'my_action',
// Тут думаю все понятно, в $_POST['catid'] будет id категории
catid : game_id,
// Это для проверки (хоть у нас и работает весь этот код только для авторизованных, но пусть будет)
nonce:'<?php echo wp_create_nonce('featured'); ?>' },
// После отправки запроса wordpress нам вернет результат result. В нашем коде это будет текст
// Добавить - если категорию удалили из избранного и Удалить - если добавили
function(result){
// Меняем текст внутри нашей кнопки на то, что получили в ответе. Тут то нам и пригодится
// переменная element (т.к. this тут не сработает, но по сути мы обращаемся к нашей кнопке)
jQuery(element).text(result);
// Добавляем класс remove если категорию добавили в избранное или удаляем этот класс если удалили
// категорию из избранного
jQuery(element).toggleClass("remove");
// Убираем класс progress т.к. получили ответ от wordpress и иконка загрузки больше не нужна
jQuery(element).toggleClass("progress"); } );
});
});
</script>
Ну и самое последнее - код в functions.php который и будет обрабатывать наш запрос на добавление в избранное.
// в коде скрипта я уже описал что это, т.е. при получении ajax запроса с action: my_action
// запускаем нашу функцию
add_action('wp_ajax_my_action', 'my_action_callback');
function my_action_callback() {
// объявляем глобальную переменную с ID пользователя который кликнул по кнопке
global $user_ID;
// Получаем id категории
$catid = $_POST['catid'];
// Получаем код проверки nonce
$nonce = $_POST['nonce'];
// Если проверка пройдена, продолжаем. Иначе... Иначе какого хуя?
if (!wp_verify_nonce($nonce, 'featured')) die( 'Какого хуя?');
// Получаем все избранные категории пользователя (значение мета поля 'featured_cat_id')
$user_featured = get_user_meta( $user_ID, 'featured_cat_id', true );
// Смотрим есть ли в избранном что то
if ($user_featured) {
// Ищем в массиве нашу категорию и удаляем ее если она там уже есть
if(($key = array_search($catid, $user_featured)) !== FALSE){
// Удаляем категорию
unset($user_featured[$key]);
// В ответ пишем текст "Добавить", т.к. если мы удалили категорию из массива - значит она там была
// И пользователь нажал удалить
$text = "Добавить";
}
// Если мы не нашли в избранном нашу категорию, то добавляем ее
else {
$user_featured[] = $catid; // если нет добавляем
$text = "Удалить"; // Пишем текст "Удалить", т.к. мы добавили категорию в избранное
}
}
// Если в избранном ничего нет, значит добавим в массив $user_featured ID категорию которую добавляем
//в избранное
else {
$user_featured[] = $catid;
$text = "Удалить";
}
// Обновляем мета-поле пользователя
if (update_user_meta( $user_ID, 'featured_cat_id', $user_featured )) {
// Пишем ответ "Добавить" - если удалили категорию и "Удалить" - если добавили категорию
echo $text;
}
// Если update_user_meta не сработал, значит какая то ошибка и выведем на кнопку текст:
else {
echo "Ошибка. Сообщите администратору";
}
die(); // обязательно в ajax запросах
}
Ну вот и все, теперь осталось вывести результат. В моем случае это будет в выпадающем меню (скриншоты все в конце)
<?php
// Берем все избранное у пользователя. Проверять на наличие там категории будем уже в цикле
$user_featured = get_user_meta( $user_ID, 'featured_cat_id', true );
// Если в избранном ничего нет, то напишем это
if(!$user_featured) { ?>
<p class="no-game">Вы еще не добавляли игры в избранное.<br>Перейдите по ссылке ниже на страницу с играми,
там вы сможете добавить игры в избранное.</p>
<?php }
// Если в избранном что то есть, то получим все категории с ID которые есть в избранном
else {
$args = array( 'include' => $user_featured );
// Записываем в переменную все категории что есть в избранном
$allgames = get_terms('category',$args);
// Считаем их количество
$count = count($allgames);
// Выводим
for ($i=0; $i < $count; $i++) { ?>
<a href="/<?php echo $allgames[$i]->slug; ?>/">
<h2><?php echo $allgames[$i]->name; ?></h2>
</a>
<?php }
} ?>
Вот и все. Конечно же я не уверен что конкретно мой пример кому-то понадобится, все таки задача довольно специфическая. Но может быть кто-то сможет использовать это как "базу" и переделать под себя.
Или укажет мне на ошибки и я их исправлю ![]()
А вот порция скриншотов как это работает у меня:





Опять же, не думаю что кому то пригодится, но вчера меня это очень бы выручило. Но ничего я не нашел и угрохал весь день на это, но сделал. Решил на радостях поделиться, может кому-то понадобится.
Если что-то не понятно - спрашивайте, только без "а куда вставлять?" все что выше расчитано на таких как я - вроде понимающих, но пишущих только из кусков чужих кодов
В скрипте 15 я строка
- ее тоже закомментировать нужно. 14я строка ведь закомментирована - с открывающим спаном
Да это подсветка плохо разбирается с кавычками в комментариях, удалил )
Для непросвещенных может быть неясно как реализовать цикл категорий в котором у вас размещается кнопка добавления, но в целом суть ясна. Код бы причесать, да активнее использовать хуки ВП).
Некритично, но глаз зацепился за хранение ИД категории в атрибуте id кнопки, это неграмотно, для этого существует атрибут data, например data-game-id="123", а затем получаете в js:
var game_id = jQuery(this).data('game-id');И думаю, зря вы кодируете массив данных в json, это лишнее, тк при сохранении массива в usermeta он автоматически будет сериализован, а при получении - десериализован.
Да, с id косяк, как то из головы вылетело что в css есть атрибут id, поправил и проверил - все работает.
По json сейчас попробую, посмотрим что там будет
Все, все строчки с json кодированием удалил - и в правду лишнее.
скажите а добавление в избранное для записей работает? как сделать есть инструкция? спасибо!
Для этого есть дополнение закладок - https://codeseller.ru/products/bookmarks-recall-polzovatelskie-zakladki-s-wp-recall/