Pluginy do WordPress

Uwaga: post oryginalnie został opublikowany w 2014, ale lista pluginów jest stale aktualizowana.

Poniżej prezentuję moją subiektywną listę najlepszych pluginów przydatnych do tworzenia i utrzymywania serwisu opartego o platformę WordPress.

Jeżeli znasz przydatny plugin podziel się tym w komentarzu.

Budowanie serwisu

Advanced Custom Fields – najlepszy plugin do budowania intuicyjnego interfejsu w panelu admina dla użytkowników serwisu postawionego na WordPress’ie. ACF bazuje na WordPress’owych custom_fields, nawet początkujący developer WP jest w stanie stworzyć przyjazdy interfejs z dedykowanymi polami pod konkretne dane dla każdego typu postu czy strony. Z płatnych add-on’ów szczególnie polecam The Repeater Field (do sortowania użyteczny jest Advanced Custom Fields Repeater & Flexible Content Fields Collapser). Integracja z Gravity: Gravityforms Add-on, i NinjaForms.

Custom Post Type UI – plugin do tworzenia własnych typów danych i taksonomii, współpracuje z ACF.

Posts 2 Posts – Najlepszy plugin do tworzenia relacji pomiędzy typami postów. To poniekąd analogia do typu Relationship z ACF.

Debug Bar – plugin dodaje do wordpressowego toolbara informacje o wykonanych zapytaniach SQL, pobranych danych z cache, warningach i noticeach phpowych, listuje zmienne GET, POST, COOKIE oraz inne przydatne informacje. Aby skorzystać z wszystkich możliwości plugina należy ustawić w wp-config.php zmienne WP_DEBUG i SAVEQUERIES na true.

Query Monitor – dużo lepsza wtyczka od Debug Bar. Wyświetla więcej danych w bardziej przystępny sposób.

Regenerate Thumbnails – niezastąpiony plugin do aktualizowania plików graficznych z biblioteki mediów po zmianie rozmiaru miniaturek (Ustawienia->media) lub po dodaniu dodatkowych niestandardowych rozmiarów poprzez funkcję add_image_size.

Polylang – bardzo dobry plugin do obsługi wielojęzykowych serwisów, w przeciwieństwie do WPML jest darmowy.

https://github.com/KLicheR/wp-polylang-translate-rewrite-slugs/blob/master/polylang-translate-rewrite-slugs.php

JSON API – RESTful API dla WordPressa. Przydatne gdy w prosty sposób chcemy dostarczyć dane z WP do aplikacji zewnętrznych lub interfejsów JavaScriptowych.

WordPress REST API – oficjalny plugin REST API od WP

Add From Server – jeżeli potrzebujesz wgrywać do WP duże pliki to zrobisz to dzięki Add From Server. Schemat działania jest prosty, wgrywasz duży plik poprzez FTP do określonego katalogu a następnie z poziomu WP dodajesz do biblioteki mediów. Prosto i intuicyjnie. Jeżeli potrzebujesz wgrywać pliki o niestandardowych rozszerzeniach to pamiętaj o wyłączeniu natywnego filtrowania.

Loco Translate – plugin do tłumaczeń, korzysta z plików PO.

Post Type Archive Link – plugin dodaje linki do menu dla stron list custom post type. Dzięki temu można w prosty i automatyczny sposób dodawać do menu linki do stron z listami custom posts.

Breadcrumb NavXT – plugin do generowania okruszków, breadcrumbs

Simple Share Buttons Adder – przyjazny plugin do social ikon.

Social Media Feather – chyba jeszcze lepszy plugin do social media ikon.

SVG Support – plugin umożliwiający wgrywanie do WP plików SVG. Dodaje też pogląd SVG w bibliotece mediów.

WP-DB-Table-Editor – plugin umożliwiający odczyt/zapis/eksport danych z customowych tabel z bazy danych.

WP Crontrol – plugin umożliwiający dodawanie i zarządzeni wbudowanymi do WP zadaniami crona

Czytaj dalej Pluginy do WordPress

Wysyłka SMS w aplikacjach internetowych

Tworząc aplikacje internetowe często zachodzi potrzeba implementacji modułu do wysyłki SMS.

