Jak może wyglądać zarządzanie menu w WordPressie, 10 ciekawostek, tworzenie tłumaczeń w kokpicie – WordPressowe Linki #31

Zarządzanie menu na ekranie personalizacji motywu

Warto przyjrzeć się jak może wyglądać zarządzanie menu z poziomu ekranu personalizacji motywu. Mam przeczucie, że jeszcze góra kilka wersji WordPressa i oddzielne strony zarządzania widżetami i menu znikną zupełnie z kokpitu.

10 rzeczy, których nie wiecie o WordPressie

Zbiór 10 ciekawostek dotyczących WordPressa o których większość użytkowników zapewne nie miała pojęcia.

Tworzenie tłumaczeń dla wtyczek i motywów w kokpicie WordPressa

Każdemu zapewne zdarzyło się być zmuszonym do stworzenia tłumaczenia jakiejś wtyczki lub motywu – dzięki powyższej wtyczce można zrezygnować z dodatkowego programu do tworzenia tłumaczeń i zacząć robić tłumaczenia bezpośrednio w kokpicie.

WordPress.com standaryzuje wsparcie motywów dla logotypów

To dość logiczne posunięcie – chyba każdy motyw zawierający wsparcie dla ekranu personalizacji motywu zawiera opcję pozwalającą określić logo strony.

List otwarty Sucuri do MailPoet w sprawie ostatnio wykrytej podatności

Krótko mówiąc zespół MailPoet trochę niepoważnie podszedł do sprawy poważnej luki bezpieczeństwa w swojej wtyczce. Mam nadzieję, że ta sytuacja nauczy deweloperów rozszerzeń dla WordPressa, że bezpieczeństwo użytkowników trzeba stawiać ponad kwestie marketingowe i PR-owe.

Pobieranie produktu WooCommerce na bazie jego SKU z uwzględnieniem wielojęzyczności (WPML)

Dzisiaj krótki kawałek kodu, który może się przydać osobom posiadającym wielojęzyczne sklepy oparte na WooCommerce i WPML.

Otóż typowy kod zwracający produkt z WooCommerce na bazie jego SKU wygląda następująco:

function get_product_by_sku( $sku ) {
    global $wpdb;
    $product_id = $wpdb->get_var($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $sku));
    if ($product_id) {
        return new WC_Product($product_id);
    }
    return null;
}

Niestety nie uwzględnia on faktu iż WPML dla każdego produktu tworzy oddzielny rekord w tabeli postów, zatem otrzymamy produkty w jednym języku. Na szczęście możemy to naprawić i to w relatywnie prosty sposób, bo wystarczy zmodyfikować zapytanie:

function get_product_by_sku($sku) {
    global $wpdb;

    $product_id = $wpdb->get_var($wpdb->prepare("SELECT pm.post_id FROM ".$wpdb->postmeta." AS pm LEFT JOIN ".$wpdb->prefix."icl_translations AS tr ON pm.post_id = tr.element_id WHERE pm.meta_key='_sku' AND pm.meta_value='%s' AND tr.language_code = '".ICL_LANGUAGE_CODE."'", $sku));

    if($product_id) {
        return new WC_Product($product_id);
    }
    return null;
}

Powyższy kod działa podobnie do poprzedniego tylko podczas zapytania pobierane są dane z tabeli icl_translations, które pozwalają określić język wpisów powiązanych ze zwracanymi ID. Oczywiście najważniejszy jest ostatni warunek, który wybiera tylko ten rekord, który powiązany jest z obecnie wykorzystywanym językiem na stronie.

Odpowiedzi na pytania z WordUpa w Krakowie

Na ostatnim WordUpie w Krakowie po mojej prelekcji pojawiło się kilka pytań wartych opisania z odpowiedziami w formie wpisu.

Jak dodać do popupa własną logikę?

W zasadzie dobór metody zależy od poziomu skomplikowania zawartości popupa i logiki go obsługującej. Jeżeli potrzebujemy zawartości popupa mającej niewiele wspólnego z listą kontrolek to mamy do dyspozycji dwa rozwiązania – skorzystać z kontrolki typu container, która oferuje nam możliwość wstawienia własnego kodu HTML przez właściwość html oraz obsługę zdarzeń poprzez onclick, onmouseover etc. Przykładem wykorzystania tej kontrolki jest wtyczka charmap – polecam lekturę jej kodu.

Drugie wyjście to sposób w jaki rozwiązano to w wypadku wstawiania linków – istnieje wtyczka wplink, która korzysta z obiektu window.wpLink zdefiniowanego w pliku wp-includes/js/wp-link.js – w tym wypadku działa to tak, że kliknięcie przycisku powoduje wywołanie metody open obiektu window.wpLink z ID aktywnego edytora. Dzięki temu możemy wykonać w popupie w zasadzie dowolny kod a na koniec rezultaty umieścić w edytorze znając jego ID. Póki co polecam analizę kodu wspomnianej wtyczki i skryptu z nią związanego – możecie się spodziewać, że rozwinę ten temat w sierpniu na łamach bloga 😉

Jak usunąć buttony po nazwie (czy jest oddzielna metoda)?

Jest to bardzo dobre pytanie, gdyż związane jest ono z większą elastyką naszych skryptów. Wyobraźmy sobie sytuację w której korzystamy z następującego kodu:

function dziudek_remove_btn($btns) {
    unset($btns[0]);
    return $btns;
}

add_action('mce_buttons', 'dziudek_remove_btn');

Ten kod będzie działał dokładnie tak jak sobie to zaplanowaliśmy do momentu gdy użytkownik nie wpadnie na pomysł wstawienia na początku pierwszego rzędu przycisków własnego przycisku – wtedy nasz skrypt usunie ten nowo dodany przycisk a nie przycisk pogrubienia tekstu. Na szczęście możemy temu łatwo zaradzić modyfikując trochę kod usuwania przycisku:

function dziudek_remove_btn($btns) {
    $index = array_search('bold', $buttons);

    if($index !== FALSE) {
        array_splice($buttons, $index, 1);
    }

    return $btns;
}

add_action('mce_buttons', 'dziudek_remove_btn');

Powyższy kod korzysta z faktu, że przyciski są przechowywane w tablicach według nazw. Istnieje też druga metoda – można przyciski usunąć już na etapie działania filtra tinymce_before_init.

Niestety nie natrafiłem na dedykowaną funkcję służącą do usuwania przycisków po samej nazwie.

Jak wykorzystać w TinyMCE kontrolki wyboru kolorów w popupie?

Pytanie o kontrolki kolorów pojawia się bardzo często, niestety są one też najbardziej problematyczne w wykorzystaniu. Teoretycznie można umieścić kontrolkę wyboru kolorów w popupie z użyciem pola typu colorbutton. Problem polega na tym, że aby ta kontrolka zadziałała trzeba stworzyć spory kawałek kodu generujący listę kolorów – w najprostszym wypadku wymaga to skopiowania 3/4 kodu wtyczki textcolor, gdyż ta wtyczka posiada kod, który generuje całą strukturę bloku pozwalającego wybrać kolor tekstu/tła.

Mam pewien pomysł na podejście do tego problemu i myślę, że w sierpniu można spodziewać się wpisu na ten temat (podobnie jak w wypadku logiki w popupach).

Jaką korzyść dają nam przyciski wstawiające kod, który można uzyskać poprzez dostępne już w TinyMCE przyciski?

