Из-за большого обилия рубрик у меня появилась идея сделать возможность добавлять их в "Избранное" для быстрого доступа к ним с любой страницы. Добавлять рубрики в "Избранное" я захотел через 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:
И думаю, зря вы кодируете массив данных в json, это лишнее, тк при сохранении массива в usermeta он автоматически будет сериализован, а при получении - десериализован.
Да, с id косяк, как то из головы вылетело что в css есть атрибут id, поправил и проверил - все работает.
По json сейчас попробую, посмотрим что там будет
Все, все строчки с json кодированием удалил - и в правду лишнее.
скажите а добавление в избранное для записей работает? как сделать есть инструкция? спасибо!
Для этого есть дополнение закладок - https://codeseller.ru/products/bookmarks-recall-polzovatelskie-zakladki-s-wp-recall/