WordPress - motywy, wtyczki, informacje, programowanie

Motywy potomne

Motywy potomne (child themes) – bezpieczne modyfikacje motywu

W tym poradniku pokażemy, co to są motywy potomne (ang: child themes), jak je tworzyć i dzięki nim modyfikować gotowe motywy kupione lub pobrane za darmo z sieci. Przy okazji (w ramach przykładów) dowiesz się jak dodać do każdego artykułu przycisk Google+1 oraz jak używać Google Web Fonts.

Chociaż na rynku dostępnych jest bardzo wiele gotowych motywów, zarówno tych darmowych jak i płatnych, bardzo często zaawansowani użytkownicy chcą dokonać w nich jakichś modyfikacji. Czasem chodzi o drobne zmiany, dodanie nowych styli, zmianę kolorów, ale czasem wymagane zmiany są poważniejsze, dotyczą nowych funkcjonalności.

Modyfikacja oryginalnego motywu nie jest dobrym pomysłem. Większość lepszych motywów jest regularnie aktualizowana przez autorów, chociażby po to, żeby wykorzystać możliwości nowych wersji WordPressa, lub załatać jakieś błędy i luki w bezpieczeństwie. Jeżeli nowa wersja będzie zawierała zmiany w plikach, które my zmodyfikujemy, nasze dodatki znikną, bo pliki zostaną zastąpione przez te pochodzące z nowszej wersji.

Aby uniknąć tego rodzaju problemów, a jednocześnie nie ograniczać użytkowników i umożliwić im bezpieczne rozwijanie motywów, powstał mechanizm motywów potomnych (child themes). Jest on prawie zawsze wystarczający do takich celów. Jeśli oryginalny motyw został dobrze napisany, zgodnie ze sztuką i zaleceniami WordPress Codex, nie powinniśmy napotkać większych kłopotów.

Co ważne, wykorzystanie motywów potomnych nie wymaga jakiejś wielkiej wiedzy informatycznej, wystarczy pobieżna znajomość PHP i CSS, chyba że zmiany których chcemy dokonać są bardzo skomplikowane. Jeśli zmiany są proste, może je wykonać ogólnie sprawny komputerowo amator.

Przed lektura tej notki warto przeczytać tekst: Szablony stron w WordPressie – z czego składa się każdy motyw.

Co to jest motyw potomny i jak go założyć. Plik style.css

Idea i logika motywu potomnego jest bardzo prosta. Polega on ana tym, że zakładamy nowy motyw jednocześnie informując WordPressa, że jeśli nie znajdzie w jego obrębie szablonu do wyświetlenia jakiejś strony, powinien skorzystać z motywu nadrzędnego, którego nasz motyw jest potomkiem. To trochę tak, jakbyśmy dziedziczyli klasę w PHP, czy w jakimś innym obiektowym języku programowania.

Na potrzeby tego poradnika załóżmy, że będziemy chcieli zbudować motyw potomny do motywu TwentyEleven, który jest domyślnym motywem obecnej instalacji WordPressa (3.3.2).  W motywie potomnym, który nazwiemy Something Better zmienimy podstawową czcionkę i sprawimy, żeby pod każdym postem  pojawiał się przycisk Google +1.

Zacznijmy od tego, że w kartotece /wp-content/themes/ założymy kartotekę something-better. W kartotece założymy plik style.css o następującej zawartości:

/*
Theme Name: Something Better
Template: twentyeleven
*/

@import url("../twentyeleven/style.css");

Plik ten ma dla WordPressa specjalne znaczenie. Na górze pliku znajduje się blok komentarza, w którym zawarte są dwie informacje. Linia:

Theme Name: Something Better

mówi WordPressowi, że własnie utworzylismy motyw o nazwie Something Better, a linia

Template: twentyeleven

określa, że nasz nowy motyw dziedziczy po motywie TwentyEleven. Przy czym podajemy tutaj nie nazwę motywu, po którym dziedziczymy, tylko nazwę katalogu, w którym znajdują się pliki tego motywu.

Kolejna linia

@import url("../twentyeleven/style.css");

oznacza, że WordPress ma załadować  (w tym miejscu) arkusz styli z motywu nadrzędnego.

W tym momencie utworzyliśmy już motyw potomny i możemy się na niego przełączyć, korzystając ze strony administracyjnej Wygląd/Motywy. Gdy to zrobimy możemy zauważyć, że wszystko wygląda dokładnie tak samo jak w oryginalnym motywie TwentyEleven. Aby zobaczyć, jak ważna jest komenda @import z pliku style.css, możemy ją na chwile usunąć, lub zakomentować. Zobaczymy wtedy, że nasz serwis rozleciał się zupełnie  – po prostu nie ma żadnych styli.

Przywracamy linię z komenda @import i poniżej dodajemy modyfikację czcionki, której chcieliśmy dokonać. Załóżmy, że chcemy zmienić czcionkę naszego serwisu na jedną z dostępnych w Google WebFonts. Niech będzie to Droid Sans.