To pytanie zasugerowało mi, że sekcja prezentacji odpowiadająca na pytanie – „Dlaczego warto tworzyć wtyczki dla TinyMCE?” wymaga rozwinięcia 🙂 Przede wszystkim trzeba wziąć poprawkę na to, że moja prelekcja opisuje podstawowe funkcjonalności i rzeczywiście efekty mogą się wydawać powieleniem dostępnych już funkcji. Co nie zmienia faktu, że przy edycji dużej ilości tekstu nawet przycisk, który jednym kliknięciem zastępuje trzy kliknięcia w edytorze jest naprawdę dużym udogodnieniem (nieraz się o tym przekonałem na własnej skórze). No i pozostaje kwestia bardziej zaawansowanych rozwiązań przygotowywanych pod klientów – jeżeli musimy wstawiać np. mapy we wpisach to miło byłoby gdyby klient od razu widział podgląd tego co wstawił i nie musiał znać całego API skryptu generującego mapki – tu właśnie leży siła autorskich rozwiązań – możemy sobie i klientowi dość łatwo ułatwić życie i uniknąć zbędnych pytań.

 

Zdjęcie dzięki uprzejmości Kasi Karus – współorganizatorki WordUpa w Krakowie.

Jak w prosty sposób stworzyć cache dla shortcode’ów?

Czasami zdarza się, że shortcode przed zwróceniem efektów swojego działania musi wykonać dużo czasochłonnych operacji – np. jeżeli robimy shortcode, który zwraca statusy z Twittera dla określonego zapytania. W takim wypadku powinniśmy stworzyć cache z dwóch powodów:

  • pobranie informacji o statusach z Twittera wymaga pobrania tych danych z zewnętrznego serwera co może zająć sporo czasu
  • Twitter nakłada limity zapytań do swojego API

Na szczęście stworzenie prostego mechanizmu cache dla shortcode’ów jest w WordPressie bardzo proste.

Przyjmijmy, że nasz shortcode pobiera 3 różne parametry z wartościami domyślnymi i zamieniane na zmienne o odpowiednich nazwach w poniższy sposób:

$atts = shortcode_atts(array(
'param1' => 'lorem',
'param2' => 'ipsum',
'param3' => 'dolor'
), $atts);

extract($atts);

Zatem nasz shortcode ma poniższą składnię:

[txt][shortcode param1=”x” param2=”y” param3=”z”][/txt]

Pierwsza istotna obserwacja – nasz shortcode zwróci te same rezultaty dla takich samych wartości parametrów, zatem ciąg złożony z wartości tych parametów może śmiało posłużyć za identyfikator rezultatów danego shortcode’a. Do przechowania zawartości cache wykorzystamy Transients API.

Zatem nasz mechanizm cache będzie potrzebował dwóch kluczowych fragmentów kodu – zapisu i odczytu zawartości cache.

Zacznijmy od odczytu zawartości cache, gdyż ta operacja jest wykonywana przez rozpoczęciem operacji przez nasz shortcode:

$cache = get_transient(md5('PREFIX'.serialize($atts)));

if($cache) {
    return $cache;
}

Jak wspominałem – wykorzystujemy ciąg wartości parametrów jako identyfikator, do tego sugeruję dodać też jakiś własny prefix – dzięki temu zabezpieczymy się przed sytuacją gdy wszystkie parametry będą puste. Jeżeli cache dla danej konfiguracji istnieje to po prostu funkcja zwróci od razu zawartość cache, bez wykonywania dodatkowych operacji.

Następnie cały kod wyjściowy generowany przez shortcode umieszczamy w zmiennej np. $cache_output – jeżeli dobrze tworzycie swoje shortcode’y to zapewne taką zmienną z zawartością rezultatów już posiadacie (nie używacie w shortcode’ach echo, prawda?). Na koniec działania naszego shortcode’u możemy umieścić zawartość tej zmiennej w bazie danych:

set_transient(md5('PREFIX'.serialize($atts)) , $cache_output, 10 * 60);

Jak widać dzięki stworzeniu 6 dodatkowych linijek kodu mały gotowy mechanizm cache.

Osobiscie polecam do listy parametrów takiego shortcode’a dodać też parametr cache_time – dzięki temu będzie można określić czas przechowywania cache, a ostatnia linijka związana z cache zmieni się na:

