Jak stworzyć filtr wczytujący custom post za pomocą AJAX w WordPress?
W tym artykule pokażemy jak w łatwy i szybki sposób wczytać custom posts za pomocą AJAX w WordPress.
Zadaniem będzie stworzenie filtru do typów projektów, który pozwoli nam na wczytanie listy projektów z wybranym typem.
WordPress – jak stworzyć filtr AJAX?
Co musisz wiedzieć
- Przede wszystkim musisz znać page builder’a WPBakery na której opieramy budowę stron internetowych. We wcześniejszych naszych poradnikach znajdziesz całą wiedzę potrzebną do zrozumienia procesu tworzenia widget’ów do WPBakery.
Link do artykułu: REDO JSComposer Additional – plugin dodający widget do WPBakery
Link do pluginu WPBakery: https://wpbakery.com/ - Jeśli nie znasz WPBakery potrzebna będzie znajomość innego page builder’a – Elementor. Jest to jedna z najbardziej znanych wtyczek do tworzenia stron internetowych w systemie WordPress. Aby dobrze zrozumieć sposób działania naszej wtyczki do tworzenia widgetów dla Elementora – zapoznaj się z artykułem: Elementor – jak stworzyć własny plugin dodający custom post
Link do pluginu Elementor: https://elementor.com/ - Jeśli temat AJAX’a w WordPress’ie jest Ci obcy – przeczytaj ten artykuł i spróbuj samodzielnie zrobić przykład z artykułu: AJAX w WordPress – kompletny przewodnik
- Bazujemy na podstawowych umiejętnościach programowania języka PHP, oraz na umiejętności tworzenia kodu HTML i CSS. Jeśli przeczytałeś nasze poprzednie poradniki to stworzenie slider’a nie powinno być trudne.
Link do listy poprzednich artykułów: Artykuły.
Tworzymy strukturę do wczytania listy AJAX
Zaczniemy od stworzenia struktury html, do której wczytamy listę custom posts. Wykorzystamy do tego WPBakery Page Builder.
Skorzystamy z gotowego już custom post type „Projekty” i stworzymy funkcję AJAX, która będzie wczytywać listę projektów danego typu. Typ projektu będzie przechowywany w taxonomy „Typ projektu”. Jeśli nie wiesz jak dodać taxonomy dla custom post type odsyłam do artykułu: How to add custom taxonomy (Custom Post Type UI)
W docelowej stronie, na której ma być wyświetlana lista projektów tworzymy strukturę:
- Filter-container
- Types-container
- Projects-container
Docelowo do Types-container wczytamy za pomocą AJAX listę typów projektów z domyślnym ustawieniem na wyświetlanie wszystkich projektów w Projects-container. Po kliknięciu na dany typ projektu lista projektów zostanie „przefiltrowana” i wyświetli tylko projekty danego typu.
W WPBakery struktura powinna wyglądać w ten sposób:
Skrypt AJAX wczytujący custom posts WordPress
Tworzymy skrypt AJAX przy pomocy jQuery w motywie WordPress
Przechodzimy do stworzenia skryptu JS. W folderze naszego motywu wyszukujemy folder js i w nim tworzymy plik .js, w którym umieścimy nasz skrypt. W naszym przypadku będzie to redo-script.js
Do poprawnego działania skryptu potrzebna będzie bioblioteka jQuery – upewnij się, że Twój motyw ją posiada.
Główną funkcją, która umożliwia nam korzystanie z AJAX jest funkcja: $.post(), która wysyła do serwera dane używając HTTP POST Request. Wewnątrz należy umieścić url, który zawiera admin-ajax.php (w WordPress to ten plik jest odpowiedzialny za przesył danych za pomocą ajax). Poprawny url umieścimy w zmiennej $ajaxurl i prześlemy ją odpowiednio późniejszej części w functions.php.
1 2 3 4 | $.post( ajaxurl,{}, function( response ) {} ); |
Następnie musimy podać z jakiego skryptu php chcemy skorzystać, aby pobrać listę projektów. Skrypt ten będziemy tworzyć w pliku functions.php naszego motywu – nazwiemy go: get_projects(). Dodatkowo musimy podać jaki typ projektu chcemy pobrać. Skoro to początkowy skrypt wczytujący listę projektów, chcemy pobrać wszystkie typy projektów. Zmienną przechowującą typ projektu nazwiemy $projectType.
1 2 3 4 5 6 7 8 | $.post( ajaxurl, { 'action' : 'get_projects', 'projectType' : 'wszystkie' }, function( response ) {} ); |
Gdy wykonaliśmy nasz skrypt po stronie serwera otrzymaliśmy odpowiedź, która jest w formacie JSON. Odpowiedź musimy odpowiednio przekonwertować za pomocą wbudowanej funkcji parseJSON() i następnie włożyć do odpowiednich kontenerów na naszej stronie. Wstawiamy nasze projekty do wcześniej stworzonego kontenera – projects-container.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | (function($){ $(document).ready(function(){ $.post( ajaxurl, { 'action' : 'get_projects', 'projectType' : 'wszystkie' }, function( response ) { $data=$.parseJSON(response); $('.projects-container').html($data[0]); } ); }); })(jQuery); |
Należałoby jeszcze obsłużyć wybór typu projektu. Zakładamy, że każdy typ projektu będzie miał klasę .project-type, a typ projektu, który będzie aktualnie wybrany będzie posiadał dodatkowo klasę .type-active. Typy projektów będą znajdować się w kontenerze .types-container. Po kliknięciu na dany typ projektu sprawdzamy gdzie w naszym kontenerze znajduje się klasa .type-active i usuwamy ją z poprzedniej lokacji, a następnie dodajemy ją do nowej.
1 2 3 4 | $(document).on('click', ".project-type" ,function(){ $('.projects-types').find('.type-active').removeClass('type-active'); $(this).addClass('type-active'); }); |
Po dodaniu aktywnej klasy dla naszego aktualnego typu projektu, należy za pomocą $.post() pobrać aktualny typ projektu. Odpowiedź parsujemy z JSON’a i następnie „wkładamy” do naszego kontenera na projekty.
1 2 3 4 5 6 7 8 9 10 11 | $.post( ajaxurl, { 'action' : 'get_projects', 'projectType' : $(this).data("projectType") }, function( response ) { $data=$.parseJSON(response); $('.projects-container').html($data[0]); } ); |
Całość naszego skryptu redo-script.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | (function($){ $(document).ready(function() { $.post( ajaxurl, { 'action' : 'get_projects', 'projectType' : 'wszystkie' }, function( response ) { $data=$.parseJSON(response); $('.projects-container').html($data[0]); $('.projects-types').html($data[1]); } ); $(document).on('click', ".project-type" ,function(){ $('.projects-types').find('.type-active').removeClass('type-active'); $(this).addClass('type-active'); $.post( ajaxurl, { 'action' : 'get_projects', 'projectType' : $(this).data("projectType") }, function( response ) { $data=$.parseJSON(response); $('.projects-container').html($data[0]); } ); }); }); })(jQuery); |
Skrypt po stronie serwera – jak obsłużyć AJAX w WordPress
Obsługę funkcji AJAX programujemy w pliku functions.php. Pierwszym krokiem jest zarejestrowanie naszego skryptu JS – redo-script.js, oraz ustalenie ajaxurl. Stworzymy więc funkcję add_js_scripts_redo() w której dodamy nasz skrypt oraz ustalimy ajaxurl.
1 2 3 4 5 6 7 8 9 10 11 12 | function add_js_scripts_redo() { wp_enqueue_script( 'redoscript', get_template_directory_uri().'/js/redo-script.js', array('jquery'), 1, 1, 1 ); if ( isset($_SERVER['HTTPS']) ) $protocol = 'https://'; else $protocol = 'http://'; // pass Ajax Url to script.js wp_localize_script('redoscript', 'ajaxurl' , admin_url( 'admin-ajax.php', $protocol ) ); } add_action('wp_enqueue_scripts', 'add_js_scripts_redo'); |
Teraz należy stworzyć funkcję, którą definiowaliśmy w skrypcie JS – get_projects().
Pierwszym krokiem w get_projects() jest pobranie parametru $projectType, który został wysłany przez $.post().
1 2 3 | function get_projects() { $param = $_POST['projectType']; } |
Teraz przechodzimy do sprawdzenia parametru. Jeśli zmienna $param == 'wszystkie’ – wówczas pobieramy całą listę projektów niezależnie od typu projektu. Jeśli nie to sprawdzamy typ projektu, który zawiera wysłany projectType. Zakładamy, że wysyłany projectType będzie zawierał ID typu projektu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | function get_projects() { $param = $_POST['projectType']; if($param == 'wszystkie') { $projectsQuery = new WP_Query(array( 'post_type' => 'projekty', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC' )); } else { $projectsQuery = new WP_Query(array( 'post_type' => 'projekty', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'tax_query' => array( array( 'taxonomy' => 'typ_projektu', 'field' => 'ID', 'terms' => $param, ) ), )); } } |
Musimy także przygotować strukturę, którą będziemy wysyłać za pomocą JSON.
Mamy już listę projektów zależną od wysłanego przez $.post() typu projektu, którą przechowujemy w tablicy $projectsQuery. Brakuje nam listy typów projektów, którą byśmy wczytali do naszego kontenera – types-container. Pobieramy ją za pomocą funkcji PHP dostępnej w WordPress – WP_Term_Query(), która pobierze nam listę taxonomy o danym slug’u.
1 2 3 4 5 | $projectsTypeQuery = new WP_Term_Query( array( 'taxonomy' => 'typ_projektu', 'hide_empty' => false, 'order' => 'DESC', ) ); |
Aby móc pracować na pobranych listach $projectsQuery i $projectsTypeQuery musimy wybrać z nich to co nas interesuje czyli posty i taxonomies. Przypisujemy je do odpowiednich zmiennych.
1 2 | $projekty=($projectsQuery->posts); $typyProjektow=($projectsTypeQuery->terms); |
Przygotowujemy puste tablice, które końcowo wyślemy za pomocą AJAX oraz funkcji json_encode(), która zakoduje nam nasze dane w kod JSON. Pierwsza tablica będzie przechowywać html projektów i nazwiemy ją $projektyString. Kolejna będzie przechowywać listę typów projektów – $typyString. Ostatnia tablica będzie przechowywać nasz kod JSON i zostanie wysłana za pomocą funkcji echo – nazwiemy ją $contents.
1 2 3 | $projektyString = []; $typyString = []; $contents = []; |
Zaczniemy od wczytania listy projektów do $projektyString[]. Pojedynczy projekt będzie wyświetlony w znaczniku <a> z klasą .project-card. Będzie zawierał link do projektu oraz obraz projektu. Każdy projekt wczytany będzie za pomocą pętli foreach.
1 2 3 | foreach($projekty as $projekt) { $projektyString[] = '<a class="project-card" href="'. get_permalink($projekt->ID) .'"><img src="'.get_the_post_thumbnail_url($projekt->ID).'"/></a>'; } |
Mamy gotową listę projektów do wysłania. Teraz musimy stworzyć listę typów projektów. Nasze taxonomies zawiera odpowiednie nazwy typów projektów, które później wyświetlimy w kontenerze .types-container, natomiast co jeśli chcemy wyświetlić wszystkie projekty? Jakiś typ projektu musi za to odpowiadać. Początkowa wartość wysyłana w projectType, po wczytaniu skryptu wysyła nam projectType==’wszystkie’. Musimy więc dodać do $typyString[] typ projektu odpowiedzialny za wszystkie projekty, następnie wczytujemy standardowo za pomocą pętli foreach pozostałe typy projektów. Typ projektu będzie wyświetlany w znaczniku <a> będzie zawierał wcześniej ustalone klasy: .project-type oraz klasę .type-active, która początkowo będzie przypisana do typu projeku – wszystkie. Każdy typ projektu musi zawierać atrybut data-project-type, który będzie przechowywał ID typu projektu, a w przypadku wszystkich projektów będzie przechowywał string – „wszystkie”. W znaczniku wyświetlimy nazwę typu projektu.
1 2 3 4 | $typyString[] = '<a class="project-type type-active" data-project-type="wszystkie">Wszystkie</a>'; foreach($typyProjektow as $typ) { $typyString[] = '<a class="project-type" data-project-type="'.$typ->term_id.'">'.$typ->name.'</a>'; } |
Na koniec nasze tablice dodajemy do pustej tablicy $contents i kodujemy za pomocą json_encode(). Wysyłamy za pomocą echo i uśmiercamy funkcję get_projects() za pomocą funkcji die().
1 2 3 | $contents = json_encode([ $projektyString, $typyString ]); echo $contents; die(); |
Należy jeszcze, aby funkcja korzystała z AJAX należy dodać dwie akcje, z przedrostkami wp_ajax oraz wp_ajax_nopriv – są to hook’i w WordPress, które umożliwiają nam stworzenie własnych żądań AJAX, po których podajemy nazwę akcji, która będzie z nich korzystać. Hook wp_ajax – dla zalogowanych użytkowników, wp_ajax_nopriv – dla niezalogowanych. W naszym przypadku jest to obojętne czy użytkownik będzie zalogowany (każdy może wyświetlić listę projektów).
1 2 | add_action( 'wp_ajax_get_projects', 'get_projects' ); add_action( 'wp_ajax_nopriv_get_projects', 'get_projects' ); |
Całość kodu zawartego w functions.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | function add_js_scripts_redo() { wp_enqueue_script( 'redoscript', get_template_directory_uri().'/js/redo-script.js', array('jquery'), 1, 1, 1 ); if ( isset($_SERVER['HTTPS']) ) $protocol = 'https://'; else $protocol = 'http://'; // pass Ajax Url to script.js wp_localize_script('redoscript', 'ajaxurl' , admin_url( 'admin-ajax.php', $protocol ) ); } add_action('wp_enqueue_scripts', 'add_js_scripts_redo'); add_action( 'wp_ajax_get_projects', 'get_projects' ); add_action( 'wp_ajax_nopriv_get_projects', 'get_projects' ); function get_projects() { $param = $_POST['projectType']; if($param == 'wszystkie') { $projectsQuery = new WP_Query(array( 'post_type' => 'projekty', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC' )); } else { $projectsQuery = new WP_Query(array( 'post_type' => 'projekty', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'tax_query' => array( array( 'taxonomy' => 'typ_projektu', 'field' => 'ID', 'terms' => $param, ) ), )); } $projectsTypeQuery = new WP_Term_Query( array( 'taxonomy' => 'typ_projektu', 'hide_empty' => false, 'order' => 'DESC', ) ); $projekty=($projectsQuery->posts); $typyProjektow=($projectsTypeQuery->terms); $projektyString = []; $typyString = []; $contents = []; foreach($projekty as $projekt) { $projektyString[] = '<a class="project-card" href="'. get_permalink($projekt->ID) .'"><img src="'.get_the_post_thumbnail_url($projekt->ID).'"/></a>'; } $typyString[] = '<a class="project-type type-active" data-project-type="wszystkie">Wszystkie</a>'; foreach($typyProjektow as $typ) { $typyString[] = '<a class="project-type" data-project-type="'.$typ->term_id.'">'.$typ->name.'</a>'; } $contents = json_encode([ $projektyString, $typyString ]); echo $contents; die(); } |
Gotowe! Działający skrypt AJAX filtrujący posty
Otrzymaliśmy działający skrypt, który wczytuje nam posty wybranego typu przy pomocy AJAX w WordPress. Do wcześniej stworzonych kontenerów skrypt dodaje typy projektów oraz projekty danego typu. Po kliknięciu na dany typ zostaje wysłane zapytanie do serwera, który zwraca nam odpowiednio przefiltrowane projekty.
Podsumowanie
W tym poradniku pokazaliśmy w jaki sposób dodać prosty skrypt AJAX filtrujący custom posts w WordPress. Dodawanie skryptów AJAX w WordPress nie jest trudne, natomiast trzeba znać kilka podstawowych funkcji WordPress, które przedstawiliśmy w tym artykule.
Jeśli chcesz się dowiedzieć więcej na temat WordPress’a czy page builder’ów takich jak WPBakery lub Elementor – zapraszam na listę artykułów: Przydatne artykuły.