0

Piszemy własną wtyczkę do WordPressa, czyli jak stworzyć niezawodny plugin.

WordPress - piszemy własną wtyczkę

Parę dni temu na naszej stronie zdarzyło się nieszczęście: po zaktualizowaniu WordPressa do najnowszej wersji jedna z wtyczek, której zadaniem było wyświetlanie okienek popup, odmówiła posłuszeństwa. I to jeszcze w taki sposób, że dawała o sobie znać tylko niezalogowanym użytkownikom, a co gorsza powodując wewnętrzny błąd serwera (HTTP 500), czyli kompletnie uniemożliwiając korzystanie ze strony. Nie było to zbyt miłe przeżycie, szczególnie, że dla zalogowanego użytkownika (admina) strona działała w porządku. Jak zapobiec takim sytuacjom? Można chociażby napisać własną wtyczkę!

Niniejszy artykuł ma na celu napisanie jak najprostszej wersji wtyczki, która będzie wyświetlała okienko popup. Bardziej rozbudowana wersja wtyczki będzie dostępna na serwerze WordPressa pod nazwą „Easy Free Popup”.

To, co wtyczka koniecznie musi mieć

Przechodząc do konkretów – jak stworzyć swoją własną wtyczkę? Najpierw tworzymy nowy katalog w folderze z pluginami do WordPressa. Nazwa nie powinna zawierać m.in. spacji.

WordPress struktura katalogów (drzewo katalogów) do naszej wtyczki

WordPress struktura katalogów (drzewo katalogów) do naszej wtyczki

Wskazany folder (easy-free-popup) będzie od teraz naszym głównym katalogiem i to w nim będziemy dokonywać wszystkich czynności. Utwórzmy w nim zatem nasz pierwszy plik. Musi on się nazywać tak samo jak folder i mieć rozszerzenie .php. W naszym przypadku tworzymy plik easy-free-popup.php Jego zawartość niech będzie następująca:

<?php
/*
  Plugin Name: Easy Free Popup
  Version: 0.1
  Description: Basic popup with social media
  Author: Józef Curyłło
  Author URI: http://szalonypecet.pl
 */

Prawdę mówiąc to właśnie jest minimalna zawartość wtyczki, jakiej oczekuje WordPress. Jak widać parsuje on też komentarze i pobiera z nich informacje o naszym pluginie. Już teraz możemy przejść do naszego panelu administracyjnego (do opcji „Wtyczki”) i zobaczyć taki oto wpis:

WordPress - widok najprostszego pluginu w panelu administracyjnym

WordPress – widok najprostszego pluginu w panelu administracyjnym

Niech ta wtyczka cokolwiek robi

Nasza wtyczka w tym momencie już istnieje, ale kompletnie nic nie robi. Pora więc dodać do naszego głównego pliku PHP cokolwiek innego niż komentarz. Zmieńmy więc jego zawartość na poniższą.

<?php
/*
  Plugin Name: Easy Free Popup
  Version: 0.1
  Description: Basic popup with social media
  Author: Józef Curyłło
  Author URI: http://szalonypecet.pl
 */

/*
  Ładujemy HTML
*/
function efp_html(){
  echo "<h1>To jest moja pierwsza wtyczka!</h1>";
}
add_action('wp_footer', 'efp_html');

Dodaliśmy tutaj naszą własną funkcję o nazwie efp_html, która wyświetla jeden paragraf tekstu. Będzie ona wywołana w pobliżu tagu </body>, a wynika to z zapisu  add_action('wp_footer', 'efp_html'); , który określa, że podczas akcji wp_footer (czyli bezpośrednio przez zamykającym tagiem body) chcemy wywołać wskazaną przez nas funkcję efp_html. Do wyboru mamy całkiem sporo akcji, chociaż w tym momencie ta będzie dla nas najważniejsza. Podobne konstrukcje są powszechne w WordPress – często będziemy podpinać się pod różne akcje podając jako jeden z parametrów nazwę funkcji. Skąd wiedzieć jakich akcji używać? Trzeba tego po prostu szukać na stronach WordPressa, chociaż po pewnym czasie można je zapamiętać, co znacznie przyspiesza pracę.

Jeśli teraz uruchomimy naszą wtyczkę w panelu administracyjnym (jeśli jeszcze tego nie zrobiliśmy) i odświeżymy stronę główną to na samym dole strony powinniśmy zobaczyć nasz tekst: „To jest moja pierwsza wtyczka!”.

Dodanie stylów i skryptów

Możliwość pisania na wyjście jest bardzo przydatna, ale jednak przydałaby się też co najmniej możliwość używania skryptów języka JavaScript i stylów CSS. Dodajmy więc odpowiednie funkcje do naszego pliku, który teraz powinien wyglądać tak:

