Joomla@jogger.pl

 

14

lutego

2010

Moduły bez użycia pozycji modułów

Joomla! dzięki swojej elastyce nie ogranicza nas do korzystania wyłącznie z pozycji modułów dostępnych w szablonie - czasem pojawia się potrzeba umieszczenia modułu bezpośrednio w kodzie szablonu.

Zaplecze teoretyczne

Zanim przystąpimy do praktycznej części, przedstawię odrobinę teorii wymaganej do zrozumienia kodu, który stworzymy.

Joomla! pozwala tworzyć nam różne konfiguracje dla zainstalowanych modułów - przykładowo dzięki temu możemy utworzyć kilka menu dla naszej strony na bazie standardowego modułu mod_mainmenu. Każda taka instancja danego modułu posiada swoją nazwę - tytuł. Standardowo daną instancję modułu przypisujemy do jednej z pozycji i wybranych podstron na których dany moduł ma się wyświetlać. Możemy też określić poziom dostępności modułu dla użytkowników witryny.

W wypadku gdy tworzymy szablony i umieszczamy w nim pozycje modułów, możemy określić stylowanie modułów na danej pozycji - np. xhtml, który tworzy dodatkowe kontenery wokół standardowej zawartości modułu.

W naszych działaniach skupimy się na klasie JModuleHelper dostępnej we frameworku Joomla! - oferuje ona kilka metod, które będą nam potrzebne do osiągnięcia zamierzonego efektu - getModule oraz renderModule. Pierwsza z nich służy do pobrania obiektu modułu na bazie nazwy i (opcjonalnie) tytułu, natomiast druga służy do wygenerowania kodu modułu na bazie dodatkowych parametrów.

Zaletą takiego rozwiązania jest to, że tak osadzony moduł pojawi się na naszej stronie zawsze (na każdej podstronie).

Wariant 1

W tym wariancie stworzymy kod, który wygeneruje nam kod modułu bez odwoływania się do bazy danych. Wadą tego rozwiązania jest to, że aby zmienić jakiekolwiek ustawienia modułu musimy zmieniać je w pliku - wariant drugi ten problem zniweluje.

Sam kod wczytujący wybrany moduł jak widać nie jest zbyt długi:

<?php

    $module = JModuleHelper::getModule( 'mod_mainmenu' ); // 1
    $module->params = 'menuname=mainmenu'; // 2
    $options = array( 'style' => 'none' ); // 3
    echo JModuleHelper::renderModule( $module, $options ); // 4

?>

W pierwszej linii wczytujemy obiekt standardowego modułu mod_mainmenu z wykorzystaniem klasy JModuleHelper. Warto tu wspomnieć, że gdyby klasa ta była z jakiegoś powodu niedostępna to należy na początku naszego kodu dodać linijkę:

jimport( 'joomla.application.module.helper' );

która wczyta nam klasę JModuleHelper.

W drugiej linijce określamy parametry naszego modułu - jest to ciąg par NAZWA_PARAMETRU=WARTOŚĆ_PARAMETRU rozdzielonych znakiem nowej linii. Gdybyśmy chcieli ustawić kilka parametrów wystarczy napisać:

parametr1=wartosc1\nparametr2=wartosc2\nparametr3=wartosc3

Wszystkie nieuwzględnione parametry przyjmą wartości domyślne.

Oczywiście nazwy parametrów i format wartości musimy wydedukować na bazie opcji modułu w panelu administracyjnym (nazwy pól z opcjami to nazwy parametrów przechowywanych w bazie danych) lub z pliku instalacyjnego XML danego modułu.

Jeżeli mamy w planach przeprowadzać bardziej wyszukane operacje na parametrach - warto zapoznać się z klasą JParameter - w jednym z kolejnych wpisów poświęcę jej więcej uwagi.

Trzecia linijka to tablica asocjacyjna zawierająca dodatkowe opcje wykorzystywane podczas generowania kodu modułu. Każdej pozycji modułów można przypisać oddzielny sposób generowania kodu modułów - możemy przykładowo dodać dodatkowe kontenery wokół treści naszego modułu. W naszym wypadku atrybut style powoduje, że kod modułu zostanie wygenerowany bez żadnej dodatkowej "otoczki". Możemy tam także ustawić jeden ze standardowych styli chrome - ich lista dostępna jest tutaj.

Jeżeli w pliku modules.php w katalogu html szablonu zdefiniujemy własne style chrome, wtedy możemy dodać dodatkowe parametry wykorzystywane przez te style - ale o tym w jednym z kolejnych wpisów, bo sam temat jest dość długi. Wracając do naszego kodu - pora na ostatnią linijkę - wywołujemy w niej statyczną metodę klasy JModuleHelper - renderModule, jako argumenty przyjmującą obiekt modułu oraz jego dodatkowe atrybuty dotyczące sposobu generowania kodu. Metoda ta zwraca wygenerowany kod modułu, który dzięki funkcji echo wyświetlamy na naszej stronie.

