14
lutego
2010
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.
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).
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.
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:
$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).
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.
ciekawa sprawa z tymi modułami bez modułów
na pewno się przyda
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 ;)
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 ;)
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ś.
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 ;)
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.
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 ? :>