Może to być informacja o zmianie statusu zamówienia złożonego w sklepie internetowym, może to być jakiś ważny komunikat systemowy dotyczący konta w serwisie, może to być powiadomienie o wystąpieniu jakiegoś zdarzenia, które monitoruje klient (np. pojawienie się oferty spełniającej ustawione kryteria) lub po prostu mechanizm weryfikacji wysyłający kod na telefon. Potrzeby wdrożeń powiadomień SMS’owych z pewnością można mnożyć.

Wdrażając moduł powiadomień SMS należy mieć na uwadze, że komunikacja SMS’owa nadaje przekazywanej wiadomości dużo większy priorytet niż e-mail czy powiadomienie w aplikacji na smartfona, nic bardziej nie irytuje użytkownika niż spam w SMS’ach.

Obecnie w internecie znaleźć można bardzo wiele bramek/serwisów oferujących mniej lub bardziej zaawansowane systemy do obsługi powiadomień sms.

Jak to działa?

Wdrożenie modułu SMS jest na prawdę proste i nieskomplikowane, opiera się na 3 krokach:

  • Rejestrujesz się w serwisie obsługującym wysyłki SMS. Ściągasz klienta API czyli bibliotekę przez którą łączysz się z systemem obsługującym wysyłkę.
  • Wprowadzasz namiary autoryzacyjne (login/hasło/hash autoryzujący) tak aby system mógł zidentyfikować żądanie wysyłki.
  • Wdrażasz wywołanie API do aplikacji.

Należy w tym miejscu rozróżnić bramkę sms od usługi sms api. Zwykła bramka sms jedynie umożliwia ręczne wprowadzenie wiadomości natomiast w aplikacji potrzebujemy mechanizmu automatycznego, czyli dostęp przez API.

Który serwis do wysyłki SMS wybrać?

Jak wspomniałem wcześniej, serwisów do wysyłki SMS jest wiele, zdecydowana większość jest płatna a ceny wahają się w granicach od kilku do kilkunastu groszy za SMS, czyli w budżecie np. 100 zł dostępnych jest 1428 smsów w cenie 0,07 zł każdy. Myślę, że przy takim niskim koszcie wysyłki nie opłaca się szukać na siłę darmowych niekoniecznie sprawdzonych i dobrze działających alternatyw.

Ja w projekcie wybrałem SMSAPI.pl. Dlaczego?

  • Profesjonalnie napisany klient php, dostępny od ręki w composerze.
  • Bardzo dobrze przygotowany dział dla developera (smsapi.pl/dev) z wieloma gotowymi modułami i przykładowymi integracjami.
  • Mnogość opcji wysyłki wiadomości ECO, PRO, ze zdefiniowanym nadawcą lub bez, MMS, VMS, odbiór wiadomości.
  • Szybkość działania, większość wiadomości dostarczane jest w czasie do 10 sekund.
  • Przejrzysty serwis internetowy i panel klienta, możliwość wysyłki bezpośrednio z panelu klienta.

Przykład użycia API

<?php

require_once 'smsapi/Autoload.php';

$client = new \SMSApi\Client('login');
// Ustawiamy hasło, w panelu klienta możemy wygenerować hasło różne od hasła do panelu klienta, wysyłkę można też zabezpieczyć IPkami.
$client->setPasswordHash( 'haslo w md5' );

// Inicjalizujemy klienta API
$smsapi = new \SMSApi\Api\SmsFactory();
$smsapi->setClient($client);

try {

    $actionSend = $smsapi->actionSend();

    $actionSend->setTo('600xxxxxx');
    $actionSend->setText('Hello World!!');
    //Pole nadawcy lub typ wiadomość 'ECO', '2Way'
    $actionSend->setSender('Info');

    $response = $actionSend->execute();

    foreach( $response->getList() as $status ) {
        echo  $status->getNumber() . ' ' . $status->getPoints() . ' ' . $status->getStatus();
    }
}
// Przechwytujemy ewentualne błędy, będą one automatycznie widoczne w panelu klienta.
catch( \SMSApi\Exception\SmsapiException $e ) {
    echo 'ERROR: ' . $e->getMessage();
}

Kombinacje bez powtórzeń zbioru liczb – zapytanie SQL

Pytanie zgłoszone przez czytelnika. W jaki sposób z zestawu liczb będących w osobnych rekordach wyświetlić kombinacje bez powtórzeń. Dla przykładu wyświetlimy kombinacje bez powtórzeń zbioru 3 elementowego ze zbioru 6 elementowego. n!/k!(n-k)!

Tworzymy tabelę testową:

create table test(
id serial primary key,
  number float
);

insert into test(number) values(2.49);
insert into test(number) values(5.11);
insert into test(number) values(10);
insert into test(number) values(20);
insert into test(number) values(27.4);
insert into test(number) values(75);

W zapytaniu nasze dane złączamy 3 krotnie bo takiej wielkości zbiór unikalnych liczb chcemy uzyskać, złączamy z warunkiem na różne IDki aby uniknąć zduplikowanych liczb. Następnie w zapytaniu nadrzędnym odfiltrowujemy powtarzające się rekordy.

W przypadku gdybyśmy chcieli uzyskać zbiory 4 elementowe należy złączyć 4 krotnie, stworzyć kolumnę number4 i dodać na nią warunek w zapytaniu zewnętrznym.

SELECT 
*
FROM 
  (SELECT
    T1.number AS number1, 
    T2.number AS number2, 
    T3.number AS number3 
  FROM test AS T1 
  JOIN test AS T2 ON T1.id != T2.id
  JOIN test AS T3 ON T2.id != T3.id AND T1.id != T3.id
  ORDER BY number1, number2, number3
  ) AS sub
WHERE 
  sub.number1 <  sub.number2
AND
  sub.number2 <  sub.number3

Wynik zapytania:

 number1 | number2 | number3
---------+---------+---------
    2.49 |    5.11 |      10
    2.49 |    5.11 |      20
    2.49 |    5.11 |    27.4
    2.49 |    5.11 |      75
    2.49 |      10 |      20
    2.49 |      10 |    27.4
    2.49 |      10 |      75
    2.49 |      20 |    27.4
    2.49 |      20 |      75
    2.49 |    27.4 |      75
    5.11 |      10 |      20
    5.11 |      10 |    27.4
    5.11 |      10 |      75
    5.11 |      20 |    27.4
    5.11 |      20 |      75
    5.11 |    27.4 |      75
      10 |      20 |    27.4
      10 |      20 |      75
      10 |    27.4 |      75
      20 |    27.4 |      75
(20 rows)

Masz problem SQL do rozwiązania? Napisz.

Jak usunąć klasę „hentry” z WordPress?

W wordpress’owym szablonie single.php, który odpowiada za wyświetlenie pojedynczego wpisu używana często jest funkcja

post_class();

Funkcja ta generuje szereg klas typu:

class="post-395 post type-post status-publish format-standard hentry category-sample category-wyroznione"

Konflikt Rich Snippets

Klasy te często są przydatne i na części z nich z pewnością opierają się definicje CSS. Problem w tym, że jeżeli na blogu posiadamy zaimplementowane Google Rich Snippets w formacie innym niż microformats to klasa „hentry” będzie powodować błędy widoczne na screenie. Czytaj dalej Jak usunąć klasę „hentry” z WordPress?

Jak w WordPress usunąć rel=”next” i rel=”prev”?

Według wytycznych Google atrybuty znacznika LINK rel=”next” i rel=”prev” znajdujące się w sekcji HEAD służą do wskazywania zależności pomiędzy stronami na liście stron… czyli opisują pozycje w pagerze. Jest to istotna podpowiedź na temat duplikacji oraz zależności treści w serwisie i wpływa pozytywnie na SEO.

Duże było moje zdziwienie gdy niedawno odkryłem, że WordPress standardowo wstawia te atrybuty na stronach ze szczegółami wpisu wstawiając w nich linki do następnego i poprzedniego (w kontekście daty publikacji) wpisu. Każdy post jest unikalny, posiada unikalny adres url i zazwyczaj nie jest semantycznie powiązany z następnym/poprzednim.

Wpisy z rel=”next” i rel=”prev” powinny być na stronie z listą wpisów w kategorii gdzie mamy stronicowanie, natomiast na stronach ze szczegółami wpisu znaczniki te są kompletnie niepotrzebne i mogą powodować jedynie zamieszanie.. Czytaj dalej Jak w WordPress usunąć rel=”next” i rel=”prev”?

Instalacja Apache 2.4 + PHP 5.4 pod Windows 7

Z pewnością w necie znajduje się już wiele poradników w temacie instalacji i konfiguracji PHP + Apache, jednak nie zawsze zawierają wszelkie niezbędne informacje. Wczoraj sam przebrnąłem przez proces aktualizacji z Apache 2.2 i PHP 5.2 do Apache 2.4 + PHP 5.4 co defakto oznaczało ponowną instalacją i konfiguracją tych dwóch softów. Czytaj dalej Instalacja Apache 2.4 + PHP 5.4 pod Windows 7

Sprawdzanie permutacji ciągu znaków w PostgreSQL

Permutacja w języku matematycznym to „wzajemnie jednoznaczne przekształcenie pewnego zbioru na siebie”. Używając języka mniej technicznego permutacje, na przykładzie liter w słowie, to wszystkie możliwe ustawienia literek w słowie, zatem dla słowa „marcin” permutacjami będą: „amrcin”, „mracin”, „mrcain” etc… w słowie 6 znakowym będzie ich łącznie 6!.

Problem

W bazie danych mamy pole tekstowe z zapisanymi pewnymi ciągami znaków, chcemy sprawdzić te dane pod kątem występowania w nich permutacji pewnego stringu. Czyli mając w danych wejściowych np. „mrcain” chcemy sprawdzić czy w bazie nie ma „marcin” lub innej permutacji. Czytaj dalej Sprawdzanie permutacji ciągu znaków w PostgreSQL

Jak w Google Analytics zliczać kliknięcia ‚like it’?

Tworząc aplikacje czy konkursy na Facebooku z pewnością chcielibyśmy wiedzieć jak przekładają się one na przyrost fanów fanpage marki.

  1. W sekcji <head> podpinamy kod Google Analytics.
  2. Wstawiamy like button <fb:like></fb:like>
  3. Osadzamy asynchroniczny kod biblioteki Facebooka.
  4. Podpinamy funkcje pod zdarzenia facebooka ‚edge.create’ i ‚edge.remove’, w tych funkcjach wywołujemy handler Google Analytics z pożądanymi parametrami.

 

<head>
 <script type="text/javascript">
      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', 'UA-XXXXX-XX']);
      _gaq.push(['_trackPageview']);
    
      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();  
 </script>
</head>

<body>
<div id="fb-root"></div>
<fb:like href="http://www.facebook.com/FANPAGE" send="false" show_faces="false" font=""></fb:like>

<script type="text/javascript">
    window.fbAsyncInit = function() {
        FB.init({appId: 'YOUR_APP_ID', status: true, cookie: true, xfbml: true});
        FB.Canvas.setAutoResize();
        FB.Event.subscribe('edge.create',
            function(response) {
                alert('like');
                _gaq.push(['_trackPageview', '/like_it']);
            }
        );
        FB.Event.subscribe('edge.remove',
            function(response) {
                alert('unlike');
                _gaq.push(['_trackPageview', '/unlike_it']); 
            }
        );
    };

    //Load the SDK asynchronously
    (function() {
        var e = document.createElement('script'); e.async = true;
            e.src = document.location.protocol +
              '//connect.facebook.net/pl_PL/all.js';
            document.getElementById('fb-root').appendChild(e);
    }());
</script>
</body>

Z powyższego kodu należy usunąć alerty, które są wstawione jedynie dla testu działania mechanizmu.

Numerowanie listy zwracanych rekordów w MySQL

Przy różnorakich konkursach często zachodzi potrzeba wyciągnięcia pozycji konkretnego użytkownika (wpisu w bazie) na tle innych użytkowników (wpisów) w ograniczeniu czasowym.

Czyli np. mamy 10 tys wyników gry z danego dnia i chcemy poznać pozycje w rankingu, które zajmują użytkownicy o identyfikatorach 1, 2, 3.

Oczywistym rozwiązaniem jest zwykły selekt z ORDER BY po polu z punktami i następnie iterowanie w php, jednak gdy liczba danych będzie większa taki SELECT nie wykona się lub będzie bardzo niewydajny.

Rozwiązaniem dużo lepszym jest użycie podzapytania i wykonania obliczeń numerowania na samej bazie a następnie zwrócenie do php jedynie rekordów pasujących do naszych użytkowników. Czytaj dalej Numerowanie listy zwracanych rekordów w MySQL

Jak promować serwis na Facebook’u?

Tego, że w dzisiejszych czasach obecność Twojego serwisu lub marki na Facebook’u jest niezbędna, tłumaczyć chyba nie trzeba. Jeżeli Cię tam nie ma – tracisz, gdyż Twoja konkurencja już tam jest i czerpie z tego profity.

Okej, zatem mając serwis internetowy (aka marka/firma) i konto na fejsie, jak mogę czerpać tego korzyści? Czytaj dalej Jak promować serwis na Facebook’u?