set_transient(md5('PREFIX'.serialize($atts)) , $cache_output, $cache_time * 60);

Powyższe rozwiązanie ma tą zaletę, że w wypadku shortcode’ów w których istnieje niewielkie zróżnicowanie wartości parametrów do przechowywania rezultatów nawet z kilku tysięcy wpisów, będzie potrzeba kilku-kilkunastu rekordów w bazie danych. Natomiast sugeruję ostrożność w wypadku gdy przy podobnej liczbie wpisów mamy unikalne konfiguracje shortcode’ów – wtedy istnieje ryzyko, że ilość rekordów w bazie danych będzie zbliżona do liczby wpisów.

Historia WordPressa, Panele w ekranie personalizacji, usprawnienia dla motywów – WordPressowe Linki #30

Artykuł o historii WordPressa, jego ekosystemie i przyszłości

Historia WordPressa oraz duża dawka wiedzy o jego obecnym ekosystemie – warta uwagi lektura szczególnie dla osób, które chcą wkroczyć w WordPressowy świat.

Usprawnienia ekranu personalizacji motyw w WordPressie 4.0

WordPress 4.0 wprowadza spore zmiany w ekranie personalizacji motywu. Największą zmianą są panele – dzięki nim będzie można stworzyć grupy zakładek opcji motywu. Ten mechanizm został też wykorzystany do odseparowania widżetów od ustawień motywu – zamiast listy wszystkich paneli bocznych w WordPressie 4.0 będziemy mieli jedną zakładkę „Widżety” po kliknięciu której pojawi się lista paneli bocznych.

Powiązanie motywów z wtyczkami z użyciem TGM Plugin Activation Library

Tutorial opisujący jak wykorzystać w swoim motywie TGM Plugin Activation Library, która umożliwia poinformowanie użytkownika naszego motywu o tym jakie wtyczki są potrzebne do uzyskania pełnej funkcjonalności strony – jest to niezwykle wygodne rozwiązanie jeżeli mocno rozdzielamy funkcjonalność wtyczki od funkcjonalności motywu.

Tworzenie podstron przy aktywacji motywu

Przydatny fragment kodu, który umożliwia stworzenie podstron w trakcie aktywacji motywu – idealne w wypadku, gdy podstrony stanowią istotny fragment wizualny naszego motywu.

Dodawanie numerowanego stronicowania w motywie

Jeżeli nie chcecie zaciągać do tworzenia numerowanego stronicowania wpisów dodatkowych wtyczek to powyższy artykuł opisuje proste rozwiązanie wymagające niewielkiej ilości kodu.

Dodawanie podtytułów do wpisów

Podtytuły to zgrabny element typografii całego wpisu – powyższy artykuł opisuje prosta wtyczkę która dodaje w edytorze wpisów dodatkowe pole do dodawania podtytułów dla naszych wpisów.

TinyMCE – zarządzanie stanami przycisków

W poprzednich wpisach pokazałem jak dodawać własne przyciski do edytora TinyMCE oraz wstawić własny kod do edytora. Pora na zagadnienie bardziej złożone – dodawanie własnego formatowania i sprawienie by zachowywało się ono tak jak podstawowe przyciski formatowania dostępne w TinyMCE.
Czytaj dalej TinyMCE – zarządzanie stanami przycisków

Podgląd zmian kolorów motywu na ekranie personalizacji

Ekran personalizacji motywu to świetne narzędzie, które umożliwia łatwy podgląd zmian, które chcemy nanieść w naszym motywie z użyciem jego opcji. Jedną z ciekawszych opcji jakie możemy zaoferować użytkownikom naszego motywu jest możliwość zmiany kolorów w motywie z podglądem „na żywo” w ekranie personalizacji.

Czytaj dalej Podgląd zmian kolorów motywu na ekranie personalizacji