Wariant 2

W tym wypadku napiszemy kod, który pozwoli nam wygenerować kod modułu, którym możemy zarządzać z poziomu panelu administracyjnego - ów moduł będzie po prostu nieopublikowany na stronie (poza miejscem gdzie wstawimy nasz kod).

<?php

    $db =& JFactory::getDBO(); // 1
    $db->setQuery('SELECT title, module, params FROM #__modules WHERE id = 1'); // 2
    $item = $db->loadRow(); // 3
    $module = JModuleHelper::getModule( $item[1], $item[0] ); // 4
    $module->params = $item[2]; // 5
    $options = array( 'style' => 'none' ); // 6
    echo JModuleHelper::renderModule( $module, $options ); // 7

?>

Dwie ważne kwestie odnośnie powyższego kodu:

  1. Celem skrócenia kodu przyjmujemy, że rekord o danym ID istnieje w bazie danych - jeżeli nie mamy takiej pewności to aby uniknąć problemów warto sprawdzić po wykonaniu zapytania ile rekordów zwróciło zapytanie
  2. W ramach zgodności z PHP 4 w pierwszej linijce mamy zastosowane przypisywanie przez referencję. Jeżeli działamy w środowisku PHP 5 możemy (a nawet wypada) zmienić tą linijkę na:

    $db = JFactory::getDBO();
    

    ponieważ w PHP 5 przypisywanie obiektów odpowiada przypisywaniu obiektów przez referencję znanemu z PHP 4. W niektórych wypadkach ta zmiana będzie wręcz konieczna, jeżeli mamy ustawiony odpowiednio wysoki poziom ostrzeżeń w pliku php.ini i chcemy uniknąć komunikatów o używaniu przestarzałych operatorów.

Przejdźmy teraz do analizy kodu - na początku w pierwszej linii tworzymy referencję do obiektu klasy JDatabase (a dokładniej do jednej z klas dziedziczących po tej klasie - najczęściej JDatabaseMysql).

Następnie w drugiej linii definiujemy kod zapytania do wykonania - w naszym wypadku pobierzemy zawartość kolumn title, module i params dla rekordu posiadającego id równe 1 w tabeli jos_modules (Prefiks "#__" jest automatycznie zamieniany na domyślnie ustawiony prefiks tabeli w bazie danych podany podczas instalacji).

W kolejnej linii (3) wczytujemy z bazy danych pierwszy rezultat naszego zapytania (tak jak wspominałem tu może wystąpić potrzeba pewnej walidacji ilości zwróconych rekordów pominięta ze względu na uproszczenie skryptu).

W kolejnej linii wczytujemy obiekt naszego modułu - podobnie jak w poprzednim wariancie, tym razem jednak odwołujemy się do tablicy $item, która przechowuje zawartość kolumn wczytanego rekordu z bazy danych. Przy okazji ustawiamy też opcjonalny parametr $title metody getModule, związany z tytułem modułu.

W piątej linii ustawiamy parametry modułu na bazie wczytanych parametrów z bazy danych (tu mamy spore pole do popisu - więcej w "Inne ciekawe możliwości").

I na koniec dwie ostatnie linijki (6 i 7) - mamy tutaj to samo co mieliśmy w wariancie pierwszym więc nie ma sensu powielać opisu.

Teraz wystarczy stworzyć potrzebny nam moduł, skonfigurować go i nie publikować na naszej stronie (no chyba, że chcemy wyświetlić ten moduł dwa razy).

Inne ciekawe możliwości