/*
Theme Name: Something Better
Template: twentyeleven
*/

@import url("../twentyeleven/style.css");
@import url(http://fonts.googleapis.com/css?family=Droid+Sans:regular,bold|Droid+Serif:regular,italic,bold,bolditalic&subset=latin);

body, input, textarea {
 font-family: 'Droid Sans', Arial, Helvetica, sans-serif;
}

Przy okazji, jeśli dotąd tego nie wiedziałeś, nauczyłeś się korzystać z Web Fonts. Czcionki możesz osadzać na kilka sposobów, zarówno z serwisu Google (Google Web Fonts) jak i z własnej strony. Możłiwość ta jest w tej chwili obsługiwana przez wszystkie nowoczesne przeglądarki.

Dodatkowe funkcjonalności motywu – plik functions.php

Zwykle tworząc motyw potomny chcemy zrobić coś więcej niż tylko zmienić style i w takim wypadku najczęściej będziemy chcieli dodać jakieś dodatkowe funkcje. Można to zrobić tworząc własną wersję pliku functions.php. Plik o tej nazwie występuje w większości motywów i WordPress tratuje go specjalnie, inaczej niż plik style.css. Jak zauważyłeś, plik style.css, ładowany jest z Twojego, potomnego motywu, a Ty sam musisz zatroszczyć się, żeby wczytać przez @import arkusz lub arkusze styli z motywu nadrzędnego. Jeśli tego nie zrobisz, serwis będzie nieostylowany. W wypadku pliku functions.php najpierw ładowany jest Twój plik , a po nim automatycznie plik z motywu nadrzędnego. W ten sposób działają wszystkie funkcje motywu nadrzędnego, ale mogą być przykryte (zamienione) przez te, które znajda się w motywie potomnym, pod warunkiem, że twórca motywu nadrzędnego użył konstrukcji.

if (!function_exists('add_decoration')) {
  function add_decoration() {
    // do something
  }
}

Jeśli teraz w swoim pliku functions.php napiszesz funkcję add_decoration, zastąpi ona analogiczną funkcje  motywu nadrzędnego.

Najczęściej jednak nie chodzi o zmianę działania funkcji, a raczej o dokładanie nowych funkcjonalności. Jeśli utworzysz w kartotece swojego szablonu potomnego plik functions.php o poniższej zawartości, pod każdym  postem na twoim blogu pojawi się przycisk Google +1.

<?php

function disp_gplus($content){
  global $post;
  $post_link = get_permalink($post->ID);
  $epost_link = urlencode($post_link);
  $gplus_button =
    '<div class="g-plusone" data-size="medium" data-href="'.
    $epost_link.'"></div>';
  return $content . $gplus_button;
}

function gplus_js() {
?>
<!-- Script for Google +1 button -->
<script type="text/javascript">
  window.___gcfg = {lang: 'pl'};
  (function() {
    var po = document.createElement('script');
    po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(po, s);
  })();
</script>
<?php
}

add_action( 'wp_head', 'gplus_js' );
add_filter('the_content', 'disp_gplus',1);

?>

Funkcja gplus_js wypisuje skrypt, który jest niezbędny aby przycisk Google +1 zadziałał. Przy pomocy

add_action( 'wp_head', 'gplus_js' );

„podpinamy” funkcję gplus_js do miejsca w kodzie WordPressa, gdzie wypisywany jest nagłówek <head>...</head> wszystkich stron serwisu, ponieważ dobrze jest, aby skrypt ładował się właśnie w tym miejscu.

Funkcja disp_gplus „podpięta” jest przy pomocy

add_filter('the_content', 'disp_gplus',1);

jako filter, przez który przepuszczana jest treść każdego postu przed wypisaniem na stronie. Funkcja dokleja do postu fragment HTML w wyniku którego pod postem pojawia się prawidłowo umieszczony przycisk Google +1.

Obydwa mechanizmy – add_filter i add_action pozwalają podpinać swoje funkcje na tak zwane haki WordPressa. Umożliwia to zmianę istniejących i dodawanie nowych funkcjonalności do serwisu (w pliku functions.php, wtyczce lub dowolnym innym pliku php) bez ingerencji w kod WordPressa. Mechanimy te dokładnie omawiamy w artykułach Wprowadzenie do akcji i filtrów oraz Akcje i filtry od środka.

Szablony stron w motywie potomnym

Oprócz plików style.css i functions.css w kartotece motywu znajdują się szablony stron. na przykład pliki: single.php albo tag.php oraz szablony elementów stron np. header.php albo sidebar.php. Bardzo często autorzy motywów potomnych chcą zmienić jeden z tych szablonów.

Aby zmienić jeden z szablonów, wystarczy powołać plik o tej samej nazwie w kartotece motywu potomnego. Jeśli WordPress go napotka, użyje go zamiast szablonu z motywu nadrzędnego. Najczęściej rozsądne będzie skopiowanie oryginalnego szablonu do motywu potomnego i zmienianie go tutaj, bez naruszania wersji oryginalnej.

W wypadku plików takich jak header.php czy sidebar.php, czyli takich, które są częściami szablonów, działa to identycznie jeśli tylko autor motywu nadrzędnego, z którego korzystamy użył ich właściwie. Plików tych nigdy nie wolno ładować instrukcją require albo require_once języka PHP, zamiast tego należy użyć odpowiednio funkcji get_header, get_siedebar, itd.  Dołączają one wspomniane pliki najpierw z kartoteki motywu potomnego, a dopiero później z motywu nadrzędnego. Gdyby użyć komendy require lub require_once, ścieżka do pliku byłaby wpisana na stałe i zawsze byłby ładowany plik z motywu nadrzędnego.

Jeśli motyw, z którego dziedziczymy jest rozbudowany, np. szablony stron są różnorodne i podzielone na wiele plików, które są dołączane do głównych szablonów (podobnie jak w wypadku header.php czy sidebar.php), autorzy takich  motywów często dostarczają dodatkowych funkcji podobnych w swojej logice do get_header czy get_sidebar, abyśmy mogli łatwo nadpisać poszczególne fragmenty szablonów. Jeśli tworzymy motyw potomny dobrym zwyczajem jest zaglądnąć do dokumentacji motywu z którego dziedziczymy,  bardzo często znajdziemy tam instrukcje o tym jak tworzyć motywy potomne, spis użytecznych funkcji, jakieś uwagi związane z kompatybilnością i możliwymi problemami.

Przy pomocy motywu potomnego możemy też dodać nowe szablony i WordPress skorzysta nich właściwie. Na przykład motyw nadrzędny może zawierać tylko szablon archive.php,  który odpowiada za wyświetalanie wszystkich zbiorczych list postów w serwisie – np. listy postów w danej kategorii, z danym tagiem, listy postów danego autora, listy postów z danej daty itd. Możemy jednak utworzyć szablon tag.php, którego WordPress używa domyślnie aby wyświetlić archiwum postów dla danego taga. Teraz archiwa wszystkich tagów będa wyświetlane przez szablon tag.php a wszystkie pozostałe listy postów w dalszym ciągu szablonem archive.php.

Możemy pójść jeszcze dalej i stworzyć szablon tag-12.php. WordPress użyje go jeśli będzie miał wyświetlić archiwum taga o ID=12, pozostałe tagi wyświetli szablonem tag.php, a resztę archiwów szablonem archive.php.

Inne pliki w motywach potomnych

Oprócz tego, w kartotece z motywem potomnym mogą się znajdować dowolne inne pliki, z których możemy korzystać – jakieś dodatkowe piki PHP, obrazki, inne arkusze styli, pliki mp3, itp. Nie ma tu ograniczeń z wyjatkiem jednego – uważaj, aby pliki .php nie pokrywały się ze standardowymi nazwami szablonów WordPressa albo z nazwami, które ustandardyzował autor motywu nadrzędnego. Najrozsądniej jest stworzyć kartotekę o nazwie, która nie występuje w motywie nadrzędnym (np. child-inc) i wszelkie pliki PHP umieszczać tam.

Aby użyć jakiegoś innego pliku z motywu potomnego należy się posługiwać funkcją get_stylesheet_directory, która zwraca kartotekę, w której znajduje się głowny arkusz styli dla danego motywu (style.css) a zatem kartotekę motywu potomnego. Np.:

require_once( get_stylesheet_directory(). '/my_decorations.php' );

Jeśli zamiast kartoteki potrzebujemy URI (np. po to, żeby odwołać się do obrazka) trzeba użyć funkcji get_stylesheet_directory_uri.

Analogicznie, aby użyć w motywie potomnym jakiegoś pliku z szablonu nadrzędnego, możesz użyć funkcji get_template_directory i get_template_directory_uri.

Uwagi dodatkowe:

  1. Nie da się zrobić motywu potomnego do motywu potomnego. Dlatego jeśli korzystasz z motywu, który już jest motywem potomnym, będziesz musiał go modyfikować żywcem, ze wszystkimi tego konsekwencjami.
  2. Motyw TwentyEleven zawiera alteranatywny arkusz styli (dark.css) dla ciemnej wersji serwisu. Znajduje się on w kartotece /wp-coontent/twentyeleven/colors/. Niestety nie ma prostej i eleganckiej metody aby zmodyfikować jego style, ponieważ jest ładowany po arkuszu style.css i WordPress w żaden sposób nam tu nie pomaga. Najłatwiejszym (choć niezbyt eleganckim) rozwiązaniem jest nadpisanie odpowiednich styli w arkuszu style.css z użyciem !important. Dla większości zastosowań to powinno wystarczyć.
  3. Jeżeli twoja strona ma obsługiwać języki czytane od prawej do lewej (np. hebrajski) i motyw z którego dziedziczysz zawiera plik rtl.css (czyli arkusz styli dla tych języków), możesz założyć w swoim motywie potomnym taki plik i zaimportować do niego rtl.css z motywu nadrzędnego – dokładnie tak samo jak to  robiliśmy w wypadku pliku style.css.