<?php
/*
  Plugin Name: Easy Free Popup
  Version: 0.1
  Description: Basic popup with social media
  Author: Józef Curyłło
  Author URI: http://szalonypecet.pl
 */

/*
  Ładujemy dodatkowe (wymagane przez nas) style - w tym przypadku Font Awesome
*/
function efp_enqueue_required_stylesheets(){
  wp_enqueue_style('font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css'); 
}
add_action('wp_enqueue_scripts','efp_enqueue_required_stylesheets');

/*
  Ładujemy plik ze skryptem JS
*/
function efp_enqueued_scripts() {
  wp_enqueue_script( 'efp-script', plugin_dir_url( __FILE__ ) . '/js/scripts.js', null, '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'efp_enqueued_scripts' );

/*
  Ładujemy nasz plik ze stylami
*/
function efp_enqueued_styles() {
  wp_enqueue_style( 'efp-style', plugin_dir_url( __FILE__ ) . '/css/styles.css', null, '1.0' );
}
add_action( 'wp_enqueue_scripts', 'efp_enqueued_styles' );


/*
  Ładujemy HTML
*/
function efp_html(){
  echo "<h1>To jest moja pierwsza wtyczka!</h1>";
}
add_action('wp_footer', 'efp_html');

Dodaliśmy trzy funkcje, które ładują nasze style i skrypty i powiązaliśmy je z akcją wp_enqueue_scripts (swoją drogą trochę dziwny zabieg, że jednak akcja służy zarówno do skryptów i do stylów… w dodatku końcówka „scripts” może być mocno myląca…). Na większą uwagę zasługuje 3 oraz 5 parametr funkcji wp_enqueue_scriptwp_enqueue_style: trzeci zawiera ścieżkę do naszych plików, a piąty jego wersję (jest to dobre posunięcie pod względem cachowania plików przez przeglądarki).

Skąd wiedzieć jakich funkcji mamy użyć i jakie przyjmują argumenty? Czasem może nam w tym pomóc dobre IDE. Jeśli jednak takowego nie posiadamy to zostaje nam szukanie rozwiązania na stronach WordPressa (codex) albo po prostu w wyszukiwarce.

Skoro odwołujemy się do dodatkowych plików to warto je utworzyć, bo inaczej dostaniemy błąd 404. Teraz nasze drzewo folderów (i plików) powinno więc wyglądać następująco:

WordPress - drzewo folderów ze skryptami i stylami

WordPress – drzewo folderów ze skryptami i stylami

Dodanie funkcjonalności popup

Korzystając z wcześniej poznanych wiadomości jesteśmy już w stanie napisać całość naszej wtyczki – musimy po prostu uzupełnić funkcję efp_html oraz pliki: styles.css oraz scripts.js. Można to zrobić chociażby korzystając z odpowiedniego poradnika. Nie jest to już zagadnienie bezpośrednio związane z WordPressem. W najprostszej wersji (czyli opierając się na wspomnianym poradniku) kod wskazanych plików będzie się przestawiał jak poniżej.

Plik easy-free-popup.php:

<?php
/*
  Plugin Name: Easy Free Popup
  Version: 0.1
  Description: Basic popup with social media
  Author: Józef Curyłło
  Author URI: http://szalonypecet.pl
 */


/*
  Load Font-Awesome (to show icons of Social Media)
*/
function efp_enqueue_required_stylesheets(){
  wp_enqueue_style('font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css'); 
}
add_action('wp_enqueue_scripts','efp_enqueue_required_stylesheets');

/*
  Load necessary scripts
*/
function efp_enqueued_scripts() {
  wp_enqueue_script( 'efp-script', plugin_dir_url( __FILE__ ) . '/js/scripts.js', null, '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'efp_enqueued_scripts' );

/*
  Load necessary styles
*/
function efp_enqueued_styles() {
  wp_enqueue_style( 'efp-style', plugin_dir_url( __FILE__ ) . '/css/styles.css', null, '1.0' );
}
add_action( 'wp_enqueue_scripts', 'efp_enqueued_styles' );


/*
  Load HTML
*/
function efp_html(){
  ?>
  <div id="efp_modal" class="efp-modal">
    <div class="efp-modal-content">
      <div class="efp-modal-header">
      <span id="efp_close">&times;</span>
      <h2><?php _e('Stay with us on social media!'); ?></h2>
      </div>
      <div class="efp-modal-body">
      <p class="efp-justify-text efp-padding-text"><?php _e('If you like our page you should also stay connected with us. Just visit our social media pages and become our fan. You will obtain additional articles, news and you will be the first one who knows what is new on our website.'); ?></p>
      <div class="aligncenter efp-center-text efp-social-box">

          <a href="https://www.facebook.com/Szalony-pecet-713171005480057/" 
          title="Facebook - <?php echo get_option('blogname'); ?>"
          target="_blank"> 
            <i class="fa fa-facebook-official fa-3x" aria-hidden="true"></i>
          </a>
       
          <a href="https://twitter.com/SzalonyPecet" 
          title="Twitter - <?php echo get_option('blogname'); ?>"
          target="_blank"> 
            <i class="fa fa-twitter-square fa-3x" aria-hidden="true"></i>
          </a>

      </div>
      
      </div>
      <div class="efp-modal-footer">
      <h3><?php _e('Thank you!'); ?></h3>
      </div>
    </div>
  </div>
  <?php 
}
add_action('wp_footer', 'efp_html');

Plik scripts.js:

// get elements
var modal = document.getElementById('efp_modal');
var span = document.getElementById("efp_close");

// calculate the scroll position in percentage
function getScrollPercent() {
    var h = document.documentElement, 
        b = document.body,
        st = 'scrollTop',
        sh = 'scrollHeight';
    return (h[st]||b[st]) / ((h[sh]||b[sh]) - h.clientHeight) * 100;
}

// set a cookie
function setCookie(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+ d.toUTCString();
    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

// get a cookie
function getCookie(cname) {
    var name = cname + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i <ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

var cookie_name = "efp_modal_cookie";

function showPopup(){
  if (!getCookie(cookie_name)){
    modal.style.display = "block";
    setCookie(cookie_name, 1 , 30);
  }
}

if (!getCookie(cookie_name)){

  // call function after scrolling
  window.onscroll = function() {
    if (getScrollPercent() >= 70){
      showPopup();
    }	
  };

  // When the user clicks on <span> (x), close the modal
  span.onclick = function() {
    modal.style.display = "none";
  }

  // When the user clicks anywhere outside of the modal, close it
  window.onclick = function(event) {
    if (event.target == modal) {
      modal.style.display = "none";
    }
  }

}

Plik styles.css:

/* The Modal (background) */
.efp-modal {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 1000; /* Sit on top */
    left: 0;
    top: 0;
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: auto; /* Enable scroll if needed */
    background-color: rgb(0,0,0); /* Fallback color */
    background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* Modal Content/Box */
.efp-modal-content {
    background-color: #fefefe;
    margin: 15% auto; /* 15% from the top and centered */
  position: relative;
    background-color: #fefefe;
    border: 1px solid #888;
    width: 80%;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
    -webkit-animation-name: animatetop;
    -webkit-animation-duration: 0.4s;
    animation-name: animatetop;
    animation-duration: 0.4s
}

/* The Close Button */
#efp_close {
    color: #aaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
}

#efp_close:hover,
#efp_close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}

/* Modal Header */
.efp-modal-header {
    padding: 2px 16px;
    background-color: #000;
    color: white;
  border-bottom: #ea0000 solid 3px;
}

.efp-modal-header h2 {
  padding: 0;
        color: #adadad;
}

/* Modal Body */
.efp-modal-body {
  padding: 2px 16px;
  background-color: #f5f5f5;
}

/* Modal Footer */
.efp-modal-footer {
    padding: 2px 16px;
    background-color: #000;
    color: white;
}

.efp-modal-footer h3 {
  padding-top: 10px !important;
        color: #717171;
}

/* Modal Content */
.efp-modal-content {
  
}

/* Add Animation */
@-webkit-keyframes animatetop {
    from {top: -300px; opacity: 0} 
    to {top: 0; opacity: 1}
}

@keyframes animatetop {
    from {top: -300px; opacity: 0}
    to {top: 0; opacity: 1}
}


/*
  Common text styles
*/
.efp-center-text {
  text-align: center;
}

.efp-justify-text {
  text-align: justify;
}

/*
  Padding for elements in the modal
*/
.efp-padding-text {
  padding: 10px;
}

.efp-social-box {
  padding: 20px;
}

Podsumowanie

Przedstawiony plugin działa poprawnie, tzn. wyświetla się po przewinięciu 70% strony oraz pojawia się użytkownikowi raz na 30 dni (na podstawie ciasteczka). Po zmianie „contentu” przedstawia się jak poniżej:

WordPress- przykład pluginu easy-free-popup

WordPress- przykład pluginu easy-free-popup

Omówiony powyżej przykład jest jedną z najprostszych możliwych wtyczek jakie możemy napisać do CMSa WordPress. W ogóle nie wspomniałem tutaj chociażby o tworzeniu strony ustawień dla naszej wtyczki czy o obsłudze bazy danych – na te tematy przyjdzie kolej w przyszłości. WordPress posiada całkiem sporo możliwości i jak widać jakoś się spisuje we współczesnym świecie. Chciałbym jednak wspomnieć, że taki styl pisania wtyczek jest trochę mało ambitny i przestarzały – warto by się postarać o użycie OOP (szczególnie w przypadku skomplikowanych pluginów). Warto jednak zacząć od prostych struktur, żeby móc zagłębiać się w bardziej zaawansowane tematy 🙂

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *