Tworzymy wtyczkę poprawiającą funkcjonowanie Kokpitu na ekranach dotykowych

Kokpicie, daj się dotknąć

Gdy ktoś dodaje zlecenie na WPzlecenia.pl, zlecenie zapisywane jest jak szkic wordpressowego wpisu, a ja dostaję o tym informację na maila z linkiem do tej części Kokpitu, w której mogę szybko zmienić status z szkic, na opublikowny.

Powyższy widok jest chyba wszystkim wordpressowcom znany: po najechaniu myszką na listę wpisów przy każdym z nich pojawia się zestaw kilku linków. Gdy klikniemy w jeden z nich – Szybka edycja – widzimy to co powyżej.

Problemem są ekrany dotykowe, z których coraz częściej korzystamy: nie da się na nich zasymulować stanu mouseover i skorzystać z dobrodziejstw CSSowej pseudoklasy :hover. Ta natomiast jest właśnie wykorzystywana w tym miejscu, dodatkowo zdarzenie mouseover wykorzystywane są w bocznym i górnym menu Kokpitu – po najechaniu na nie rozwijane jest podmenu. Na tablecie możemy tylko kliknąć, a wtedy otwierana jest główna strona danej grupy.

Postanowiłem  to naprawić. Nie było to trudne i napisanie odpowiedniej wtyczki zajęło mi kilka minut. Jest to jednak dobra okazja by jeszcze raz zaprezentować tutorial na temat tworzenia pluginów do WordPressa. Celem tej części jest nauczenie Was w jaki sposób osadzamy pliki skryptów JS i stylów CSS.

Założenia wtyczki

Wtyczka powinna:

  1. rozpoznać czy aktualnie używanym urządzeniem jest tablet lub telefon z ekranem dotykowym
  2. jeśli tak:
    1. usunąć style ukrywające szybkie odnośniki pod każdym wpisem w Kokpicie
    2. sprawić za pomocą JS, że kliknięcie w menu w jego element nie otworzy przypisanego do niego odnośnika, a jedynie rozwinie podmenu (jeśli element podmenu ma)
  3. działać powinna tylko w ramach Kokpitu

Pliki wtyczki

W katalogu /wp-content/plugins tworzymy nowy katalog na wszystkie pliki wtyczki – w moim wypadku będzie to katalog 'touchscreen-dashboard-fixes’.

W katalogu tworzymy pliki:

  • touchscreen-dashboard-fixes.php – jako główny plik z kodem wtyczki oraz nagłówkiem informującym o wtyczce
  • script.js  – plik na skrypty JavaScript zmieniające domyślne działanie górnego i lewego menu
  • style.css – plik na style CSS „odkrywające” szybkie linki na liście wpisów

Zawartość pliku stylów

Inspektorem kodu wbudowanym w Chrome sprawdzam jak to się dzieje, że szybkie linki pod wpisem są widoczne dopiero po najechaniu myszką:

Jak widać każdy blok w takimi szybkimi linkami ma przypisaną klasę row_actions a w niej zdefiniowane visibility: hidden. Musimy zmienić wartość tego parametru na visible, kod naszego pliku style.css będzie więcej krótki:

.row-actions {
 visibility: visible;
}

Więcej stylów zmieniać nie musimy, plik więc można zapisać i zamknąć.

Zawartość pliku ze skryptami

Po kliknięciu w napisy lewego lub górnego menu przechodzimy pod kolejne adresy dlatego, że są one zwykłymi odnośnikami (znacznik <a…). Trzeba zatem za pomocą JavaScript tym odnośnikom (i tylko tym) zablokować takie przekierowanie.

Ponownie inspektorem (użytkownicy Firefoksa zapewne użyli by tu dodatku Firebug) sprawdzam kod interesujących nas elementów. Odnośnik w lewym menu znajduje się w elemencie z klasą .wp-menu-image znajdującej się z kolej w elemencie z klasą .wp-has-submenu (zwłaszcza ta ostatnia jest ważna bo wskazuje, że element ma podmenu, nie wszystkie bowiem pozycje w lewym menu są rozwijalne). Odnośnik w górnym menu to element <a> znajdujący się w elemencie z klasą .menupop.

Gdy już zdefiniowaliśmy zagnieżdżenie w drzewie dokumentu interesujących nas elementów za pomocą jQuery możemy wyłączyć ich domyślne działanie. Kod pliku script.js będzie wyglądał następująco:

