Własna wtyczka dodająca widget do pluginu WPBakery
Własna wtyczka dodająca widget do pluginu WPBakery – brzmi trudno. W tym artykule dowiesz się jakie proste jest tworzenie własnych modułów do pluginu WPBakery. Jest to bardzo przydatna funkcjonalność, której nie posiada ten kreator stron. Pozwala ona na wstawienie dowolnego kodu poprzez Page Builder, umożliwiającego rozbudowanie naszej strony w dowolny sposób jaki potrzebujemy. Przykładem użycia może być dodanie widget’u wyświetlającego wpisy typu Custom Post Type np. Projekty w określony sposób, np. grid.
Własna wtyczka dodająca widget do pluginu WPBakery – w tym poradniku dowiesz się jak ją zrobić
Czego będziemy potrzebować do stworzenia wtyczki?
- Aktywnej wersji pluginu WPBakery Page Builder – WordPress Page Builder Plugin – jest to płatny plugin, pozwalający na tworzenie widoków stron metodą drag & drop. Jest to narzędzie ułatwiajace tworzenie stron internetowych w WordPress, które mocno przyspiesza pracę nad projektami.
- Znajomość języka PHP oraz tworzenia kodu w podejściu obiektowym – nasz plugin będziemy tworzyć w podejściu obiektowym za pomocą języka PHP i bez wiedzy w tych tematach ciężko będzie zrozumieć kod stworzony w tym poradniku. Polecam zapoznanie się z poradnikami: PHP zorientowane obiektowo dla początkujących oraz Pierwsze kroki w tworzeniu wtyczek WordPress.
- Cierpliwości i skupienia podczas tworzenia wtyczki 🙂
Zaczynajmy tworzenie wtyczki dodającej widget do WPBakery!
Pierwszym krokiem będzie stworzenie folderu naszego pluginu, który nazwiemy: REDO JSComposer Additional. Plugin należy umieścić w folderze, w którym znajdują się wszystkie nasze pluginy, czyli należy znaleźć folder: Plugins, a w nim stworzyć nasz folder, w którym będzie znajdował się plugin. Nazwa folderu nie może zawierać dużych oraz małych liter oraz spacji i znaków specjalnych, więc folder nazywamy odpowiednio redo-jscomposer-additional.
Teraz musimy stworzyć strukturę naszego pluginu, która wyglądać będzie w następujący sposób:
W naszym folderze głównym pluginu, tworzymy foldery:
- images – folder w, którym będziemy przechowywać nasze ikony używane w pluginie,
- widgets – folder, zawierający widget’y do wyświetlenia za pomocą pluginu,
oraz pliki:
- index.php – plik definiujący plugin (nazwa pluginu, autor itd) oraz inicjujący nasz plik główny main.php,
- main.php – plik główny naszego pluginu.
Najpierw przejdźmy do edycji index.php.
Pierwszym krokiem jest zabezpieczenie kodu przed bezpośrednim dostępem do plików za pomocą ABSPATH, która jest stałą definiowaną w WordPress, zabezpieczającą dostęp do plików .php.
Następnie w bloku komentarza umieszczamy opis naszego pluginu:
- Plugin Name – tutaj należy nadać nazwę naszego pluginu, która później będzie widoczna we wtyczkach w panelu WordPress,
- Description – opis naszego pluginu,
- Author– nazwa autora,
- Author URI– URL przekierowujący do strony autora,
- Version– wersja pluginu,
- License– określ licencję, aby plugin był dostępny dla wszystkich użytkowników we wtyczkach WordPress’a.
Wszystkie pola są opcjonalne, za wyjątkiem Plugin Name, który jest polem obowiązkowym.
Następnie za pomocą funkcji require_once()dodajemy ścieżkę do pliku głównego pluginu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } /* Plugin Name: REDO JSComposer Addditional Description: REDO JSComposer Addditional gives you multi plugins all in one. It's very powerful for any theme. Plugin URI: https://redo-interactive.com Author: REDO Author URI: https://redo-interactive.com Version: 3.1 License: GPL2 */ require_once('main.php'); ?> |
Przechodzimy do stworzenia logiki naszej wtyczki za pomocą edycji pliku main.php. W tym pliku obsłużymy dodawanie widget’u do naszego pluginu WPBakery za pomocą klasy VC_REDO.
1 2 3 | <?php class VC_REDO { } ?> |
Pierwszym krokiem jest dodanie konstruktora do naszej klasy za pomocją funkcji __construct(). Konstruktor będzie przyjmował prywatną zmienną $file– jest to zmienna reprezentująca plik na, którym będziemy pracować. W konstruktorze używamy wbudowanych w Visual Composer hook’ów dzięki, którym możemy „zaczepić” nasze funkcje. Odpowiednio:
- vc_before_init– do tego hook’a dopisujemy naszą funkcję vc_redo_widgets(), która będzie odpowiadać za dołączenie pliku z naszym widget’em,
- wp_ajax_vc_save_data– tutaj dopiszemy naszą funkcję aktualizującą vc_redo_update(),
- init – przy inicjalizacji będziemy sprawdzać czy WPBakery jest zainstalowane za pomocą funkcji check_for_install().
1 2 3 4 5 6 7 8 9 10 11 | <?php class VC_REDO { private $file; function __construct($file) { $this->file = $file; add_action( 'vc_before_init', array($this, 'vc_redo_widgets' )); add_action( 'wp_ajax_vc_save_data', array($this, 'vc_redo_update' )); add_action( 'init', array( $this, 'check_for_install' ) ); } } ?> |
Po napisaniu funkcji konstruktora, przechodzimy do funkcji redo-init(), która pomoże aktywować nasz widget. W funckji dodajemy wbudowany w WordPress hook odpowiadający za aktywację pluginu – register_activation_hook(). Dołączamy do niego funkcję odpowiadającą za aktywację naszego widget’u – redo_activation().
1 2 3 | public function redo_init () { register_activation_hook( $this->file, array( $this, 'redo_activation' ) ); } |
Funkcja vc_redo_widgets(), która jest załączona w naszym konstruktorze zawiera metodę includezawierającą ścieżkę do naszego widgetu, który napiszemy później. Ścieżką będzie folder widgets zawierający nasz własny widget, narazie przyjmujemy nazwę widget’u nazwaWidgetu.php.
1 2 3 | function vc_redo_widgets() { include 'widgets/nazwaWidgetu.php'; } |
Kolejną funkcją jest vc_redo_update() – sprawdza ona czy jest ustawiona zmienna globalna $_REQUEST, która jest odpowiedzialna za ustawianie danych w tym przypadku w WPBakery. Czyli – jeśli wystąpi jakaś zmiana w formularzach WPBakery (np, zmiana checkbox’a) to wartość ta będzie się znajdować w zmiennej $_REQUEST. Idąc dalej – jeśli zmienna ta jest ustawiona ( isset() ) – zaktualizuj dane pluginu za pomocą update_option().
1 2 3 4 5 | function vc_redo_update() { if (isset($_REQUEST)) { update_option( 'vc_redo_update', $_REQUEST ); } } |
Kolejną funkcją podpiętą do hook’a – redo_init jest funkcja check_for_install(). Odpowiada ona za sprawdzanie czy wtyczki potrzebne do wyświetlenia naszego widoku końcowego są zainstalowane na naszym WordPress’ie. W naszym przypadku będą to wtyczki:
- WPBakery,
- CPT UI,
- Custom Field.
Sprawdza ona czy są zdefiniowaniowane zmienne WPB_VC_VERSION, ACF_VERSION, CPT VERSION. Są to zmienne globalne pluginów i można się do nich odwołać tylko jeśli plugin istnieje w naszym WordPress. Jeśli dana zmienna nie występuje wyświetlamy stosowny komunikat o tym, aby zainstalować plugin WPBakery. Aby wyświetlić dany komunikat dołączamy funkcję show_redo_warning(), która wyświetla odpowiedni div.
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 | function check_for_install() { if (!defined('CPT_VERSION') || !defined('ACF_VERSION') || !defined('WPB_VC_VERSION')) { add_action('admin_notices', array( $this,'show_redo_warning')); return; } } function show_redo_warning() { if (!defined('WPB_VC_VERSION')) { $link = "https://wpbakery.com/"; $plugin = "WPBakery Page Builder"; ?> <div class="notice notice-warning is-dismissible"> <p>Please install <a href="<?php echo $link; ?>"><?php echo $plugin; ?></a> to use REDO JSComposer Additional.</p> </div> <?php } if (!defined('CPT_VERSION')) { $link = "https://pl.wordpress.org/plugins/custom-post-type-ui/"; $plugin = "Custom Post Type UI"; ?> <div class="notice notice-warning is-dismissible"> <p>Please install <a href="<?php echo $link; ?>"><?php echo $plugin; ?></a> to use REDO JSComposer Additional.</p> </div> <?php } if (!defined('ACF_VERSION')) { $link = "https://pl.wordpress.org/plugins/advanced-custom-fields/"; $plugin = "Advanced Custom Fields"; ?> <div class="notice notice-warning is-dismissible"> <p>Please install <a href="<?php echo $link; ?>"><?php echo $plugin; ?></a> to use REDO JSComposer Additional.</p> </div> <?php } } |
Przejdźmy do aktywacji naszego pluginu – funkcja redo_activation(). Pierwszym krokiem jest sprawdzenie za pomocą funkcji WordPress get_option(), czy istnieje opcja vc_redo_update. Wartość ta będzie zawsze false przy aktywacji, ponieważ dopiero w momencie aktywacji zostanie ta opcja dodana do pluginu WPBakery. Za pomocą tablicy $vc_default_redo ustawiamy wartość dla naszego widgetu wartość: ‚on’. Następnie aktualizujemy naszą funkcję vc_redo_update dodając nasz widget.
1 2 3 4 5 6 7 | public function redo_activation () { if ( !get_option( 'vc_redo_update' ) ) { $vc_default_redo = array( 'nazwaWidgetu' => 'on' ); update_option( 'vc_redo_update', $vc_default_redo); } |
Tutaj znajduje się cały nasz kod pliku main.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 | <?php class VC_REDO { private $file; function __construct($file) { $this->file = $file; add_action( 'vc_before_init', array($this, 'vc_redo_widgets' )); add_action( 'wp_ajax_vc_save_data', array($this, 'vc_redo_update' )); add_action( 'redo_init', array( $this, 'check_for_install' ) ); } public function redo_init () { register_activation_hook( $this->file, array( $this, 'redo_activation' ) ); } function vc_redo_widgets() { include 'widgets/projekty.php'; } function vc_redo_update() { if (isset($_REQUEST)) { update_option( 'redo_activation', $_REQUEST ); } } function check_for_install(){ if ( ! defined( 'WPB_VC_VERSION' ) ) { add_action('admin_notices', array( $this, 'show_redo_warning' )); return; } } public function redo_activation () { if ( !get_option( 'vc_redo_update' ) ) { $vc_default_redo = array( 'projekty' => 'on' ); update_option( 'vc_redo_update', $vc_default_redo); } } function show_redo_warning(){ ?> <div class="redo-warning-container"> <p>Please install <a href="https://wpbakery.com/">WPBakery Page Builder</a> to use REDO JSComposer Additional.</p> </div> <?php } } ?> |
Musimy powrócić do pliku index.php, w którym należy dodać inicjację naszej klasy VC_REDO.
Tworzymy zmienną $redo_object, w której inicjujemy nową instancję klasy VC_REDO zawierającej stałą __FILE__przechowującą ścieżkę systemu plików do bieżącego pliku .php. Następnie odwołujemy się do metod publicznych klasy VC_REDO czyli redo_init() oraz redo_activation().
Nasz kod php pliku index.php wygląda teraz następująco:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } /* Plugin Name: REDO JSComposer Addditional Description: REDO JSComposer Addditional gives you multi plugins all in one. It's very powerful for any theme. Plugin URI: https://redo-interactive.com Author: REDO Author URI: https://redo-interactive.com Version: 3.1 License: GPL2 */ require_once('main.php'); $redo_object = new VC_REDO( __FILE__ ); $redo_object->redo_init(); $redo_object->redo_activation(); ?> |
Mamy skonfigurowany plugin pod wyświetlenie naszego widgetu poprzez WPBakery. Brakuje nam tylko jednego – widgetu. Przejdźmy do sedna artykułu czyli dodawania własnego widgetu do WPBakery.
W folderze widgets tworzymy plik .php z nazwą naszego widgetu. W naszym przypadku będzie to nazwa pliku projekty.php, który będzie odpowiedzialny za wyświetlenie wszystkich post’ów typu projekty, w konkretnym widoku HTML za pomocą WPBakery.
Pierwszym krokiem podobnie jak w pliku index.php zabezpieczamy dostęp do pliku z zewnątrz za pomocą ABSPATH.
1 2 3 | if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } |
Kolejnym działaniem jest stworzenie klasy dziedziczącej po klasie wbudowanej w plugin WPBakery – WPBakeryShortCode. Nasza klasa będzie się nazywać dziedzicząc nazwę klasy dziedziczonej, dodając nazwę pliku .php czyli: WPBakeryShortCode_projekty. Za pomocą extends oznaczamy dziedziczenie klasy WPBakeryShortCode.
1 | class WPBakeryShortCode_projekty extends WPBakeryShortCode { } |
W naszej klasie WPBakeryShortCode_projekty musimy zdefiniować funkcję content()odpowiedzialną za wczytanie danych oraz wyświetlenie ich w odpowiednim widoku.
1 | protected function content() { } |
Przejdźmy do pobrania tablicy post’ów typu projekty. Jeśli nie wiesz na czym polega tworzenie wpisów własnego typu oraz jak na nich operować w PHP odsyłam do naszego artykułu – Tworzymy widok (template) dla custom post w WordPress.
W parametrach podajemy:
- typ posta: ’projekty’,
- ile postów wyświetlić: ’-1′ – w ten sposób wyświetli wszystkie post’y,
- wyświetl według: ’date’ – projekty zostaną wyświetlone według daty utworzenia.
Skorzystamy z metody wbudowej WordPress WP_Query()za pomocą, której wyślemy zapytanie do bazy danych z parametrami przekazanymi w tablicy $args.
1 2 3 4 5 6 | $args = array( 'post_type' => 'projekty', 'posts_per_page' => -1, 'orderby' => 'date' ); $projekty = new WP_Query($args); |
Możemy przejść do stworzenia widoku wyświetlającego projekty.
Aby, poprawnie wyświetlić nasz kod html potrzebujemy funkcji wbudowanej WordPress – ob_start(), którą dodamy do naszej funkcji content(). Funkcja ta tworzy bufor, do którego zapisywane są dane wyjściowe. Aby zamknąć ten bufor wystarczy zwrócić w returnfunkcję czyszczącą bufor: ob_get_clean(). Pomiędzy tymi funkcjami dodajemy nasz blok kodu html odpowiedzialny za wyświetlanie projektów.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ob_start(); ?> <div class="projekty-container"> <h2 class="projekty-container-tytul">PROJEKTY</h2> <?php while ($projekty->have_posts()) : $projekty->the_post(); ?> <div class="projekt"> <h1 class="projekt-tytul"> a href="<?php echo get_permalink(); ?>"> <?php echo get_the_title() ?> </a> </h1> <?php echo get_the_post_thumbnail(get_the_ID(), 'thumbnail'); ?> </div> <?php endwhile; ?> </div> <?php return ob_get_clean(); |
Następnie przechodzimy do implementacji funkcji WPBakery vc_map(). Pełna dokumentacja funkcji znajduje się tutaj i możesz tu znaleźć więcej możliwości ustawień dla swojego widgetu, natomiast w tym artykule opisze podstawowe ustawienia do poprawnego wyświetlenia widgetu.
Odpowiednio ustawiamy parametry naszego widgetu:
- name: „Projekty” – nazwa główna wyświetlana w liście elementów WPBakery, „projekty” – slug naszej nazwy.
- base: „projekty” – jest to nazwa wykorzystywana później w shortcode WPBakery, czyli np. wpisując w base nazwę projekty, nasz shortcode w WPBakery będzie wyglądał następująco: [ projekty ],
- category: „REDO JSComposer Additional” – nazwa kategorii jest dowolna, w naszym przypadku nazwaliśmy kategorię nazwą naszego pluginu
- description: „Display projects” – krótki opis za co odpowiada nasz widget,
- icon: – tutaj dodajemy ikonę, która będzie reprezentowała nasz widget. Ikonę dodajemy do folderu icons i następnie podajemy ścieżkę za pomocą wbudowanej funkcji dostępu do ścieżki katalogu pluginu: plugin_dir_url(__FILE__) i łączymy ze ścieżką do folderu z ikonami: ‚../images/eye-icon.png‚.
1 2 3 4 5 6 7 | vc_map( array( "name" => __( 'Projekty', 'projekty' ), "base" => "projekty", "category" => __('REDO JSComposer Additional'), "description" => __('Display projects'), "icon" => plugin_dir_url( __FILE__ ).'../images/eye-icon.png' ) ); |
Całość kodu naszego pliku projekty.php wygląda następująco:
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 | <?php if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } class WPBakeryShortCode_projekty extends WPBakeryShortCode { protected function content() { $args = array( 'post_type' => 'projekty', 'posts_per_page' => -1, 'orderby' => 'date' ); $projekty = new WP_Query($args); ob_start(); ?> <!-- HTML DESIGN HERE --> <div class="projekty-container"> <h2 class="projekty-container-tytul">PROJEKTY</h2> <?php while ($projekty->have_posts()) : $projekty->the_post(); ?> <div class="projekt"> <h1 class="projekt-tytul"> <a href="<?php echo get_permalink(); ?>"> <?php echo get_the_title() ?> </a> </h1> <?php echo get_the_post_thumbnail(get_the_ID(), 'thumbnail'); ?> </div> <?php endwhile; ?> </div> <!-- HTML END DESIGN HERE --> <?php return ob_get_clean(); } } vc_map( array( "name" => __( 'Projekty', 'projekty' ), "base" => "projekty", "category" => __('REDO JSComposer Additional'), "description" => __('Display projects'), "icon" => plugin_dir_url( __FILE__ ).'../images/eye-icon.png' ) ); |
Gotowe! Otrzymaliśmy działający plugin, który będzie dodawał nasze widget’y do pluginu WPBakery.
Przejdźmy do aktywacji pluginu i dodania widgetu do strony.
Przejdź do zakładki Wtyczki w panelu WordPress. Znajdź nazwę naszej wtyczki REDO JSComposer Additional i ją aktywuj.
Po aktywacji wtyczki wybierz stronę na, której chcesz dodać widget Projekty. Za pomocą WPBakery Backend, dodaj element do widoku.
Wybierz z listy elementów swój widget i gotowe 🙂
Otrzymaliśmy widok wyświetlający projekty dodany z poziomu pluginu WPBakery.
Podsumowanie
Dzięki dodaniu własnego widgetu do pluginu WPBakery możemy w dowolnym miejscu na stronie dodać wyświetlanie wpisów Custom Post Type: projekty. W ten sposób możemy dodawać więcej widgetów do naszej wtyczki. Wystarczy stworzyć w folderze render analogicznie do pliku projekty.php kolejne pliki wyświetlające inną zawartość. Ponadto możemy rozbudować wyświetlanie o konkretne parametry, wybieranie typu postów i innych funkcjonalności.
Jest to bardzo przydatna funkcjonalność, która nie występuje w podstawowej wersji pluginu WPBakery. Pozwala na stworzenie strony za pomocą modułów dodawanych za pomocą naszego Page Builder’a, które mogą być dodawane w wielu miejscach, a jeśli zajdą jakieś zmiany wystarczy edytować jeden plik PHP.