Niedawno zacząłem tworzyć stronę mojego duszpasterstwa. Stwierdziłem, że nie opłaca mi się programować czegoś zupełnie nowego, bo przecież ma być to strona w miarę prosta, a jedynymi ciekawostkami będzie galeria, księga gości i kalendarz wydarzeń - z tych właśnie powodów wybrałem mechanizm Wordpressa (alternatywą było użycie engine’u spiffy.content, bądź kanapy.org). Znalazłem odpowiednie narzędzie do tworzenia galerii, księgę gości chwilowo oparłem o zwykłe komentarze (co jest błędem, gdyż wygląda przez to bardzo “forumowo”). Nie mogłem jednak wygooglać żadnego pluginu, który tworzyłby kalendarz wydarzeń. Zapadła więc szybka decyzja - zrobię własny.
Podjąłem tą decyzję w chwili, gdy nie miałem Internetu w mieszkaniu, a do mojej uczelni iść mi się nie chciało (bo duszno w pracowniach). Mając pod ręką jedynie prostą wersję Wordpressa 2.0 + 3 podstawowe pluginy zabrałem się za robotę. Postanowiłem stworzyć najpierw panel administracyjny. Nie wiedziałem, jak stworzyć instalator budujący bazę danych, dlatego napisałem go w czystym SQLu i uruchomiłem z konsoli - rozwiązanie brzydkie, ale w warunkach nieInternetowych optymalne. Potem wziąłem się za lekturę pluginu Akismet, bodajże służącego do ochrony antyspamowej. No i dowiedziałem się, iż:
Warto stworzyć funkcję inicjalizującą menu administracyjne. Standardem jest chyba nazywanie jej w formie: ‘nazwapluginu_init’, choć tak naprawdę jest to dowolne, gdyż i tak trzeba poinformować Wordpress’a o tym, jaka funkcja odpowiada za utworzenie menu. Służy do tego funkcja add_action, której pierwszym parametrem jest nazwa akcji (przy dodawaniu inicjalizatora menu jest to ‘admin_menu’), a drugim nazwa funkcji odpowiedzialnej za daną akcję w pluginie (np. ‘ycalendar_init’). U mnie zatem wygląda to tak:
add_action('admin_menu', 'ycalendar_init');
Oczywiście warto by było najpierw wcześniej napisać ciało tej funkcji, której nie aplikujemy żadnych argumentów. W ciele tej funkcji budujemy nasze menu administracyjne, tj. tworzymy zakładkę yCalendar wraz z podzakładkami: dodaj wydarzenie i wyświetl listę wydarzeń. Moja funkcja ycalendar_init wygląda tak:
function ycalendar_init() {
if ( function_exists('add_menu_page') && function_exists('add_submenu_page') ) {
add_menu_page(__('yCalendar'), __('yCalendar'), 'edit_posts', __FILE__, 'ycalendar_add_event');
add_submenu_page('ycalendar/ycalendar.php', __('Dodaj zdarzenie'), __('Dodaj zdarzenie'), 6, __FILE__, 'ycalendar_add_event');
add_submenu_page('ycalendar/ycalendar.php', __('Przejrzyj zdarzenia'), __('Przejrzyj zdarzenia'), 6, 'ycalendar/admin_view_events.php', 'ycalendar_view_events');
}
}
Jak łatwo się domyślić add_menu_page tworzy nam zakładkę yCalendar (dlaczego są dwa takie same argumenty na początku to nie pytajcie, bo nie wiem ;)), którą obsługiwać mogą ludzie z uprawnieniami ‘edit_posts’, czyli bodajże 6 (później używam wartości liczbowych), następnie podajemy skrypt odpowiedzialny za obsługę tej zakładki oraz akcję w tej zakładce. Natomiast add_submenu_page tworzy podzakładki. Parametry: skrypt-matka, nazwa zakładki (patrz wyżej), uprawnienia, skrypt i akcja. W drugim wywołaniu add_submenu_page jako skrypt obsługujący wpisany jest admin_view_events.php (ścieżkowanie jest od katalogu plugins), jednak jest to drobne oszustwo, które pomoże w przetwarzaniu formularzy - tak naprawdę za wszystko odpowiedzialny jest jeden plik.
Skoro utworzyliśmy menu, warto by było dodać pierwszą stronę administracji naszego pluginu. Wg inicjalizatora za stronę odpowiedzialna jest akcja ycalendar_add_event, zatem tworzymy funkcję ycalendar_add_event. Nie będę tu przytaczał treści funkcji, szczególnie, że nie ma tak żadnych ciekawostek technologicznych. Jedyne o czym warto pamiętać, to że administracja Wordpressowa ma własny styl i najlepiej by było się do niego dostosować, tj. komunikaty wyświetlać w divie o id message i klasie updated fade, treści w divie z klasą wrap (choć to pewnie niekoniecznie), a tytuły akcji jako h2. Do tego warto przejrzeć pod względem kodu chociaż jedną stronę z formularzem i jedną z wylistowaniem. Prawie bym zapomniał - do obsługi bazy danych służy obiekt o nazwie wpdb - klasa umieszczona jest w pliku wp-includes/wp-db.php. Z tego co zdążyłem zauważyć większość funkcji używa jej poprzez instrukcję global, a nie przez zmienną _GLOBAL.
Większość formularzy, jeśli nie wszystkie, jako adres skryptu przetwarzającego dane wstawia samego siebie. Warto się dostosować do tego zwyczaju, bo czyni to kod bardziej czytelnym dla innych osób programujących pluginy dla Wordpress, a pewnie i oszczędza linii kodu.
Na samym końcu pozostaje nam stworzyć skrypt do wyświetlania kalendarza. Właściwie to ciekawszego zagadnienia w tym nie ma - ja co prawda spędziłem nad tym sporo czasu, ale tylko i wyłącznie dlatego, że chciałem wygenerować wszystkie pola kalendarza jak najładniejszym kodem. Niestety wyszło wszystko jak zwykle - niezbyt ładnie, choć mam nadzieję czytelnie.
Na koniec chciałbym zachęcić do modyfikowania, ew. rozwijania tego skryptu według własnych potrzeb, oraz, na czym bardziej mi zależy, do komentowania mojego sposobu wykonania tegoż pluginu - co warto zmienić, co się mija z celem. Całość skryptu dostępna jest na licencji CC by-sa 2.5
Ściągnij ycalendar - plugin dla Wordpressa



[…] Pisałem już raz na ten temat, jednak wtedy moje podejście do tworzenia pluginu wordpressowego było ekstremalne - jako źródło informacji, jak tworzyć wordpressowe pluginy, brałem źródła standardowych pluginów. Biorąc się za pisanie yGigs, czyli naszego działu praca, stwierdziłem, że skoro już mam swobodny dostęp do internetu, to najpierw poczytam dokumentację, a dopiero potem wezmę się za robotę. Tak też zrobiłem - zacząłem od pobieżnej lektury strony Writing a Plugin. Znalazłem tam informacje, których już wcześniej się domyślałem - istnieje API wordpressowe, o całkiem sporych możliwościach, którego należy używać przy pisaniu pluginów. Na początek warto zapoznać się z możliwościami klasy WPDB odpowiedzialnej za połączenie z bazą danych. Obiekt odpowiedzialny za bazę danych jest zdefiniowany globalnie - jest to zmienna $wpdb. Normą w pisaniu aplikacji z Wordpress jest używanie zmiennych globalnych wypisanych na początku przy użyciu instrukcji global. Obiekt ten posiada następujące metody (piszę o tych rzeczywiście istotnych): […]