jQuery(document).ready(function($) {
 $('.wp-has-submenu .wp-menu-image a, .menupop a').click(function() {
 event.preventDefault();
 });
});

Nie jest to coś, czego nie rozumie ktokolwiek znający podstawy jQuery/javascript. Linijka event.preventDefault(); blokuje domyślne działanie które powinno odbyć się po kliknięciu w któryś z elementów wskazanych (po przecinku) linijkę wyżej.

Warto zwrócić na linijkę pierwszą. Jeśli ktoś do tej pory nie pisał żadnych skryptów w jQuery dla WordPressa może się zdziwić. Wszystkie tutoriale bowiem mówią, że jQuery zaczynamy od:

$(document).ready(function() {

Taki zapis jednak sprawi, że nasz skrypt „pogryzie się” z innymi skryptami jQuery w naszej stronie (a tych w WordPressie jest cała masa). Dlatego wyżej wspomnianą linijkę należy zapisać inaczej. Wtedy wszystko działa jak należy.

…i to już konieć naszego pliku JS. Zdefiniujmy teraz:

Zawartość głównego pliku wtyczki

Główny plik wtyczki – aby była ona rozpoznawana przez WordPressa i umieszczona na liści wtyczek – musi zaczynać się od specjalnego nagłówka. Poniżej jest jego bardzo skrócona wersja, ograniczająca się do nazwy wtyczki:

<?php
/*
Plugin Name: Touchscreen Dashboard Fixes
*/

teraz tworzymy główną funkcję wtyczki, która sprawdzi czy korzystamy właśnie z urządzenia z dotykowym ekranem, a następnie zarejestruje nasze pliki stworzone powyżej i umieści je w nagłówku lub stopce Kokpitu. Cały kod wygląda następująco:

function tch_admin_fix() {
if(tch_is_touchscreen())
{
 wp_register_style( 'tchStylesheet', plugins_url('style.css', __FILE__) );
 wp_enqueue_style( 'tchStylesheet');
 wp_register_script( 'tchScript', plugins_url('script.js', __FILE__), array('jquery'));
 wp_enqueue_script( 'tchScript' );
}
}

W drugiej linijce sprawdzamy czy jest to urządzenie dotykowe (o tym za chwilę więcej), a następnie:

  1. rejestrujemy plik stylów za pomocą funkcji wp_register_style która w pierwszym parametrze przyjmuje nazwę pod jaką chcemy zarejestrować nasz styl, a w drugim ścieżkę do pliku stylów (pomogłem tu sobie funkcją plugins_url)
  2. mówimy wordpressowi aby nasz styl zakolejkował do dołączenia do dokumentu, jak dokładnie się to odbywa, nie musimy się specjalnie przejmować. Dba o to funkcja wp_enqueue_style, która jako parametr przyjmuej nazwę naszego zarejestrowanego stylu.
  3. rejestrujemy nasz skrypt. Używamy tutaj funkcji wp_register_script która jest bardzo podobna do funkcji rejestrującej style. Jedyna różnica to przekazanie w trzecim parametrze tablicy zawierającej nazwy innych zarejestrowanych skryptów od których nasz skrypt zależy. Jako, że pisząc kod scipt.js użyliśmy biblioteki jQuery, to jest właśnie sposób aby zagwarantować, że owa biblioteka zostanie na pewno załadowana.
  4. i kolejkujemy skrypt podobnie jak kolejkowaliśmy style (jedyna różnica to ostatni człon nazwy użytej funkcji)

Skąd w drugiej linijce znalazła się funkcja tch_is_touchscreen? WordPress ma wiele wbudowanych funkcji do rozpoznawania przeglądarki (np is_IE() sprawdza czy korzystamy z Internet Explorera), nie ma jednak (a przynajmniej nie znalazłem) funkcji do wykrywania przeglądarek w urządzeniach z dotykowym ekranem. Sam ją więc napisałem (przy czym 99% jej kodu pobrałem stąd) i umieściłem w tym samym pliku. Oto kod:

function tch_is_touchscreen() {
$useragent=$_SERVER['HTTP_USER_AGENT'];
if ( preg_match('/android|avantgo|bada\/|blackberry|blazer'.
'|compal|elaine|fennec|hiptop|iemobile|ip(ad|hone|od)|iris'.
'|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm'.
'( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|'.
'up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xi'.
'ino|playbook|silk/i',$useragent)||preg_match('/1207|6310|'.
'6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)'.
'|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|'.
'as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|r'.
'd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\'.
'-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|d'.
'c\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|u'.
'l)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u'.
'|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\'.
'-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|'.
'p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro'.
'|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|ji'.
'gs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)'.
'|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m'.
'3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi'.
'(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p'.
'1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7('.
'0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|'.
'op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c'.
'))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g'.
'|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks'.
'|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|'.
'p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)'.
'|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v'.
'\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|t'.
'dg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-'.
'9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3'.
']|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w'.
'3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g'.
')|yas\-|your|zeto|zte\-/i',substr($useragent,0,4)) )
return true;
return false;
}

(powyższy kod lepiej otwórzcie w osobnym okienku)

Uwaga odnośnie nazwy funkcji: pierwotnie nazwałem ją is_touchscreen() jednak podejrzewam, że prędzej czy później funkcja o tej nazwie może znaleźć się w WordPressie. Dlatego, aby nie było awarii z powodu próby przeciążenia funkcji (php nie pozwala na istnienie dwóch funkcji z tą samą nazwą – pomijam tu nowość w postaci namespaces), dodałem do jej nazwy przedrostek tch_.

Nasza główna funkcja tch_admin_fix() musi jeszcze zostać uruchomiona w odpowiednim momencie. Zapewne wiecie z poprzednich części kursu, że w takich wypadkach korzystamy tu z mechanizmu haczenia odpowiednich akcji i filtrów. W tym wypadku – jako, że chcemy aby nasze style i skrypty zostały załadowane w czasie działania Kokpitu – podhaczamy to pod akcję admin_init:

add_action( 'admin_init', 'tch_admin_fix' );

I to już koniec naszego pliku .php.

Podsumowanie

Opisaną wyżej wtyczkę zapisujemy i aktywujemy w Kokpit > Wtyczki. Od tej pory korzystanie z Kokpitu na tabletach i telefonach powinno być o wiele prostsze. Przynajmniej na mojej Nokii N8 z przeglądarką Opera Mobile i na tablecie Blackberry Playbook wszystko działa jak należy.

Powyższe możecie potraktować jako bazę do swoich dalszych zmian. Zastanówcie się gdzie jeszcze – niekoniecznie w Kokpicie ale i na głównej stronie bloga – korzystacie z możliwości najechania na coś myszką i w analogiczny sposób sprawcie by na ekranach dotykowych zamiast najechać myszą, trzeba było kliknąć.


Opublikowano

w

przez

Komentarze

4 odpowiedzi na „Tworzymy wtyczkę poprawiającą funkcjonowanie Kokpitu na ekranach dotykowych”

  1. Awatar tomek
    tomek

    Jest funkcja do wykrywania urządzeń mobilnych is_iphone(), działa na androidzie i na iphonie :), w codexie nie ma nic a w necie trudno znaleźć jakiś opis, jedynie co znalazłem to ten wpis
    http://androidandme.com/2010/02/news/tutorial-making-your-wordpress-blog-android-and-iphone-friendly/

    1. Awatar Konrad Karpieszuk

      na pewno dziala na androidzie? :) bo funkcja jest dosc prosta: sprawdza czy w UA jest 'safari’ oraz 'mobile’. android chyba tego nie ma :)

      funkcja (a wlasciwie zmienna) jest w wp-includes/vars.php

  2. Awatar wikiyu

    a przypadkiem akcja :hover nie jest wywoływana jeśli dłużej przytrzymamy paluchem na danym elemencie?
    najeżdżam paluchem, trzymam trzymam puszczam i widzę rozwinięte menu…

    1. Awatar Konrad Karpieszuk

      wlasnie sprawdzilem. dla lewego i gornego menu to dziala, jednak dla tych 'szybkich linkow’ nie. a glownie o nie mi chodzilo gdy robilem wtyczke (i za jednym zamachem „naprawilem” tez menu przy krawedziach). gdy trzymam dluzej palec w okolicach szybkich linkow to jak puszcze i tak znikaja. proba klikniecia w link drugim palcem podczas gdy pierwszym nadal trzymam nie dziala