Wordpress модифицируем виджет бегущей строки и добавляем AJAX
В прошлый раз мы создали виджет бегущей строки курсов криптовалют. Но он мог выводить только популярные валюты, а что если мы хотим вывести какие-то определенные курсы? Давайте же доработаем наш виджет и добавим ему такую возможность!
Изначально мы использовали API метод https://api.coinmarketcap.com/v1/ticker/, который возвращает список всех криптовалют, отсортированных по популярности. Искать в нем нужную валюту не целесообразно и, к сожалению, в API отсутствуют какие-либо методы, которые давали бы данные по списку из интересующих нас криптовалют. Поэтому мы будем использовать метод https://api.coinmarketcap.com/v1/ticker/{currency}/. Он выдаст нам всю необходимую информацию о каждой валюте отдельно.
Итак, мы разобрались каким образом будем получать необходимые данные, теперь модифицируем наш виджет. Начнем с функции form, нам необходимо добавить радио-группу, с помощью которой можно было бы переключаться на список из валют или на популярные валюты, а также добавим ещё одно поле ввода для этого самого списка. Теперь метод будет выглядеть следующим образом:
function form( $instance ) {
$defaults = array (
'currenciesLimit' => 10,
'type' => 'popular', // <-- новая опция
'list' => 'bitcoin,Ethereum' // <-- новая опция
);
$instance = wp_parse_args((array)$instance, $defaults);
?>
<p>
Вывод: <br/>
<label><input id="<?php echo $this->get_field_id( 'type' ); ?>" name="<?php echo $this->get_field_name( 'type' ); ?>" value="popular" type="radio" <?php checked( $instance['type'], 'popular', true ); ?> /> Популярные криптовалюты </label> <br/>
<label><input id="<?php echo $this->get_field_id( 'type' ); ?>" name="<?php echo $this->get_field_name( 'type' ); ?>" value="list" type="radio" <?php checked( $instance['type'], 'list', true ); ?>/> Список из криптовалют </label>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'currenciesLimit' ); ?>"> Выводить <input id="<?php echo $this->get_field_id( 'currenciesLimit' ); ?>" name="<?php echo $this->get_field_name( 'currenciesLimit' ); ?>" value="<?php echo $instance['currenciesLimit']; ?>" style="width:50px;" type="number"/> популярных криптовалют</label>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'list' ); ?>"> Список криптовалют</label>
<input id="<?php echo $this->get_field_id( 'list' ); ?>" name="<?php echo $this->get_field_name( 'list' ); ?>" value="<?php echo $instance['list']; ?>" type="text"/>
</p>
<?
}
Как вы могли заметить, появились две новые опции type и list, думаю и так понятно за что они отвечают. Теперь изменим метод сохранения настроек, за это у нас отвечает update :
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['currenciesLimit'] = strip_tags( $new_instance['currenciesLimit'] );
$instance['type'] = strip_tags( $new_instance['type'] );
$instance['list'] = strip_tags( $new_instance['list'] );
return $instance;
}
Здесь ничего сложного нет, мы просто добавили сохранение ещё двух опций. Следующим у нас идет метод widget, где и происходит основная работа.
function widget( $args, $instance ){
$currencies = array();
switch ($instance['type']) {
case 'popular':
{
$res = file_get_contents('https://api.coinmarketcap.com/v1/ticker/?convert=RUB&limit='.$instance['currenciesLimit']);
$currencies = json_decode($res,true);
}
break;
case 'list':
{
$list = explode(',',$instance['list']);
$currencies = array();
for ($i=0;$i<count($list);$i++) {
$res = file_get_contents('https://api.coinmarketcap.com/v1/ticker/'.str_replace(' ','-',$list[$i]).'/?convert=RUB');
$res = json_decode($res,true);
$currencies[] = $res[0];
}
}
break;
}
?>
<marquee scrollamount="3" behavior="scroll" loop="infinite" direction="left">
<?
foreach ($currencies as $key => $currency) {
?>
<span><strong><? echo $currency['name'].' ('.$currency['symbol'].')'; ?></strong> : <? echo number_format($currency['price_rub'], 2, '.', ' ').' руб.';?> </span>
<?
}
?>
</marquee>
<?
}
Была добавлена конструкция switch, которая позволяет выполнять различный код в зависимости от значения опции type. В "list" сначала мы должны превратить список в массив, для этого используется функция php explode(), первый параметр это разделитель, а второй непосредственно сама строка. Важно! между словами должны быть лишь запятые, никаких пробелов и лишних знаков, иначе функция добавит это все к нашим словам и API будет возвращать ошибку. Вы могли заметить, что в запрос мы подставляем не просто элемент массива, а конструкцию str_replace(' ','-',$list[$i]) - функция, которая меняет в строке пробелы на знак тире. Это нужно, потому как API принимает названия валют таких как Bitcoin cash или Ethereum Classic только со знаком "-" между словами. Дальнейший код аналогичен коду из секции "popular", за исключением того, что он обрамлен в цикл.
И вот наш модифицированный виджет готов, но где же AJAX спросите вы? Дело в том, что если сделать список из 5+ криптовалют, то продолжительность загрузки веб-страницы значительно увеличиться. Чтобы этого избежать нам и пригодится AJAX. Сначала ajax-запрос необходимо зарегистрировать в Wordpress, делается это одной из следующих функций:
add_action('wp_ajax_(action)', 'my_action_callback'); - эту функция регистрирует ajax-действие для админ-панели. Первый аргумент - название действия, где вместо (action) - имя вашего запроса. Второй параметр - функция, которая будет обрабатывать запрос.
add_action('wp_ajax_(action)', 'my_action_callback'); - для авторизованных пользователей.
add_action('wp_ajax_nopriv_(action)', 'my_action_callback'); - для неавторизованных пользователей.
Функции выше предназначены для создания действий на самом сайте, параметры обеих аналогичны параметрам функции для админ-панели.
Добавим в конструктор виджета следующие строки:
add_action('wp_ajax_getCurrencies', array($this,'my_action_callback'));
add_action('wp_ajax_nopriv_getCurrencies', array($this,'my_action_callback'));
Имя функции указано следующим образом array($this,'my_action_callback'), поскольку она будет являться методом класса виджета.
Теперь создадим сам метод и скопируем в него весь код из widget
function my_action_callback(){
$currencies = array();
switch ($_POST['type']) {
case 'popular':
{
$res = file_get_contents('https://api.coinmarketcap.com/v1/ticker/?convert=RUB&limit='.$_POST['currenciesLimit']);
$currencies = json_decode($res,true);
}
break;
case 'list':
{
$list = explode(',',$_POST['list']);
$currencies = array();
for ($i=0;$i<count($list);$i++) {
$res = file_get_contents('https://api.coinmarketcap.com/v1/ticker/'.str_replace(' ','-',$list[$i]).'/?convert=RUB');
$res = json_decode($res,true);
$currencies[] = $res[0];
}
}
break;
}
?>
<marquee scrollamount="3" behavior="scroll" loop="infinite" direction="left">
<?
foreach ($currencies as $key => $currency) {
?>
<span><strong><? echo $currency['name'].' ('.$currency['symbol'].')'; ?></strong> : <? echo number_format($currency['price_rub'], 2, '.', ' ').' руб.';?> </span>
<?
}
?>
</marquee>
<?
wp_die();
}
К сожалению, в данном методе нам не доступна переменная $instance, поэтому мы заменим её везде на $_POST, в которой будут хранится все значения, передаваемые POST параметрами в запросе. Также в конце функции необходимо написать wp_die();, чтобы Wordpress не возвращал ничего лишнего.
Теперь возвращаемся к методу widget и пишем в нем скрипт, который будет запрашивать данные:
function widget( $args, $instance ){
?>
<div id="marqueeCurrency" style="text-align:center;"> загрузка...</div>
<script type="text/javascript" >
jQuery(document).ready(function($) {
var data = {
action: 'getCurrencies',
currenciesLimit: <? echo $instance['currenciesLimit']?>,
type: '<? echo $instance['type']?>',
list: '<? echo $instance['list']?>',
};
jQuery.post( '<?echo admin_url('admin-ajax.php');?>', data, function(response) {
document.getElementById('marqueeCurrency').innerHTML = response;
});
});
</script>
<?
}
Самым важным параметром запроса является action - действие, которое необходимо выполнить. Также в POST параметрах мы передали все необходимые данные. Выполнением запроса будет являться html конструкция, которую мы вставим в блок div.
Таким образом теперь страница будет гораздо быстрее загружаться, поскольку не ждет пока отработает скрипт виджета.
Скачать исходный код виджета
Заглавное фото с сайта pvsm.ru
Данный материал подготовлен автором @mo3golom в рамках цикла статей о WordPress.