W tym miejscu chciałbym zwrócić uwagę na dodatkowe możliwości, które mogą być wskazówką dla kolejnych ciekawych rozwiązań, ale wymagają już samodzielnego zgłębienia niektórych tematów.

  1. Warto przede wszystkim zauważyć, że powyższe przykłady kodu dają nam ciekawą możliwość generowania kodu modułów w innym module - różnego rodzaju moduły z zakładkami (tabami) wykorzystują tą możliwość do grupowania modułów.
  2. Możliwość określenia parametrów modułu na poziomie kodu jest niezwykle przydatna z tego względu, że możemy modyfikować pewne wybrane parametry, a co za tym idzie możemy przykładowo zapewnić możliwość dostosowania opcji modułu dla konkretnego użytkownika - możemy na przykład zdecydować na podstawie plików cookies jaka kategoria artykułów zostanie użyta do wygenerowania treści zawartej w module.
  3. Nie musimy wygenerowanego kodu modułu od razu wypisywać - możemy przypisać go do zmiennej i przed wyświetleniem zmodyfikować w żądany sposób np. z użyciem wyrażeń regularnych.
  4. Warto poznać możliwości klasy JParameter, która jest używana do analizy i modyfikowania parametrów wszelkiego rodzaju rozszerzeń dla Joomla!.
  5. Kod generujący zawartość modułu możemy oczywiście otoczyć dodatkowym kodem w PHP, który ograniczy wyświetlanie modułu - oczywiście sam kod z ograniczeniami zależy już od indywidualnych potrzeb - może to być ograniczenie do wyświetlania na stronach z określonym Itemid w adresie lub wyświetlanie modułu tylko dla określonych użytkowników naszej witryny. Możliwości są naprawdę duże i wykraczają znacznie poza to co standardowo oferuje Joomla!
  6. W wypadku wariantu drugiego możemy dość szybko stworzyć sobie kod kopiujący daną instancję modułu tak by zmieniać tylko wybrane ustawienia (swoisty odpowiednik opcji "kopiuj" w menadżerze modułów panelu administracyjnego) - wystarczy tylko trochę zabawy z klasą JParameter.
  7. Sposoby selekcji modułów w wariancie drugim nie muszą się oczywiście ograniczać do selekcji po ID - analiza budowy tabeli jos_modules (zakładając zastosowanie standardowego prefiksu tabeli podczas instalacji) nasunie na pewno kilka innych ciekawych możliwości selekcji modułów na potrzeby tego wariantu kodu.
 
 

Komentarze

 
 
 

№ 1

15 lutego 2010, 08:04:43

Sun Pietro

ciekawa sprawa z tymi modułami bez modułów
na pewno się przyda

 
 
 

№ 2

15 lutego 2010, 10:42:33

mt3o

Tekst technicznie dobry, ale żaden nieprogramista nie przejdzie przez niego całego.

Dla newbie lepiej opisać moduły, które w sposób idiotoodporny pozwalają na osadzanie w sobie modułów, a także pluginy które daja taką funkcjonalność. Ostatecznie pozostaje grupa dodatków _php ;)

 
 
 

№ 3

15 lutego 2010, 10:46:10

Dziudek

Liczę, że co najmniej do wariantu pierwszego dotrze każdy ;) Zasadniczo ludzie mają świadomość istnienia modułów o takiej funkcjonalności (osadzanie innych modułów) ale one właśnie z reguły wymagają odpowiedniej konfiguracji a tutaj wsadzamy fragment kodu do szablonu i voila ;)

 
 
 

№ 4

15 lutego 2010, 11:01:19

mt3o

IMHO wstawianie modułów w szablon jest trochę bez sensu, bo skoro w szablonie wstawimy moduły, moglibyśmy tam mieć i pozycję modułów :P

Moduły się lepiej przydają w innych modułach, a także w tekstach. Artykuł o tym byłby krótszy i łatwiejszy do łyknięcia ;-)

ps. wyróżniona pierwsza linia akapitu wygląda koszmarnie... wyróżnia się bardziej od śródtytułów, a te umykają gdzieś.

 
 
 

№ 5

15 lutego 2010, 11:07:08

Dziudek

Ja osobiście miałem już sporo przypadków kiedy wstawianie modułów w samym szablonie się przydawało z różnych względów (chociażby z powodu możliwości modyfikacji jakiej nie daje normalne osadzenie pozycji modułów). Druga sprawa, że to ogólna recepta i równie dobrze można jej użyć w module czy komponencie ;)

Co do pierwszej linii akapitu - zgadzam się jak najbardziej, ale już nie miałem siły wczoraj CSS-a od tego szablonu rozgryzać - w najbliższym czasie postaram się poprawić ten szablon ;)

 
 
 

№ 6

15 lutego 2010, 16:31:18

mt3o

To prawda, ma tylko jedną pokaźną wadę - wymaga edytowania kodu PHPowego bezpośrednio w plikach.

Btw, orientujesz się może, jak w Joomli w panelu administracyjnym podlinkować coś do ekranu głównego i usunąć z niego nieużywane linki? Te takie kwadraciki z ikonkami, mam na myśli.

 
 
 

№ 7

15 lutego 2010, 16:34:08

Dziudek

To wszystko zależy jak napiszemy ten kod od generowania modułu - w niektórych wypadkach "interwencje" w kodzie można ograniczyć do minimum.

Co do "kwadracików z ikonkami" można jaśniej ? :>

 
 
 

Dodaj komentarz

 

Podpis

 

URL

 

Treść

 
 
 
 

Miniblog