Создание собственного виджета для Elementor — отличный способ расширить функциональность вашего сайта на WordPress и добавить уникальные элементы интерфейса. Особенно полезным бывает внедрение AJAX подгрузки данных — это позволяет загружать содержимое динамически, без обновления страницы, что улучшает пользовательский опыт и ускоряет работу сайта.
Почему использовать AJAX в Elementor виджетах
AJAX (Asynchronous JavaScript and XML) — технология, позволяющая обмениваться данными с сервером в фоне, не перезагружая страницу. В контексте Elementor это даёт следующие преимущества:
- Быстрая динамическая подгрузка контента.
- Снижение нагрузки на сервер и клиентскую сторону.
- Интерактивность без сложных решений.
Рассмотрим, как создать Elementor виджет с поддержкой AJAX, который, например, подгружает посты из определённой категории по кнопке «Показать ещё».
Регистрация кастомного виджета для Elementor
Для начала создадим базовый класс виджета. Все виджеты в Elementor наследуются от \Elementor\Widget_Base.
class Wpelementor_Widget_Ajax_Load extends \Elementor\Widget_Base {
public function get_name() {
return 'wpelementor_ajax_load';
}
public function get_title() {
return 'AJAX Load Posts';
}
public function get_icon() {
return 'eicon-post-list';
}
public function get_categories() {
return ['general'];
}
protected function _register_controls() {
$this->start_controls_section(
'content_section',
[
'label' => __('Настройки', 'wpelementor'),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'posts_per_page',
[
'label' => __('Постов на страницу', 'wpelementor'),
'type' => \Elementor\Controls_Manager::NUMBER,
'default' => 3,
'min' => 1,
'max' => 20,
]
);
$this->add_control(
'category',
[
'label' => __('Категория (slug)', 'wpelementor'),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => '',
'description' => __('Введите slug категории для фильтрации постов.', 'wpelementor'),
]
);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
$posts_per_page = $settings['posts_per_page'];
$category = sanitize_text_field($settings['category']);
echo '<div id="wpelementor-ajax-posts" data-category="' . esc_attr($category) . '" data-perpage="' . esc_attr($posts_per_page) . '" data-page="1">';
echo $this->wpelementor_render_posts($category, $posts_per_page, 1);
echo '</div>';
echo '<button id="wpelementor-load-more">Показать ещё</button>';
}
private function wpelementor_render_posts($category, $posts_per_page, $page) {
$args = [
'post_type' => 'post',
'posts_per_page' => $posts_per_page,
'paged' => $page,
];
if ($category) {
$args['category_name'] = $category;
}
$query = new WP_Query($args);
$output = '';
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$output .= '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
$output .= '<p>' . get_the_excerpt() . '</p>';
}
wp_reset_postdata();
} else {
$output .= '<p>Посты не найдены.</p>';
}
return $output;
}
}
// Регистрируем виджет
add_action('elementor/widgets/widgets_registered', function() {
\Elementor\Plugin::instance()->widgets_manager->register_widget_type(new Wpelementor_Widget_Ajax_Load());
});Добавление AJAX функционала: обработчик и скрипт
Чтобы кнопка «Показать ещё» работала без перезагрузки страницы, необходимо добавить AJAX обработчик на сервере и JavaScript на клиенте.
PHP: AJAX обработчик
Добавим функцию для AJAX, которая будет возвращать следующую страницу постов.
add_action('wp_ajax_wpelementor_load_more', 'wpelementor_load_more_callback');
add_action('wp_ajax_nopriv_wpelementor_load_more', 'wpelementor_load_more_callback');
function wpelementor_load_more_callback() {
$page = isset($_POST['page']) ? intval($_POST['page']) : 1;
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
$posts_per_page = isset($_POST['perpage']) ? intval($_POST['perpage']) : 3;
$args = [
'post_type' => 'post',
'posts_per_page' => $posts_per_page,
'paged' => $page,
];
if ($category) {
$args['category_name'] = $category;
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
echo '<p>' . get_the_excerpt() . '</p>';
}
wp_reset_postdata();
} else {
echo '<p>Посты не найдены.</p>';
}
wp_die();
}
JavaScript: скрипт для кнопки
Подключим JS, который будет отправлять AJAX запрос и подгружать посты на страницу.
function wpelementor_enqueue_scripts() {
wp_enqueue_script('wpelementor-ajax-load', get_template_directory_uri() . '/js/wpelementor-ajax-load.js', ['jquery'], null, true);
wp_localize_script('wpelementor-ajax-load', 'wpelementor_ajax', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpelementor_nonce'),
]);
}
add_action('wp_enqueue_scripts', 'wpelementor_enqueue_scripts');Создайте файл js/wpelementor-ajax-load.js в вашей теме или плагине с таким содержанием:
jQuery(document).ready(function($) {
$('#wpelementor-load-more').on('click', function() {
var container = $('#wpelementor-ajax-posts');
var page = parseInt(container.data('page')) + 1;
var category = container.data('category');
var perpage = container.data('perpage');
$.ajax({
url: wpelementor_ajax.ajax_url,
type: 'POST',
data: {
action: 'wpelementor_load_more',
page: page,
category: category,
perpage: perpage,
_ajax_nonce: wpelementor_ajax.nonce
},
beforeSend: function() {
$('#wpelementor-load-more').text('Загрузка...');
},
success: function(response) {
if (response.trim() === '<p>Посты не найдены.</p>') {
$('#wpelementor-load-more').text('Больше постов нет').prop('disabled', true);
} else {
container.append(response);
container.data('page', page);
$('#wpelementor-load-more').text('Показать ещё');
}
},
error: function() {
$('#wpelementor-load-more').text('Ошибка загрузки');
}
});
});
});Оптимизация и рекомендации
Чтобы виджет работал корректно и не создавал нагрузку, стоит учесть несколько моментов:
- Безопасность: добавьте проверку nonce для AJAX запросов.
- Кэширование: если данные редко меняются, можно кешировать вывод на стороне сервера.
- Универсальность: расширьте виджет дополнительными настройками — сортировка, типы постов, фильтры.
- Интеграция с WPShop: если вы используете плагины из WPShop, можно добавить интеграцию с WPRemark для отзывов или Quizle для викторин внутри виджета.
Заключение
Создание кастомного виджета Elementor с AJAX подгрузкой — мощный инструмент для улучшения UX и расширения возможностей сайта на WordPress. В статье показан базовый пример, который легко можно адаптировать под свои задачи и дополнить функционалом. Такой подход позволяет создавать современные, динамичные страницы без излишних нагрузок и сложностей.