<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0"><channel><title>Joomla@jogger.pl</title><link>http://joomla.jogger.pl/</link><description>Wpisy z dziennika internetowego Jogger, wspomaganego przez Jabbera</description><lastBuildDate>Fri, 24 Feb 2012 10:25:15 +0100</lastBuildDate><generator>JoggerPL</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Joomlajoggerpl" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="joomlajoggerpl" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Dostęp do parametrów szablonu w plikach error.php i offline.php</title><link>http://joomla.jogger.pl/2010/10/30/dostep-do-parametrow-szablonu-w-plikach-error-php-i-offline/</link><description>&lt;p&gt;Strony błędów (&lt;strong&gt;error.php&lt;/strong&gt;) oraz logowania (&lt;strong&gt;offline.php&lt;/strong&gt;) są generowane w trochę inny sposób niż zwykłe strony szablonu. Nie mamy w nich bezpośredniego dostępu do parametrów naszego szablonu. Na szczęście możemy to łatwo naprawić.&lt;/p&gt;
&lt;p&gt;Parametry szablonów są przechowywane przez obiekt klasy &lt;strong&gt;JParameter&lt;/strong&gt;. Nadpisywane przez nas pliki stron błędów i logowania znajdują się w głównym katalogu szablonu. W tym samym katalogu znajduje się też plik &lt;strong&gt;params.ini&lt;/strong&gt;, który przechowuje informacje o wartościach parametrów szablonu. Dodatkowo konstruktor klasy &lt;strong&gt;JParameter&lt;/strong&gt; przyjmuje jako pierwszy argument ciąg danych w formacie znanym z plików &lt;strong&gt;*.ini&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Zatem wystarczy wczytać plik &lt;strong&gt;params.ini&lt;/strong&gt; i tak odczytane dane podać jako argument konstruktora klasy &lt;strong&gt;JParameter&lt;/strong&gt; aby uzyskać dostęp do potrzebnych nam danych. Całość wymaga dosłownie jednej linijki kodu PHP:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$tpl_params = new JParameter(JFile::read(dirname(__FILE__).DS.'params.ini'));&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Odczyt wartości parametrów szablonu odbywa się poprzez następujący kod:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$opcja1 = $tpl_params-&amp;gt;get('NAZWA_OPCJI');&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Dzięki temu możemy nie tylko odczytywać ważne dla nas parametry szablonu, ale też definiować w szablonie nowe opcje związane ściśle z plikami &lt;strong&gt;error.php&lt;/strong&gt; i &lt;strong&gt;offline.php&lt;/strong&gt;&lt;/p&gt;
</description><pubDate>Sat, 30 Oct 2010 13:40:03 +0200</pubDate><guid>http://joomla.jogger.pl/2010/10/30/dostep-do-parametrow-szablonu-w-plikach-error-php-i-offline/</guid><category>dev</category><category>joomla</category><category>szablony</category><category>Techblog</category></item><item><title>Pluginy w mod_custom</title><link>http://joomla.jogger.pl/2010/10/28/pluginy-w-mod-custom/</link><description>&lt;p&gt;Moduł &lt;strong&gt;mod_custom&lt;/strong&gt; to bardzo użyteczne narzędzie, jednak brakuje mu jednej ważnej rzeczy: jego zawartość nie jest parsowana pod kątem zawartości pluginów. Na szczęście można łatwo ten problem rozwiązać.&lt;/p&gt;
&lt;p&gt;Wystarczy zmodyfikować sposób generowania styli modułów. Style te znajdują się w pliku &lt;strong&gt;html/modules.php&lt;/strong&gt; większości szablonów, które takie style stosują.&lt;/p&gt;
&lt;p&gt;Musimy zmodyfikować funkcję &lt;strong&gt;modChrome_NAZWASTYLU&lt;/strong&gt; - na pewno znajduje się w niej linijka podobna do tej:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;echo $module-&amp;gt;content;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Odpowiada ona za wyświetlanie treści modułu. My musimy zmienić ją na następujący kod:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;echo ($module-&amp;gt;module == 'mod_custom') ? JHTML::_('content.prepare', $module-&amp;gt;content) : $module-&amp;gt;content;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Powyższy kod sprawdza typ modułu i w wypadku gdy jest to moduł typu &lt;strong&gt;mod_custom&lt;/strong&gt; do generowania treści wykorzystywanie jest parsowanie pluginów, w przeciwnym wypadku treść generuje się tak samo jak przed modyfikacją.&lt;/p&gt;
&lt;p&gt;W wypadku gdy szablon nie używa własnych styli modułów musimy odbyć małą podróż wgłąb kodu źródłowego szablonu &lt;strong&gt;system&lt;/strong&gt; - predefiniowane style modułów dla Joomla! znajdują się w pliku &lt;strong&gt;templates/system/html/modules.php&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Uwaga!&lt;/strong&gt; ten sposób parsowania kodu pluginów jest dużo lepszy niż niektóre inne metody. Widziałem przykładowo rozwiązanie bazujące na modyfikacji pliku &lt;strong&gt;index.php&lt;/strong&gt;, gdzie po zdarzeniu &lt;strong&gt;onAfterRender&lt;/strong&gt; był umieszczony kod parsowania pluginów. Problem polegał na tym, że przy takim wywołaniu pluginy nie mogą już modyfikować sekcji &lt;strong&gt;head&lt;/strong&gt; szablonu (problem tego typu &lt;a href="http://joomla.jogger.pl/2010/08/18/operacje-na-kompletnej-sekcji-head-szablonu/"&gt;już opisywałem&lt;/a&gt;).&lt;/p&gt;
</description><pubDate>Thu, 28 Oct 2010 17:41:42 +0200</pubDate><guid>http://joomla.jogger.pl/2010/10/28/pluginy-w-mod-custom/</guid><category>dev</category><category>moduły</category><category>szablony</category><category>Techblog</category></item><item><title>Parametry w tytule modułu</title><link>http://joomla.jogger.pl/2010/10/12/parametry-w-tytule-modulu/</link><description>&lt;p&gt;Dobór stylu modułu poprzez dodanie konkretnego sufiksu w opcjach modułu to standard. Ostatnio coraz częściej korzystam z innego udogodnienia, które gwarantuje mi dużo większą elastykę przy określaniu stylistyki modułu - przekazywanie parametrów w tytule modułu.&lt;/p&gt;
&lt;p&gt;Koncepcja ta ma dwie główne zalety:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Możemy przekazywać parametry, których wartościom daleko do nazewnictwa klas CSS;&lt;/li&gt;
&lt;li&gt;Parametry te są widoczne od razu w menadżerze modułów.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Jak to działa ?&lt;/h3&gt;
&lt;p&gt;Decydujemy się, że chcemy stworzyć styl modułu, który np. w swoim prawy górnym rogu wyświetla ikonkę kanału RSS. Oczywiście adres tego kanału jest różny dla różnych modułów, a dodatkowo chcemy mieć taką ikonkę przy różnych modułach. Zatem logiczne jest, że lepiej stworzyć ze stylu modułu swoisty kontener na te dane, zamiast przerabiać kilka modułów by dodać im taką funkcjonalność.&lt;/p&gt;
&lt;p&gt;Jedyny problem to właśnie przekazywanie parametrów takiemu stylowi modułu - i tutaj rozwiązanie jest dość proste: dodajemy po tytule modułu np. w nawiasach klamrowych adres kanału RSS:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;Tytuł naszego modułu {http://adres.rss.pl}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Teraz wystarczy tak zdefiniować funkcję generującą styl modułu, by wydobyła ów adres z tytułu modułu - czyli w skrócie musimy wykonać kilka elementarnych operacji z użyciem wyrażeń regularnych:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$title = $module-&amp;gt;title;
preg_match('/\{.+?\}/', $title, $address);
$title = preg_replace('/\{.+?\}/', '', $title);&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;W powyższym wypadku wystarczy potem dokonać sprawdzenia:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;if(isset($address[0])&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;by wiedzieć czy w ogóle podano parametr, a jeżeli tak to właśnie zmienna &lt;strong&gt;$address[0]&lt;/strong&gt; przechowuje jego wartość.&lt;/p&gt;
&lt;p&gt;Oczywiście sami możemy sobie zdefiniować sposób podawania parametrów - równie dobrze możemy wykorzystywać nawiasy kwadratowe (choć w wypadku adresów internetowych to zły pomysł, gdyż takie znaki mogą występować w adresie) czy po prostu ciąg symboli lub symbol stanowiący separator tytułu od parametrów.&lt;/p&gt;
&lt;p&gt;Daje to nam naprawdę duże możliwości - przede wszystkim jest to rozwiązanie elastyczne. Oczywiście moglibyśmy przekazywać parametry stylowi modułu poprzez atrybuty znacznika &lt;strong&gt;jdoc:include&lt;/strong&gt;, ale to nam nie daje możliwości powiązania wartości parametru z modułem tylko z pozycją modułu.&lt;/p&gt;
&lt;p&gt;Na koniec jeszcze ciekawa koncepcja - przeniesienie sufiksów modułów właśnie do parametrów przekazywanych w tytule. Dzięki temu od razu w menadżerze modułów zobaczymy jaki sufiks nadano konkretnemu modułowi. Przy czym odradzam takie rozwiązanie przy projektach udostępnianych na szerszą skalę - wielu użytkowników jest przyzwyczajonych do opcji "module suffix" ;)&lt;/p&gt;
</description><pubDate>Tue, 12 Oct 2010 20:33:22 +0200</pubDate><guid>http://joomla.jogger.pl/2010/10/12/parametry-w-tytule-modulu/</guid><category>dev</category><category>szablony</category><category>Techblog</category></item><item><title>Cufon - typowe problemy</title><link>http://joomla.jogger.pl/2010/09/29/cufon-typowe-problemy/</link><description>&lt;p&gt;Możliwość osadzania czcionek w CSS wciąż jest dość odległą perspektywą ze względu na brak wsparcia w przeglądarkach używanych przez znaczną część internautów. Czasem jednak istnieje potrzeba wykorzystania w layoucie czcionki znacząco odbiegającej wyglądem od grupy czcionek, które są powszechnie dostępne na komputerach internautów. Pewnym rozwiązaniem tego problemu jest skrypt &lt;a href="http://cufon.shoqolate.com/generate/"&gt;Cufon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Od razu muszę napisać, że osobiście nie jestem zwolennikiem tego typu rozwiązań, ale w chwili obecnej jest to jeden z nielicznych i względnie uniwersalny sposób obejścia problemu z nietypowymi czcionkami.&lt;/p&gt;
&lt;p&gt;Jako, że sporo szablonów, które współtworzyłem zawiera wsparcie dla Cufon-a chciałbym zwrócić uwagę na kilka kwestii, które są często poruszane przez klientów/developerów.&lt;/p&gt;
&lt;h3&gt;Bez JavaScript ani rusz&lt;/h3&gt;
&lt;p&gt;Cufon to skrypt, zatem możemy zapomnieć o naszych pięknych czcionkach zdobiących layouty w przeglądarkach, które mają wyłączony JavaScript. Na szczęście osób wyłączających skrypty jest mało, zwłaszcza w stosunku do osób, które mają przeglądarki nieobsługujące osadzania czcionek.&lt;/p&gt;
&lt;h3&gt;Z pustego i Salomon nie naleje&lt;/h3&gt;
&lt;p&gt;Bardzo często poruszanym problemem jest brak konkretnych liter charakterystycznych dla różnych języków. W tym wypadku trzeba pamiętać o dwóch kwestiach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;duża część czcionek ma dość ograniczoną ilość znaków - dlatego z reguły trzeba wybrać inną czcionkę, która znaki charakterystyczne dla danego języka wspiera;&lt;/li&gt;
&lt;li&gt;gdy mamy już taką czcionkę to musimy ją jeszcze odpowiednio wygenerować - generator plików czcionek dla Cufon-a zawiera sekcję "&lt;i&gt;Include the following glyphs (if available)&lt;/i&gt;", która pozwala nam na wybór stosownej grupy znaków do załączenia w pliku czcionki. Należy przy tym bezwzlędnie pamiętać, że każda dodatkowa grupa znaków znacząco zwiększa rozmiar pliku czcionki - stąd należy starać się jak najbardziej ograniczyć ilość znaków w pliku czcionki by nie spowolnić procesu ładowania strony.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Rozmiar ma znaczenie&lt;/h3&gt;
&lt;p&gt;Cufon działa naprawdę szybko i z reguły w przeglądarkach typu Firefox czy Chrome wręcz nie zauważamy, kiedy zwykły tekst jest podmieniany na tekst napisany inną czcionką. Należy jednak pamiętać, że dużo zależy tu od rozmiaru plików czcionek - jeżeli będą one duże to przynajmniej podczas pierwszego ładowania użytkownik łatwo dostrzeże podmianę tekstu. Dlatego tym bardziej dla potrzeb tzw. pierwszego wrażenia, warto zadbać o rozmiary wygenerowanych dla Cufon-a czcionek.&lt;/p&gt;
&lt;h3&gt;Problematyczny line-height&lt;/h3&gt;
&lt;p&gt;Jednym z najważniejszych parametrów dla tekstu jest wysokość linii określana w CSS poprzez właściwość line-height. Niestety Cufon ma pewne problemy z tym parametrem - w wypadku gdy np. nasz szablon jest napisany w (X)HTML Transitional w większości przeglądarek zmiana wysokości linii po prostu nie zadziała. Osobiście w takiej sytuacji stosowałem czasem marginesy dla elementów typu cufon, które są generowane przez skrypt do reprezentacji liter.&lt;/p&gt;
&lt;h3&gt;Inne efekty CSS też powodują problemy&lt;/h3&gt;
&lt;p&gt;Generalnie jeżeli potrzebujemy dla tekstu zastosować jakieś bardziej nietypowe efekty takie jak przezroczystość, cienie itd. to warto najpierw zapoznać się z częścią dokumentacji odnoszącą się do &lt;a href="http://github.com/sorccu/cufon/wiki/Styling"&gt;stylowania tekstu wygenerowanego przez Cufon&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Cufon a inne skrypty&lt;/h3&gt;
&lt;p&gt;Cufon nie bazuje na żadnym frameworku stąd jest raczej bezproblemowy w wypadku gdy stosujemy go na stronach wykorzystujących np. MooTools czy jQuery. Warto za to pamiętać, że tekst stworzony przez Cufon nie jest dynamiczny. Czyli jeżeli będziemy potrzebowali zmodyfikować tekstową zawartość kontenera wypełnionego tekstem z Cufon-a, to po tej modyfikacji tekst wyświetli się z zastosowaniem czcionki wynikającej ze styli CSS. Aby tekst był dalej zapisany naszą czcionką musimy wywołać po zmianach następujący kod:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;Cufon.refresh();&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Funkcja refresh pobiera opcjonalnie jako argument selektor więc w sytuacji gdy mamy dużo tekstów wygenerowanych przez Cufon-a, możemy wyrenderować czcionkę tylko dla konkretnego elementu.&lt;/p&gt;
&lt;h3&gt;Podsumowanie&lt;/h3&gt;
&lt;p&gt;I to by było na tyle w kwestii często występujących problemów, które mogą się pojawić podczas wykorzystywania Cufon-a na naszych stronach. Zainteresowanym polecam &lt;a href="http://github.com/sorccu/cufon/wiki/API"&gt;oficjalną dokumentację projektu&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Wed, 29 Sep 2010 19:08:09 +0200</pubDate><guid>http://joomla.jogger.pl/2010/09/29/cufon-typowe-problemy/</guid><category>dev</category><category>Techblog</category></item><item><title>Gdy MooTools powoduje problemy</title><link>http://joomla.jogger.pl/2010/09/24/gdy-mootools-powoduje-problemy/</link><description>&lt;p&gt;Ponieważ mam możliwość obserwowania ogromnej ilości stron bazujących na Joomla! wiem, że od czasu wprowadzenia do tego CMS-a nowej wersji MooTools 1.2.* często pojawia się problem kompatybilności.&lt;/p&gt;
&lt;p&gt;Niektórzy developerzy już dostosowali swoje produkty do MooTools 1.2.*, inni nie. Ja osobiście w nowych wersjach modułów planowałem dodanie w opcjach parametru wyboru wersji MooTools używanej w module.&lt;/p&gt;
&lt;p&gt;Jednak po dokładnej analizie doszedłem do wniosku, że nie jest to idealne rozwiązanie. Czasem zdarza się, że jakiś komponent na stronie gdzie normalnie używa się MooTools 1.1 "na siłę" dołącza nowszą wersję MooTools i wtedy problem mamy gotowy.&lt;/p&gt;
&lt;p&gt;Dlatego postanowiłem skorzystać w tej sytuacji z dobrodziejstw istnienia obiektu &lt;strong&gt;MooTools&lt;/strong&gt;, który przechowuje informacje o wersji frameworka. Wystarczy stworzyć dwa skrypty: jeden dla MooTools 1.1 a drugi dla wersji 1.2 i następnie w głównym skrypcie naszego szablonu/modułu dodać następujący kod:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;window.addEvent('load', function() {
        if(MooTools.version.contains('1.1')){
                new Asset.javascript('moo11.js');
        } else {
                new Asset.javascript('moo12.js');
        }
});&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Należy pamiętać o tym, że skrypty w plikach &lt;i&gt;moo11.js&lt;/i&gt; i &lt;i&gt;moo12.js&lt;/i&gt; powinny być tak napisane by wykonywały się od razu (czyli już bez dodawania funkcji obsługi zdarzenia &lt;strong&gt;onLoad&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;Oczywiście zamiast zdarzenia &lt;strong&gt;load&lt;/strong&gt; możemy wykorzystać zdarzenie &lt;strong&gt;domready&lt;/strong&gt;, ale to już zależy od tego co dokładnie robi skrypt, bo w niektórych wypadkach &lt;strong&gt;domready&lt;/strong&gt; &lt;a href="http://blog.dziudek.pl/2009/11/08/domcontentloaded/"&gt;nie spełni naszych oczekiwań&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Fri, 24 Sep 2010 15:04:34 +0200</pubDate><guid>http://joomla.jogger.pl/2010/09/24/gdy-mootools-powoduje-problemy/</guid><category>dev</category><category>joomla</category><category>moduły</category><category>mootools</category><category>Techblog</category></item><item><title>News Show Pro GK4 dla Joomla! 1.5 i Joomla! 1.6</title><link>http://joomla.jogger.pl/2010/09/16/news-show-pro-gk4-dla-joomla-1-5-i-joomla-1-6/</link><description>&lt;p&gt;Dziś małe ogłoszenie parafialne: jeżeli ktoś chciałby pomóc w rozwoju darmowego modułu dla Joomla!: &lt;a href="http://tools.gavick.com/newshowpro.html"&gt;News Show Pro GK4&lt;/a&gt; to zapraszam do rejestracji na stronie &lt;a href="http://pm.gavick.com/"&gt;pm.gavick.com&lt;/a&gt;. W chwili obecnej zapraszam do testowania modułu News Show Pro GK4 &lt;a href="http://pm.gavick.com/view.php?id=53"&gt;w wersji 2.0 dla Joomla! 1.5&lt;/a&gt; oraz &lt;a href="http://pm.gavick.com/view.php?id=60"&gt;w wersji 1.0 dla Joomla! 1.6&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;W najbliższym czasie powinny się też pojawiać nowe wersje innych modułów. Wszelkie znalezione błędy, opinie, uwagi oraz sugestie są bardzo miło widziane :)&lt;/p&gt;
</description><pubDate>Thu, 16 Sep 2010 12:39:07 +0200</pubDate><guid>http://joomla.jogger.pl/2010/09/16/news-show-pro-gk4-dla-joomla-1-5-i-joomla-1-6/</guid><category>dev</category><category>joomla</category><category>moduły</category></item><item><title>Operacje na kompletnej sekcji head szablonu</title><link>http://joomla.jogger.pl/2010/08/18/operacje-na-kompletnej-sekcji-head-szablonu/</link><description>&lt;p&gt;Proces renderowania szablonu w Joomla! składa się generalnie z dwóch etapów. Zrozumienie jak on przebiega ma często kluczowe znaczenie dla działania niektórych skryptów. W dzisiejszym wpisie opiszę dość ciekawy i sądzę, że ciekawy przypadek, kiedy to potrzebujemy uzyskać dostęp do finalnej (powstałej po wszystkich operacjach) wersji sekcji head naszego szablonu.&lt;/p&gt;
&lt;p&gt;Problem na jaki się ostatnio natknąłem, polegał na tym, że potrzebowałem zmienić kolejność kilku plików CSS dodawanych przez niektóre moduły do sekcji head szablonu.&lt;/p&gt;
&lt;p&gt;Niestety - ze względu na ideę parsowania szablonów w Joomla! nie da się tego zrobić tworząc zwykły kod operujący na sekcji head dokumentu - w czasie gdy będzie się on wykonywał, pliki CSS/JS dodawane przez moduły/komponenty nie będą jeszcze w niej dostępne. Dlaczego ? Joomla! parsuje szablon w dwóch etapach - najpierw parsowany jest kod szablonu wraz z towarzyszącym mu kodem PHP, a dopiero w drugim etapie następuje podmiana wstawek &lt;strong&gt;jdoc&lt;/strong&gt; na właściwie im fragmenty strony. Co za tym idzie dopiero wtedy wykonywany jest kod modułów i komponentów.&lt;/p&gt;
&lt;p&gt;W wielkim skrócie proces ten wygląda następująco:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pierwsze parsowanie szablonu i kodu PHP w nim zawartego&lt;/li&gt;
&lt;li&gt;Wystąpienie zdarzenia &lt;strong&gt;onAfterDispatch&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Drugie parsowanie szablonu: podmiana wstawek &lt;strong&gt;jdoc&lt;/strong&gt; i wykonanie kodu modułów/komponentów&lt;/li&gt;
&lt;li&gt;Wystąpienie zdarzenia &lt;strong&gt;onAfterRender&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Zwrócenie do przeglądarki finalnego kodu strony z bufora&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Jeżeli w naszym szablonie wykonujemy jakiś kod operujący na sekcji head to występuje on na etapie pierwszym. Natomiast część danych w sekcji head pojawia się dopiero na etapie trzecim. Co za tym idzie jedyne miejsce w którym możemy operować na kompletnej sekcji head jest etap czwarty.&lt;/p&gt;
&lt;p&gt;I w tym momencie mamy dwa wyjścia:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Możemy stworzyć stosowny plugin i mu powierzyć realizację zadania, lub&lt;/li&gt;
&lt;li&gt;Możemy w naszym szablonie stworzyć coś co śmiało możemy nazwać "pluginem osadzonym w szablonie" - innymi słowy możemy do zdarzenia &lt;strong&gt;onAfterRender&lt;/strong&gt; podpiąć dodatkową funkcję z poziomu kodu naszego szablonu.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I na tym drugim rozwiązaniu się skupimy gdyż wymaga ono aż 2 linii kodu ;) Musimy mianowicie stworzyć obiekt klasy &lt;strong&gt;JDispatcher&lt;/strong&gt;, który odpowiada za generowanie zdarzeń i rejestrację funkcji obsługi zdarzeń, a następnie musimy zarejestrować dodatkową funkcję dla zdarzenia &lt;strong&gt;onAfterRender&lt;/strong&gt;. Cały kod to:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
$dispatcher = JDispatcher::getInstance();
$dispatcher-&amp;gt;register('onAfterRender', 'NASZA_FUNKCJA');
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Oczywiście &lt;strong&gt;NASZA_FUNKCJA&lt;/strong&gt; to nazwa funkcji, która ma zostać podczas zdarzenia wywołana. W ten oto sposób część kodu naszego szablonu wykona się znacznie później w procesie renderowania szablonu.&lt;/p&gt;
&lt;p&gt;Pora na złą wiadomość - po drugim etapie renderowania szablonu nie jesteśmy już w stanie modyfikować sekcji head z użyciem standardowych metod API - po tym etapie jedyne co możemy modyfikować to zawartość bufora, która ma zostać zwrócona do przeglądarki. Aby dostać się do rzeczonego bufora korzystamy z klasy &lt;strong&gt;JResponse&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
$buf = JResponse::getBody();
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Aby zapisać efekty naszej pracy na zmiennej &lt;strong&gt;$buf&lt;/strong&gt; korzystamy z metody &lt;strong&gt;setBody&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
JResponse::setBody($buf);
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I w ten oto sposób mamy zapisane modyfikacje pełnej sekcji head naszego szablonu.&lt;/p&gt;
</description><pubDate>Wed, 18 Aug 2010 18:34:16 +0200</pubDate><guid>http://joomla.jogger.pl/2010/08/18/operacje-na-kompletnej-sekcji-head-szablonu/</guid><category>dev</category><category>joomla</category><category>szablony</category><category>Techblog</category><category>framework</category></item><item><title>Panel Joomla! 1.6 i trochę AJAX-a</title><link>http://joomla.jogger.pl/2010/08/16/panel-joomla-1-6-i-troche-ajax-a/</link><description>&lt;p&gt;Zawsze mnie intrygowało czemu w panelu administracyjnym Joomla! nie ma ajaksowych elementów. To ciągłe odświeżanie strony przy pracy zwyczajnie drażni. Dlatego też postanowiłem w wolnym czasie powoli sobie usprawniać samodzielnie panel Joomla!. Na pierwszy ogień poszły wszechobecne tabele: od zarządzania modułami/użytkownikami etc. Dzięki prostemu skryptowi sortowanie kolumn, filtrowanie oraz stronicowanie wreszcie działają tak jak powinny: bez przeładowywania strony :)&lt;/p&gt;
&lt;p&gt;Jeszcze nie stworzyłem żadnego plugina, zatem dodanie moich rozwiązań do najnowszej wersji beta Joomla! wymaga paru minut, ale myślę, że warto je poświęcić.&lt;/p&gt;
&lt;p&gt;Zacznijmy od pliku JavaScript - poniżej jego kod źródłowy:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
window.addEvent('domready',function(){   
    new JAjax(); 
});

var JAjax = new Class({
    main: null,
    preloader: null,
    preloaderFX:null,
    $this: null,
    
    initialize: function(){
        $this = this;
        this.main = document.id('element-box');
        this.preloader = new Element('div').setProperty('class','gk-preloader');
        this.preloaderFX = new Fx.Tween(this.preloader, { duration:250, wait:false }).set('opacity', 0);
        this.preloader.inject(document.id('element-box'), 'inside');
        this.initUI();
    },
    
    initUI: function(){
        if($$('form .adminlist')[0]){
            document.adminForm.setProperty('action', document.adminForm.getProperty('action')+'&amp;amp;tmpl=ajax');
            $this.filter();
            $this.sort();
            $this.pagination();
        }    
    },
    
    sort: function(){ 
       $$('form .adminlist')[0].getElements('thead a').each(function(el){
            var href = el.getProperty('href');
            href = href.replace('javascript:tableOrdering(','').replace(');','').replace(/\'/g,'').split(',',2);
            el.setProperty('href',href[0]+','+href[1]);
            
            el.addEvent('click', function(e){    
                e.stop();
                cmd = el.getProperty('href').split(',');
                document.adminForm.filter_order.value = cmd[0];
                    document.adminForm.filter_order_Dir.value = cmd[1];
                $this.makeTableReq(); 
            });
       });
    },
    
    filter: function(){
        $$('#filter-bar select').each(function(el){
            el.removeProperty('onchange');
            el.addEvent('change', function(e){
                $this.makeTableReq(); 
            });
        });
        
        $$('#filter-bar .filter-search button').each(function(el,i){
            el.addEvent('click',function(e){
                e.stop();
                if(i == 1) document.id('filter_search').value='';
                $this.makeTableReq();                 
            });
        });
    },
    
    pagination: function(){
        document.id('limit').removeProperty('onchange');
        document.id('limit').addEvent('change', function(e){
            $this.makeTableReq();
        });
        
        $$('tfoot .pagination a').each(function(el){
            var limit = el.getProperty('onclick');
            el.removeProperty('onclick');
            el.addEvent('click', function(e){
               e.stop();
               document.adminForm.limitstart.value = limit.replace(/[^0-9]+/g,''); 
               $this.makeTableReq();
            });
        });
    },
    
    makeTableReq: function(){ 
        new Request.HTML({
            url: document.adminForm.getProperty('action'),
            onComplete: function(nodes, elms, code){
                $$('#element-box .m')[0].innerHTML = code;
                $this.preloaderFX.start('opacity', 0);
                $this.initUI();
            },
            onRequest: function(){
                $this.preloaderFX.start('opacity', 0.85); 
            }    
        }).post(document.adminForm);
    }
});
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Tworzymy plik &lt;strong&gt;tools.js&lt;/strong&gt; i umieszczamy go w katalogu &lt;strong&gt;administrator/templates/bluestork/js/&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Następnie tworzymy plik &lt;strong&gt;tools.css&lt;/strong&gt; i umieszczamy go w katalogu &lt;strong&gt;administrator/templates/bluestork/css/&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
#element-box{ 
    position:relative; 
}

.gk-preloader{ 
    background:#fff; 
    height:100%; left:0; 
    position:absolute; 
    top:0; 
    width:100%; 
    z-index:1; 
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Ponieważ osobiście nie dotarłem jeszcze do odpowiednika &lt;strong&gt;format=raw&lt;/strong&gt; w Joomla! 1.6 problem rozwiązałem inaczej tworząc plik &lt;strong&gt;ajax.php&lt;/strong&gt; w katalogu &lt;strong&gt;administrator/templates/bluestork/&lt;/strong&gt; :&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
&amp;lt;jdoc:include type="message" /&amp;gt;
&amp;lt;jdoc:include type="component" /&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Na koniec w pliku &lt;strong&gt;index.php&lt;/strong&gt; szablonu &lt;strong&gt;bluestork&lt;/strong&gt; pod koniec sekcji &lt;strong&gt;head&lt;/strong&gt; dodajemy dwie linijki:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
&amp;lt;script type="text/javascript" src="templates/&amp;lt;?php echo  $this-&amp;gt;template ?&amp;gt;/js/tools.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link rel="stylesheet" type="text/css" href="templates/&amp;lt;?php echo  $this-&amp;gt;template ?&amp;gt;/css/tools.css" /&amp;gt;    
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I gotowe :)&lt;/p&gt;
&lt;p&gt;Od teraz klikając na tytuły kolumn w tabelach, przyciski stronicowania/zmiany ilości elementów czy korzystając z filtrowania, wszystko powinno się ładować asynchronicznie. Planuję dalsze usprawnienia w niedalekiej przyszłości, ale powoli: trzeba przy Joomla! działać ostrożnie by przypadkiem nie popaść w konflikty z jakimiś zewnętrznymi komponentami :)&lt;/p&gt;
</description><pubDate>Mon, 16 Aug 2010 14:59:59 +0200</pubDate><guid>http://joomla.jogger.pl/2010/08/16/panel-joomla-1-6-i-troche-ajax-a/</guid><category>dev</category><category>joomla</category><category>Techblog</category><category>joomla 1.6 dev administracja javascript</category></item><item><title>Joomla! 1.5.19 i MooTools 1.2.4</title><link>http://joomla.jogger.pl/2010/07/16/joomla-1-5-19-i-mootools-1-2-4/</link><description>&lt;p&gt;W najnowszej wersji Joomla! dodano plugin nazywany MooTools 1.2.4 upgrade plugin. Jest on domyślnie wyłączony i działa on na zasadzie - potrzebujesz MooTools 1.2.4 na swojej stronie ? - to włącz ten plugin. Osobiście jednak uważam, że dodanie takiego dodatku do Joomla! jest bardzo złym i nieprzemyślanym posunięciem.&lt;/p&gt;
&lt;p&gt;Powiedzmy sobie otwarcie - jeżeli ktoś chciał korzystać z MooTools 1.2.4 na swojej stronie opartej o Joomla! to i tak to od dawna robił. Joomla 1.5.* od początku bazowała na MooTools 1.1.* i dodawanie takiej opcji do tego CMS-a w tym momencie oznacza jedno: developerzy rozszerzeń muszą (no dobrze - powinni) napisać spory kawałek warstwy client-side swoich produktów od nowa i dodatkowo tak rozwiązać problem by w zależności od wybranej wersji MooTools na witrynie dane rozszerzenie automatycznie wybierało z której wersji skryptu ma korzystać.&lt;/p&gt;
&lt;p&gt;Pytanie podstawowe jakie się nasuwa - na co to komu ? Duża część rozszerzeń i tak prawdopodobnie nie zostanie zaktualizowana więc prawdopodobnie nowy tryb pracy będzie wykorzystywany sporadycznie. Bo o ile pogodzić jQuery i MooTools nie jest specjalnie trudno to niestety ale dwie różne wersje tego samego frameworka raczej nie chcą ze sobą współpracować.&lt;/p&gt;
&lt;p&gt;Mam cichą nadzieję, że nie będzie podobnych przebojów z Joomla! 1.6 i MooTools 1.2.4 oraz MooTools 1.3.&lt;/p&gt;
</description><pubDate>Fri, 16 Jul 2010 03:44:12 +0200</pubDate><guid>http://joomla.jogger.pl/2010/07/16/joomla-1-5-19-i-mootools-1-2-4/</guid><category>dev</category><category>joomla</category><category>Techblog</category><category>joomla dev</category></item><item><title>Joomla! 1.6 i własny styl formularzy w panelu administracyjnym</title><link>http://joomla.jogger.pl/2010/07/13/joomla-1-6-i-wlasny-styl-formularzy-w-panelu-administracyjny/</link><description>&lt;p&gt;W Joomla! 1.5 pola formularza danego rozszerzenia można było łatwo modyfikować poprzez własne style CSS i skrypty JavaScript dołączając je np. w opisie danego rozszerzenia. Nie było to może rozwiązanie piękne, ale działało skutecznie. W Joomla! 1.6 niestety nie mamy już do dyspozycji opisu w miejscu gdzie występuje formularz konfiguracji danego rozszerzenia.&lt;/p&gt;
&lt;p&gt;Na szczęście Joomla! udostępnia nam inny mechanizm, który możemy wykorzystać na nasze potrzeby - możliwość tworzenia własnych rodzajów pól formularza.&lt;/p&gt;
&lt;p&gt;Własne pola formularza tworzymy na bazie klasy &lt;strong&gt;JFormField&lt;/strong&gt;. Przykłady standardowych pól dostępnych w Joomla! możemy sobie przejrzeć w katalogu &lt;strong&gt;libraries/joomla/form/fields/&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Stworzymy więc własny rodzaj pola formularza, który pozwoli nam dołączać skrypty i style do danej strony. W tym celu tworzymy w katalogu z naszym rozszerzeniem folder &lt;strong&gt;admin/elements/&lt;/strong&gt; i umieszczamy w nim plik &lt;strong&gt;asset.php&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;?php

defined('JPATH_BASE') or die;

jimport('joomla.form.formfield');

class JFormFieldAsset extends JFormField {
        protected $type = 'Asset';

        protected function getInput() {
                $doc = JFactory::getDocument();

                if($this-&amp;gt;element['extension'] == 'js') {
                        return $doc-&amp;gt;addScript(JURI::root().$this-&amp;gt;element['path']);
                } else {
                        return $doc-&amp;gt;addStyleSheet(JURI::root().$this-&amp;gt;element['path']);        
                }
        }
}

?&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Powyższa klasa definiuje pole formularza, które będzie miało następującą budowę:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;field type="asset" extension="ROZSZERZENIE" path="ŚCIEŻKA" /&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Gdzie &lt;strong&gt;ROZSZERZENIE&lt;/strong&gt; przyjmuje wartość &lt;strong&gt;js&lt;/strong&gt; lub &lt;strong&gt;css&lt;/strong&gt; natomiast &lt;strong&gt;ŚCIEŻKA&lt;/strong&gt; to adres żądanego pliku. Na przykład: "&lt;em&gt;templates/NAZWA_SZABLONU/admin/js/skrypt.js&lt;/em&gt;".&lt;/p&gt;
&lt;p&gt;I już prawie jesteśmy u celu - pozostaje nam jeszcze poinformować skrypt gdzie będą znajdowały się dodatkowe klasy pól formularza - w tym celu w elemencie &lt;strong&gt;fieldset&lt;/strong&gt;, który będzie zawierał nasz własny rodzaj pola formularza dodajemy atrybut &lt;strong&gt;addfieldpath&lt;/strong&gt; (w Joomla! 1.5 był to atrybut &lt;strong&gt;addPath&lt;/strong&gt;) ze ścieżką do naszego katalogu z dodatkowymi klasami, na przykład: "&lt;em&gt;/templates/NAZWA_SZABLONU/admin/elements&lt;/em&gt;".&lt;/p&gt;
&lt;p&gt;Po tym zabiegu możemy już śmiało tworzyć własne style CSS i skrypty dla formularzy w panelu administracyjnym znacząco rozszerzające ich zwyczajne możliwości.&lt;/p&gt;
</description><pubDate>Tue, 13 Jul 2010 19:41:06 +0200</pubDate><guid>http://joomla.jogger.pl/2010/07/13/joomla-1-6-i-wlasny-styl-formularzy-w-panelu-administracyjny/</guid><category>dev</category><category>joomla</category><category>Techblog</category><category>framework</category></item><item><title>Joomla! i LESS</title><link>http://joomla.jogger.pl/2010/07/12/joomla-i-less/</link><description>&lt;p&gt;Szablony dla Joomla! mają tą cechę, że z reguły są dość rozbudowane, zwłaszcza jeżeli chodzi o kod CSS: tworząc szablon trzeba ostylować standardowe podstrony, dodatkowe moduły, komponenty. Im bardziej chcemy zadbać o detale tym bardziej rośnie ilość kodu. Kodu w którym pewne rzeczy się powielają. Dlatego od pewnego czasu jestem zwolennikiem wykorzystywania do tworzenia szablonów prekompilatorów CSS. Jednym z takich narzędzi jest &lt;a href="http://lesscss.org/"&gt;LESS&lt;/a&gt;. Pokażę jak bezboleśnie zaimplementować LESS w swoim szablonie oraz jak wykorzystać jego możliwości.&lt;/p&gt;
&lt;p&gt;LESS pierwotnie został stworzony w języku Ruby, jednak nie stanowi to żadnego problemu gdyż istnieją jego implementacje w innych językach m.in. w PHP (&lt;a href="http://leafo.net/lessphp/"&gt;lessphp&lt;/a&gt;) i JavaScript (&lt;a href="http://fadeyev.net/2010/06/19/lessjs-will-obsolete-css/"&gt;LESS.js&lt;/a&gt;). Wersja JavaScript jest mniej wymagająca pod względem dołączenia do szablonu, natomiast jeżeli wyłączymy JavaScript w przeglądarce to niestety mamy problem. Dlatego bezpieczniej skorzystać z wersji LESS, która działa po stronie serwera.&lt;/p&gt;
&lt;p&gt;Tutaj mała uwaga - osobiście polecam korzystanie z LESS tylko na etapie tworzenia szablonu i jego ewentualnych modyfikacji. Dlaczego ? Nie ma sensu by LESS przetwarzał nasze pliki &lt;strong&gt;*.less&lt;/strong&gt; przy każdym wywołaniu strony lub co określony czas (przy wykorzystaniu cache). Dlatego po zakończeniu prac najlepiej zamienić prezentowany kod na odwołania do wygenerowanych z użyciem LESS plików &lt;strong&gt;*.css&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Co nam daje LESS ?&lt;/h3&gt;
&lt;p&gt;LESS rozszerza składnię CSS-a o wiele nowych możliwości. Zacznijmy od mojej ulubionej czyli zmiennych. Większość layoutów ma to do siebie, że bazuje na kilku kolorach. W LESS zmienne tworzymy korzystając z zapisu:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;@nazwa_zmiennej: WARTOŚĆ;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Przykład:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;@kolor1: #000;
@kolor2: #fff;

#nawigacja{
        color: @kolor1;
        background: @kolor2;
}

.code{
        color: @kolor2;
        background: @kolor1;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;W powyższej sytuacji gdybyśmy chcieli odwrócić kolory w elemencie &lt;strong&gt;#nawigacja&lt;/strong&gt; oraz elementach z klasą &lt;strong&gt;code&lt;/strong&gt; wystarczy zmienić wartości zmiennych. Niesamowicie przydatne gdy mamy ogromny plik CSS z mnóstwem powtarzających się kolorów.&lt;/p&gt;
&lt;p&gt;Druga ważna funkcjonalność - zagnieżdżanie elementów. Zamiast pisać:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;#nawigacja {}
#nawigacja a {}
#nawigacja a:hover {}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Zapisujemy:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;#nawigacja {
        /* tu style dla elementu #nawigacja */
        color: #000;
        margin: 10px;

        a {
                /* tu style dla linków w #nawigacja */
                color:#aaa;
                display:block;
                
                /* a tu style dla pseudoklas */
                :hover {
                        text-decoration:none;
                }
        }
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Taki zapis jest o wiele czytelniejszy bo często niektórzy próbują kod formatować następująco:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;#nawigacja {}
        #nawigacja a {}
        #nawigacja a:hover {}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;By podkreślić, że selektory tyczą się elementów zagnieżdżonych w innym elemencie.&lt;/p&gt;
&lt;p&gt;Inna warta wspomniena rzecz to możliwość ponownego wykorzystana raz już stworzonego kodu:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;.test{
        color:#000;
        background:#fff;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Teraz możemy osadzić właściwości &lt;strong&gt;color&lt;/strong&gt; i &lt;strong&gt;background&lt;/strong&gt; w innym elemencie pisząc po prostu:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;.test2{
        .test;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Możemy też się odwoływać bezpośrednio do elementów zagnieżdżonych czy nawet do konkretnych wartości właściwości lub zmiennych, a nawet tworzyć klasy z parametrami.&lt;/p&gt;
&lt;p&gt;Możliwości LESS są naprawdę duże - zainteresowanych odsyłam do dokumentacji &lt;a href="http://leafo.net/lessphp/docs/"&gt;lessphp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My tymczasem wróćmy do meritum tego posta czyli użycia LESS w Joomla!.&lt;/p&gt;
&lt;h3&gt;Jak wykorzystać LESS w Joomla! ?&lt;/h3&gt;
&lt;p&gt;Aby użyć LESS polecam najpierw w katalogu zawierającym style CSS szablonu utworzyć katalog &lt;strong&gt;less/&lt;/strong&gt;, który będzie zawierał pliki źródłowe &lt;strong&gt;*.less&lt;/strong&gt; do przetworzenia. W katalogu ze stylami umieszamy plik &lt;strong&gt;lessphp.inc.php&lt;/strong&gt; pobrany ze strony projektu &lt;a href="http://leafo.net/lessphp/#download"&gt;lessphp&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;W pliku &lt;strong&gt;index.php&lt;/strong&gt; naszego szablonu dołączamy plik &lt;strong&gt;lessphp.inc.php&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;require_once('css/lessc.inc.php');&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;oraz definiujemy następującą funkcję:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;function generate_less($file, $template_name = 'beez5'){
        try {
            lessc::ccompile(JPATH_THEMES.DS.$template_name.DS.'css'.DS.'less'.DS.$file.'.less', JPATH_THEMES.DS.$template_name.DS.'css'.DS.$file.'.css');
            echo '&amp;lt;link rel="stylesheet" type="text/css" href="templates/'.$template_name.'/css/'.$file.'.css" /&amp;gt;';
        } catch (exception $e) {
            exit('LESS ERROR:'.$e-&amp;gt;getMessage()."\nFILE:".$file.'.less');
        }
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Oczywiście musimy pamiętać też o zapewnieniu stosownych uprawnień do zapisu w katalogu &lt;strong&gt;css/&lt;/strong&gt; i zmienieniu w parametrach funkcji nazwy szablonu na nazwę naszego szablonu.&lt;/p&gt;
&lt;p&gt;Dzięki temu możemy odwoływać się do plików CSS poprzez zapis:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;?php generate_less('template'); ?&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Powyższy zapis wygeneruje z pliku &lt;strong&gt;css/less/template.less&lt;/strong&gt; plik &lt;strong&gt;css/template.css&lt;/strong&gt; i umieści odnośnik do niego w miejscu wywołania.&lt;/p&gt;
&lt;h3&gt;Parę uwag na koniec&lt;/h3&gt;
&lt;p&gt;Jedną z bolączek LESS jest dosyć małe wsparcie dla składni w edytorach. Osobiście korzystam z edytora &lt;a href="http://www.panic.com/coda/"&gt;Coda&lt;/a&gt; i tego &lt;a href="http://groups.google.com/group/coda-users/browse_thread/thread/b3327b0cb893e439?pli=1"&gt;rozwiązania&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;LESS.js ma jeszcze tą wadę, że wszystkie generowane przez niego style są osadzane bezpośrednio w kodzie strony - stąd jeżeli mamy w plikach &lt;strong&gt;*.less&lt;/strong&gt; odnośniki do grafik tła to musimy je definiować względem głównego dokumentu strony a nie położenia pliku &lt;strong&gt;*.less&lt;/strong&gt; (oczywiście w wypadku naszych plików &lt;strong&gt;*.less&lt;/strong&gt; odniesienia do plików tła tworzymy tak jakby się znajdowały one w katalogu &lt;strong&gt;css/&lt;/strong&gt; a nie &lt;strong&gt;css/less/&lt;/strong&gt;).&lt;/p&gt;
</description><pubDate>Mon, 12 Jul 2010 19:20:02 +0200</pubDate><guid>http://joomla.jogger.pl/2010/07/12/joomla-i-less/</guid><category>dev</category><category>joomla</category><category>szablony</category><category>Techblog</category><category>joomla dev szablony</category></item><item><title>Jak NIE należy pisać rozszerzeń dla Joomla!</title><link>http://joomla.jogger.pl/2010/06/29/jak-nie-nalezy-pisac-rozszerzen-dla-joomla/</link><description>&lt;p&gt;Podczas pracy z Joomla! widziałem już sporo ogólnodostępnych komponentów i modułów w akcji. Z reguły jest miło i przyjemnie do jednego momentu - chwili w której trzeba trochę zmodyfikować styl/strukturę modułu lub komponentu. W poniższym wpisie chciałbym zaprezentować pięć najbardziej drażniących motywów z którymi wielokrotnie się spotkałem w czasie pracy.&lt;/p&gt;
&lt;h3&gt;1. Brak katalogu tmpl/ w module&lt;/h3&gt;
&lt;p&gt;Podstawowa bolączka wielu modułów, wynikająca prawdopodobnie po części z niewiedzy, po części z lenistwa programisty. Nieświadomym przypominam, że katalog tmpl/ zawiera pliki ze strukturą generowaną przez konkretny moduł, które można w łatwy sposób nadpisać w danym szablonie. Zaleta ? Przenosząc szablon na inną instalację Joomla! nie musimy tworzyć własnych wersji plików modułu, które trzeba przenosić z szablonem - wszystko mamy w jednym miejscu. Przy tworzeniu szablonów dla większego grona klientów jest to wręcz jedyne sensowne rozwiązanie (bo typowy klient nie lubi gdy poza zainstalowaniem szablonu każemy mu jeszcze podmienić jakieś pliki/katalogi).&lt;/p&gt;
&lt;h3&gt;2. jQuery&lt;/h3&gt;
&lt;p&gt;Joomla! 1.5.* od początku wykorzystywała framework MooTools po stronie back-endu i ma wbudowane dla niego wsparcie po stronie front-endu. Dlatego zupełnie nie rozumiem ludzi, którzy tworzą rozszerzenia dla Joomla! z użyciem jQuery. A już zupełnie nie trawię ludzi, którzy tworzą rozszerzenia dla Joomla! w jQuery i nie stosują funkcjonalności &lt;strong&gt;noConflict&lt;/strong&gt;. Problemy na bardziej złożonej stronie są wtedy wręcz gwarantowane, a o dodatkowym transferze nie wspomnę (nie ma to jak dwa frameworki JavaScript o zbliżonych możliwościach, zastosowane na jednej witrynie). Podsumowując - w światku Joomla! , a szczególnie świecie ogólnodostępnych rozszerzeń lepiej zapomnieć o swojej miłości do jQuery - dla dobra użytkowników.&lt;/p&gt;
&lt;h3&gt;3. Atrybut style&lt;/h3&gt;
&lt;p&gt;Kolejny "klasyk" - osobiście rozumiem, że nieraz trzeba zastosować atrybut style do określenia szerokości danego modułu, czy wysokości kontenerów - przy elastyce Joomla! jest to wręcz niezbędne by uniknąć gigantycznej sekcji head z masą znaczników &lt;strong&gt;style&lt;/strong&gt;. Nie rozumiem natomiast zupełnie jak można w ten sposób definiować takie rzeczy jak styl obramowania czy kolor czcionki. Widziałem takie cuda i to o zgrozo także w płatnych komponentach.&lt;/p&gt;
&lt;h3&gt;4. Bardzo dziwne skrypty&lt;/h3&gt;
&lt;p&gt;W komponencie Jomsocial ktoś wpadł na pomysł zastosowania skryptów do tworzenia tooltipów. I wszystko działałoby pięknie i ładnie, gdyby nie to, że wszystkie style tych tooltipów były generowane przez... skrypt JavaScript. Fantastyczna sprawa, szczególnie w wypadku tworzenia efektu zaokrąglonych rogów dla tych tooltipów, które w wypadku IE były generowane jako elementy w języku VML i nijak nie szło się ich pozbyć bez ingerencji w kod komponentu.&lt;/p&gt;
&lt;h3&gt;5. CSS-owy egoizm&lt;/h3&gt;
&lt;p&gt;Pora na "kwiatek" z komponentu K2 w której zawarto w stylu CSS zupełnie bezstresowo taki oto zapis:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;.even{...}
.odd{...}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;A teraz proszę sobie wyobrazić co mogło się stać z wszystkimi szablonami i modułami używającymi tych klas ;)&lt;/p&gt;
&lt;p&gt;Ja wiem, że to kilka znaków więcej, ale naprawdę warto wyposażyć swoje moduły/komponenty w głównym kontenerze w jakąś charakterystyczną klasę / identyfikator, która może i wydłuży ciut kod CSS:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;.dziudek .even{...}
.dziudek .odd{...}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Ale zaoszczędzi masy nerwów i analizowania potencjalnym użytkownikom ;)&lt;/p&gt;
&lt;h3&gt;Poza rankingiem&lt;/h3&gt;
&lt;p&gt;I na koniec absolutny klasyk - nieczytelny kod. Wielu ludzi sobie chyba nie zdaje sprawy, że zamiast klamerek w PHP można stosować takie słowa kluczowe jak:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;endif&lt;/li&gt;
&lt;li&gt;endfor&lt;/li&gt;
&lt;li&gt;endforeach&lt;/li&gt;
&lt;li&gt;itd...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mógłbym w tym miejscu wkleić kilka znakomitych kawałków nieczytelnego kodu, ale po prostu wręcz nie mogę na nie patrzeć. Naprawdę warto na koniec swojej pracy rzucić okiem w kod i zastanowić się czy jest on chociaż odrobinę czytelny dla innego użytkownika.&lt;/p&gt;
&lt;h3&gt;Podsumowanie&lt;/h3&gt;
&lt;p&gt;Podsumowując to zacne zestawienie - warto poświęcić odrobinę czasu i zastanowić się czy to co puszczamy w świat zadziała w ogóle u innych użytkowników, a jeżeli tak to warto się zastanowić czy ciężko jest dostosować nasze dzieło do różnych szablonów. Bo nawet najbardziej funkcjonalny moduł/komponent nie będzie użyteczny dopóki nie będzie się dawał względnie łatwo zmodyfikować.&lt;/p&gt;
</description><pubDate>Tue, 29 Jun 2010 21:28:51 +0200</pubDate><guid>http://joomla.jogger.pl/2010/06/29/jak-nie-nalezy-pisac-rozszerzen-dla-joomla/</guid><category>dev</category><category>joomla</category><category>komponenty</category><category>moduły</category><category>Techblog</category><category>joomla dev moduły komponenty rozszerzenia</category></item><item><title>Uwaga na CKForms!</title><link>http://joomla.jogger.pl/2010/06/01/uwaga-na-ckforms/</link><description>&lt;p&gt;Jeżeli ktoś z czytelników bloga korzysta na swojej stronie opartej na Joomla! z komponentu CKForms to apeluję o wyłączenie tego komponentu dla własnego bezpieczeństwa.&lt;/p&gt;
&lt;p&gt;Dziś kolega zaprezentował mi dziurę w tym komponencie, która pozwala na zrobienie właściwie wszystkiego z serwerem na którym postawiona jest strona z wspominanym komponentem. Informacja została wysłana do zespołu tworzącego CKForms, ale jak dotąd nie uzyskano odpowiedzi ani tym bardziej aktualizacji komponentu, którego ostatnia wersja z tego co widzę pochodzi z 20 marca.&lt;/p&gt;
</description><pubDate>Tue, 01 Jun 2010 01:40:56 +0200</pubDate><guid>http://joomla.jogger.pl/2010/06/01/uwaga-na-ckforms/</guid><category>joomla</category><category>komponenty</category><category>Techblog</category><category>joomla dev exploit komponenty</category></item><item><title>Problemy z UTF-8</title><link>http://joomla.jogger.pl/2010/04/18/problemy-z-utf-8/</link><description>&lt;p&gt;Gdy zajmujemy się wdrażaniem rozszerzeń dla Joomla!, które są używane do wyświetlania tekstów w różnych językach może pojawić się problem z kodowaniem znaków lub błędnym obliczaniem pozycji znaków w tekście. Wszystkiemu winne są funkcje PHP służące do operowania na ciągach znaków.&lt;/p&gt;
&lt;h3&gt;W czym tkwi problem ?&lt;/h3&gt;
&lt;p&gt;Standardowe funkcje PHP takie jak np. &lt;strong&gt;substr&lt;/strong&gt;, &lt;strong&gt;stripos&lt;/strong&gt; nie są przystosowane do operowania na ciągach znaków w których znak może być reprezentowany jako więcej niż jeden bajt. W &lt;strong&gt;UTF-8&lt;/strong&gt; niektóre znaki są reprezentowane właśnie w taki sposób. Stąd powstało rozszerzenie dla PHP - &lt;a href="http://www.php.net/manual/pl/book.mbstring.php"&gt;Multibyte String&lt;/a&gt; - jego cechą charakterystyczną są funkcje z prefiksem "&lt;em&gt;mb_&lt;/em&gt;". Co jednak jeżeli przygotowujemy rozszerzenie dla szerszego grona użytkowników z których nie każdy posiada zainstalowane u siebie takie rozszerzenie ?&lt;/p&gt;
&lt;h3&gt;JString&lt;/h3&gt;
&lt;p&gt;Rozwiązaniem problemu w takiej sytuacji jest klasa &lt;strong&gt;JString&lt;/strong&gt; - jest ona swoistą nakładką na bibliotekę &lt;a href="http://sourceforge.net/projects/phputf8/"&gt;PHP UTF-8&lt;/a&gt;, która wchodzi w skład standardowych bibliotek dostarczanych razem z Joomla!.&lt;/p&gt;
&lt;p&gt;Po zaimportowaniu klasy &lt;strong&gt;JString&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;jimport('joomla.utilities.string');&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;możemy swobodnie korzystać z funkcji operujących na ciągach znaków, które poradzą sobie z &lt;strong&gt;UTF-8&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pełna lista metod tej klasy znajduje się na &lt;a href="http://api.joomla.org/Joomla-Framework/Utilities/JString.html"&gt;tej stronie&lt;/a&gt;. Nie ma sensu ich tutaj kolejno opisywać gdyż są to po prostu odpowiedniki funkcji znanych z PHP. Jedyną niestandardową metodą jest &lt;strong&gt;transcode&lt;/strong&gt;, która bazuje na rozszerzeniu &lt;a href="http://pl.php.net/iconv"&gt;iconv&lt;/a&gt; i pozwala na konwersję ciągu znaków z jednego kodowania na inne (w tym wypadku z &lt;strong&gt;UTF-8&lt;/strong&gt; na &lt;strong&gt;ISO-8859-2&lt;/strong&gt;):&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;JString::transcode('UTF-8', 'ISO-8859-2', $text);&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Wszystkie metody klasy &lt;strong&gt;JString&lt;/strong&gt; są statyczne więc przykładowo wywołanie metody &lt;strong&gt;substr&lt;/strong&gt; ogranicza się do zapisu:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;JString::substr($text, 0);&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Dzięki funkcjonalnościom tej klasy unikniemy sytuacji w której użytkownik z Grecji żali się nam, że nasz moduł wyświetlający skróty artykułów zamiast znaków jego alfabetu wyświetla znaki zapytania :)&lt;/p&gt;
</description><pubDate>Sun, 18 Apr 2010 18:05:43 +0200</pubDate><guid>http://joomla.jogger.pl/2010/04/18/problemy-z-utf-8/</guid><category>dev</category><category>joomla</category><category>komponenty</category><category>moduły</category><category>Techblog</category></item><item><title>JBrowser</title><link>http://joomla.jogger.pl/2010/04/11/jbrowser/</link><description>&lt;p&gt;Dosyć często widuję w kodzie różnego rodzaju rozwiązań dla Joomla!, że jego twórcy próbują odkrywać koło na nowo - tak jest np. w wypadku detekcji przeglądarek. Tak jakby mało kto sobie zdawał sprawę z tego, że framework na którym bazuje Joomla! udostępnia całkiem sensowne rozwiązanie jakim jest klasa &lt;strong&gt;JBrowser&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Napisałem, że &lt;strong&gt;JBrowser&lt;/strong&gt; to całkiem sensowne rozwiązanie, ponieważ ma oczywiście kilka wad - z moich testów wynika, że np. nie rozróżnia ona Chrome i Safari, a Safari w iPhone jest traktowane tak samo jak jego desktopowe odpowiedniki - wszystkie trzy przeglądarki są rozpoznawane jako &lt;em&gt;"konqueror"&lt;/em&gt;. Natomiast świetnie sobie radzi z najważniejszym zagadnieniem jakim jest detekcja różnych wersji IE, bo to w zasadzie główne zastosowanie detekcji przeglądarek (poza detekcją przeglądarek mobilnych). Podobny problem tyczy się listy wspieranych przez przeglądarkę udogodnień - jako, że klasa &lt;strong&gt;JBrowser&lt;/strong&gt; była stworzona jakiś czas temu to nie poinformuje nas, że nowsze wersje Opery wspierają format SVG. Ale te problemy da się oczywiście wyeliminować dzięki dość szerokiej gamie metod oferowanych przez tą klasę.&lt;/p&gt;
&lt;h3&gt;Tworzenie obiektu klasy JBrowser&lt;/h3&gt;
&lt;p&gt;Aby rozpocząć pracę z klasą &lt;strong&gt;JBrowser&lt;/strong&gt; musimy najpierw ją zaimportować, gdyż nie wchodzi ona w skład klas standardowo używanych przez rozszerzenia Joomla!. Aby to zrobić umieszczamy w naszym kodzie linijkę:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;jimport('joomla.environment.browser');&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Obiekty tej klasy możemy tworzyć przez standardowy konstruktor, lub z użyciem metody &lt;strong&gt;getInstance&lt;/strong&gt;, osobiście polecam ten drugi sposób, chyba, że mamy jakiś powód dla którego musimy uzyskać niemodyfikowany wcześniej obiekt klasy &lt;strong&gt;JBrowser&lt;/strong&gt; - wtedy lepiej skorzystać ze standardowego konstruktora.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$browser = JBrowser::getInstance();&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Zarówno konstruktor jak i metoda &lt;strong&gt;getInstance&lt;/strong&gt; pobierają dwa argumenty - ciąg &lt;i&gt;user agent&lt;/i&gt; oraz zawartość nagłówka &lt;strong&gt;HTTP_ACCEPT&lt;/strong&gt;. Oba te argumenty są oczywiście opcjonalne i mają wpływ na pozostałe składowe obiektu.&lt;/p&gt;
&lt;p&gt;Jeżeli chcemy określi wspomniane dwa parametry już w czasie istnienia obiektu to możemy skorzystać z funkcji &lt;strong&gt;match&lt;/strong&gt;, która działa tak samo jak &lt;strong&gt;getInstance&lt;/strong&gt; z podanymi dwoma argumentami:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$browser-&amp;gt;match("ciąg user agent", "ciąg HTTP_ACCEPT");&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Tablice _features, _quirks i _robots&lt;/h3&gt;
&lt;p&gt;Obiekt klasy &lt;strong&gt;JBrowser&lt;/strong&gt; zawiera trzy interesujące tablice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tablicę &lt;strong&gt;_features&lt;/strong&gt;, zawierającą wspierane przez przeglądarkę udogodnienia (&lt;a href="http://api.joomla.org/__filesource/fsource_Joomla-Framework_Environment_joomlaenvironmentbrowser.php.html#a152"&gt;pełna lista&lt;/a&gt;),&lt;/li&gt;
&lt;li&gt;tablicę &lt;strong&gt;_quirks&lt;/strong&gt;, zawierającą listę znanych specyficznych problemów związanych z daną przeglądarką (&lt;a href="http://api.joomla.org/__filesource/fsource_Joomla-Framework_Environment_joomlaenvironmentbrowser.php.html#a180"&gt;pełna lista&lt;/a&gt;),&lt;/li&gt;
&lt;li&gt;tablicę &lt;strong&gt;_robots&lt;/strong&gt;, zawierającą listę rozpoznawanych botów wyszukiwarek (&lt;a href="http://api.joomla.org/__filesource/fsource_Joomla-Framework_Environment_joomlaenvironmentbrowser.php.html#a88"&gt;pełna lista&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I oczywiście mamy też kilka metod związanych z tymi tablicami. Możemy sprawdzić czy dane rozwiązanie jest wspierane przez przeglądarkę poprzez metodę &lt;strong&gt;getFeature&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$browser-&amp;gt;getFeature('svg');&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Jeżeli dodatkowo wykryjemy, że np. mamy do czynienia z Operą w nowszej wersji to wpierw możemy jej ustawić wsparcie dla SVG poprzez metodę &lt;strong&gt;setFeature&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$browser-&amp;gt;setFeature ('svg');&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Domyślna wartość drugiego argumentu tej metody to &lt;strong&gt;true&lt;/strong&gt;, stąd go nie podaję.&lt;/p&gt;
&lt;p&gt;Tak samo wygląda sytuacja z obsługą tablicy &lt;strong&gt;_quirks&lt;/strong&gt; - mamy metody &lt;strong&gt;getQuirk&lt;/strong&gt; i &lt;strong&gt;setQuirk&lt;/strong&gt;, które pobierają argumenty w identycznej ilości i typie. Dodatkowo mamy do dyspozycji metody &lt;strong&gt;hasFeature&lt;/strong&gt; i &lt;strong&gt;hasQuirk&lt;/strong&gt;, które sprawdzają czy dana pozycja znajduje się w danej tablicy.&lt;/p&gt;
&lt;p&gt;Aby stwierdzić czy aktualna przeglądarka odwiedzająca naszą witrynę jest botem jednej z wyszukiwarek wystarczy wywołać metodę &lt;strong&gt;isRobot&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;if($browser-&amp;gt;isRobot()) {
    // kod wykonywany gdy przeglądarka jest botem
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Tutaj polecam też zapoznanie się z listą dostępną na &lt;a href="http://www.user-agents.org/"&gt;http://www.user-agents.org/&lt;/a&gt; i ewentualne uzupełnienie standardowej listy o dodatkowe pozycje by lepiej wykrywać boty wyszukiwarek.&lt;/p&gt;
&lt;h3&gt;Detekcja platformy i przeglądarki&lt;/h3&gt;
&lt;p&gt;Oczywiście głównym wątkiem związanym z klasą &lt;strong&gt;JBrowser&lt;/strong&gt; jest sama detekcja rodzaju przeglądarki - związane z tym jest kilka metod, pierwszą z nich jest &lt;strong&gt;getAgentString&lt;/strong&gt;, która zwraca nam cały ciąg &lt;em&gt;user agent&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$user_agent = $browser-&amp;gt;getAgentString();&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I tą metodę będziemy wykorzystywać do detekcji wszelkich przeglądarek nierozpoznawanych standardowo przez klasę &lt;strong&gt;JBrowser&lt;/strong&gt;. Przykładowo dla detekcji iPhone wykonamy kod:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$is_iphone = false;

if(preg_match('/iPhone/',$browser-&amp;gt;getAgentString())){
    $is_iphone = true;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Aby poznać nazwę przeglądarki i platformy użytkownika korzystamy z metod &lt;strong&gt;getBrowser&lt;/strong&gt; i &lt;strong&gt;getPlatform&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;echo 'Przeglądarka:' . $browser-&amp;gt;getBrowser(). '&amp;lt;br /&amp;gt;';
echo 'OS:' . $browser-&amp;gt;getPlatform();&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Możemy też uzyskać informacje o wersji protokołu HTTP:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;$browser-&amp;gt;getHTTPProtocol();&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Oraz dokładne informacje o wersji przeglądarki:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;echo $browser-&amp;gt;getMajor() . '&amp;lt;br /&amp;gt;';
echo $browser-&amp;gt;getMinor() . '&amp;lt;br /&amp;gt;';
echo $browser-&amp;gt;getVersion();&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;W wypadku IE 8.0 uzyskamy po uruchomieniu powyższego kodu następujące trzy linijki:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;8
0
8.0&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Inne metody klasy JBrowser&lt;/h3&gt;
&lt;p&gt;Wracając jeszcze do przykładu z iPhone - zamiast korzystać z dodatkowej zmiennej &lt;strong&gt;$is_iphone&lt;/strong&gt;, możemy to zrobić bardziej elegancko, poprzez metody &lt;strong&gt;setBrowser&lt;/strong&gt; i &lt;strong&gt;isBrowser&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;if(preg_match('/iPhone/',$browser-&amp;gt;getAgentString())){
    $browser-&amp;gt;setBrowser('iPhone');
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Natomiast późniejszego rozpoznania iPhone dokonamy poprzez:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;if($browser-&amp;gt;isBrowser('iPhone')){
    // kod wykonywany tylko na iPhone
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Na koniec pozostała nam jeszcze metoda &lt;strong&gt;isSSLConnection&lt;/strong&gt;, która sprawdza czy bieżące połączenie jest połączeniem szyfrowanym - dzięki temu możemy wyświetlić na stronie stosowny komunikat gdy wiemy, że na danej stronie połączenie powinno być szyfrowane a nie jest.&lt;/p&gt;
</description><pubDate>Sun, 11 Apr 2010 11:56:35 +0200</pubDate><guid>http://joomla.jogger.pl/2010/04/11/jbrowser/</guid><category>dev</category><category>joomla</category><category>Techblog</category><category>framework</category></item><item><title>Joomla! [PRACA]</title><link>http://joomla.jogger.pl/2010/03/26/joomla-praca/</link><description>&lt;p&gt;Gdyby ktoś był zainteresowany składaniem szablonów dla Joomla! za naprawdę godziwe pieniądze to zapraszam do zapoznania się z &lt;a href="http://www.scigani.pl/praca-it/3277/praca-xhtml-css-php-sql-webmaster-dla-gavickpro"&gt;tą ofertą&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Fri, 26 Mar 2010 09:38:35 +0100</pubDate><guid>http://joomla.jogger.pl/2010/03/26/joomla-praca/</guid><category>Ogólne</category></item><item><title>Zmiana tła strony w zależności od podstrony</title><link>http://joomla.jogger.pl/2010/03/09/zmiana-tla-strony-w-zaleznosci-od-podstrony/</link><description>&lt;p&gt;Dzisiaj szybkie skryptowe rozwiązanie dość często spotykanego problemu zmiany tła w zależności od podstrony, który powinien w jakimś stopniu zniknąć w Joomla! 1.6, gdzie będzie istniała możliwość zmiany ustawień szablonu dla konkretnych podstron (obecnie trzeba tworzyć kopie danego szablonu i przypisywać go do konkretnych podstron).&lt;/p&gt;
&lt;p&gt;Do osiągnięcia pożądanych rezultatów musimy zrobić dwie rzeczy: stworzyć w katalogu &lt;strong&gt;images/&lt;/strong&gt; naszego szablonu katalog &lt;strong&gt;backgrounds/&lt;/strong&gt; wypełniony grafikami tła, których chcemy użyć oraz dodać poniższy skrypt w sekcji head naszego szablonu (najlepiej na samym jej końcu):&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;?php
    // tablica powiązań Itemid &amp;lt;-&amp;gt; grafika tła
    $bg_images = array(
        "53" =&amp;gt; "1.jpg",
        "54" =&amp;gt; "2.jpg",
        "default" =&amp;gt; "3.jpg" // grafika domyślna
    );

    $itemID_value = JRequest::getCmd('Itemid');
    $bg_image = (isset($bg_images[$itemID_value])) ? $bg_images[$itemID_value] : $bg_images["default"];
    $url =&amp;amp; JURI::getInstance();
    
?&amp;gt;

&amp;lt;style type="text/css"&amp;gt;
body{
background:#fff url('&amp;lt;?php echo $url-&amp;gt;root(); ?&amp;gt;templates/&amp;lt;?php echo $this-&amp;gt;template; ?&amp;gt;/images/backgrounds/&amp;lt;?php echo $bg_image; ?&amp;gt;') center 0!important;
}
&amp;lt;/style&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Jak to działa ?&lt;/h3&gt;
&lt;p&gt;Powyższy skrypt dysponuje tablicą powiązań &lt;strong&gt;$bg_images&lt;/strong&gt;, która definiuje powiązania pomiędzy wartościami zmiennej &lt;strong&gt;Itemid&lt;/strong&gt; z adresu i obrazkiem tła przypisanym do danej wartości &lt;strong&gt;Itemid&lt;/strong&gt;. Skrypt wczytuje wartość &lt;strong&gt;Itemid&lt;/strong&gt; z adresu i na tej podstawie określa czy do danej wartości został przypisany jakiś szczególny typ tła, w przeciwnym wypadku zostanie zastosowana grafika domyślna.&lt;/p&gt;
&lt;p&gt;Za ustawienie tła odpowiada osadzony styl CSS, w którym można oczywiście pozmieniać parametry pozycjonowania tła, koloru tła i jego powielania ;)&lt;/p&gt;
&lt;p&gt;Oczywiście nic nie stoi na przeszkodzie by określać także inne parametry tła w ten sposób, a nawet dodawać całe style CSS&lt;/p&gt;
</description><pubDate>Tue, 09 Mar 2010 22:48:18 +0100</pubDate><guid>http://joomla.jogger.pl/2010/03/09/zmiana-tla-strony-w-zaleznosci-od-podstrony/</guid><category>dev</category><category>joomla</category><category>szablony</category><category>Techblog</category><category>joomla dev szablony</category></item><item><title>Wbudowane szablony w Joomla!</title><link>http://joomla.jogger.pl/2010/03/04/wbudowane-szablony-w-joomla/</link><description>&lt;p&gt;Tworząc szablon dla Joomla! możemy zdefiniować nie tylko wygląd strony i jej podstron, ale także wygląd standardowych komunikatów o błędach czy informacji o pracach konserwacyjnych witryny. W razie potrzeby możemy też zdefiniować kilka własnych szablonów spełniających określone warunki - np. potrzebne do wymiany danych z użyciem AJAX-a. A wszystko to dzięki jednej zmiennej znajdującej się w adresie - &lt;strong&gt;tmpl&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Z reguły szablony posiadają w głównym katalogu jedynie plik &lt;strong&gt;index.php&lt;/strong&gt;, czasem plik &lt;strong&gt;component.php&lt;/strong&gt; - są one wykorzystywane do generowania treści strony w zależności od wartości zmiennej &lt;strong&gt;tmpl&lt;/strong&gt; w adresie (domyślna jej wartość to &lt;strong&gt;index&lt;/strong&gt;). W pliku &lt;strong&gt;component.php&lt;/strong&gt; definiujemy wygląd strony zawierającej wyłącznie aktualny komponent. Jeżeli przyjrzymy się zawartości katalogu &lt;strong&gt;templates/system/&lt;/strong&gt; to zauważymy, że istnieją jeszcze dwa pliki tego typu: &lt;strong&gt;error.php&lt;/strong&gt; oraz &lt;strong&gt;offline.php&lt;/strong&gt;. Pierwszy z nich odpowiada za komunikaty o błędach wyświetlane np. w wypadku wpisania nieistniejącego adresu, a drugi odpowiada za wygląd strony informującej o pracach konserwacyjnych. Oba pliki także możemy nadpisać w katalogu głównym naszego szablonu i w ten sposób uzyskać stylowanie spójne z wyglądem naszego projektu.&lt;/p&gt;
&lt;p&gt;Tak naprawdę największe możliwości daje nam możliwość stworzenia własnych szablonów tego typu. Jeżeli ktoś się zastanawiał jak zaimplementować skrypty korzystające z AJAX-a w Joomla! to odpowiedzią jest: odpowiedni komponent + odpowiedni szablon.&lt;/p&gt;
&lt;p&gt;Komponent w tym wypadku wygeneruje nam odpowiednie dane (załóżmy, że będą one w formacie &lt;i&gt;XML&lt;/i&gt;), a szablon wygeneruje nam zawartość komponentu bez całej zbędnej otoczki jaką stanowi w tym wypadku np. nagłówek dokumentu.&lt;/p&gt;
&lt;p&gt;Wystarczy stworzyć w głównym katalogu naszego szablonu plik &lt;strong&gt;ajax.php&lt;/strong&gt; o następującej zawartości:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;?php

    $document =&amp;amp; JFactory::getDocument();
    $document-&amp;gt;setMimeEncoding('application/xml');
    
    defined( '_JEXEC' ) or die( 'Restricted access' );

?&amp;gt;

&amp;lt;jdoc:include type="component" /&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Pierwsze dwie linijki powodują zmianę wyjściowego typu MIME dokumentu (jeżeli chcemy otrzymywać dane w formacie JSON to wystarczy zmienić atrybut metody &lt;strong&gt;setMimeEncoding&lt;/strong&gt;), kolejna linijka uniemożliwia zdalne wywoływanie naszego szablonu, a treść naszego szablonu stanowi zawartość komponentu zależna od parametrów zawartych w adresie strony.&lt;/p&gt;
&lt;p&gt;Od teraz każde wywołanie strony gdzie w adresie znajdzie się zmienna &lt;strong&gt;tmpl&lt;/strong&gt; o wartości &lt;strong&gt;ajax&lt;/strong&gt; spowoduje wykorzystanie naszego nowego szablonu. Przykładowo adres:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;index.php?option=com_ajax&amp;amp;tmpl=ajax&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Spowoduje wygenerowanie danych udostępnianych na stronie komponentu &lt;strong&gt;com_ajax&lt;/strong&gt; z użyciem szablonu &lt;strong&gt;ajax.php&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Usuwając zmienną &lt;strong&gt;tmpl&lt;/strong&gt; z adresu wyświetlimy zawartość komponentu w tradycyjny sposób.&lt;/p&gt;
&lt;p&gt;W ten sposób możemy łatwo tworzyć szablony odgórnie określające format wyjścia danych z komponentu. Można też teoretycznie korzystać ze zmiennej format w adresie, ale wymaga ona zdefiniowania w komponencie odpowiednich widoków odpowiadających danemu formatowi wyjścia, a dzięki prezentowanemu sposobowi robimy wszystko tylko raz zamiast robić to dla każdego komponentu oddzielnie.&lt;/p&gt;
&lt;p&gt;Przy okazji warto też wspomnieć, że dla danego szablonu można dosyć w łatwy sposób zmieniać formaty wyjścia - np. w wypadku szablonu &lt;strong&gt;ajax.php&lt;/strong&gt; pożądanymi formatami byłyby &lt;i&gt;JSON&lt;/i&gt; i &lt;i&gt;XML&lt;/i&gt; - nie ma sensu tworzyć dwóch oddzielnych szablonów - wystarczy zdefiniować dodatkową zmienną np. &lt;strong&gt;output&lt;/strong&gt; i w zależności od jej wartości generować odpowiedni typ MIME dla dokumentu.&lt;/p&gt;
&lt;p&gt;Na koniec przykładowy kod takiego szablonu z użyciem klasy &lt;strong&gt;JRequest&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;?php

$format = JRequest::getCmd('output') == 'json' ? 'application/json' : 'application/xml'; 

$document =&amp;amp; JFactory::getDocument();
$document-&amp;gt;setMimeEncoding($format);
defined( '_JEXEC' ) or die( 'Restricted access' );

?&amp;gt;

&amp;lt;jdoc:include type="component" /&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Oczywiście jak widać w ramach lenistwa - gdy podamy jakąkolwiek wartość zmiennej &lt;strong&gt;output&lt;/strong&gt; (lub jej nie podamy) inną niż &lt;strong&gt;json&lt;/strong&gt; wtedy otrzymamy dane w formacie XML.&lt;/p&gt;
&lt;p&gt;Na koniec dodam jeszcze, że warto rozważyć stosowanie wspomnianych szablonów np. do tworzenia mobilnych wersji szablonów czy różnych odmian szablonu odgórnie pozbawionych pewnych pozycji modułów.&lt;/p&gt;
</description><pubDate>Thu, 04 Mar 2010 20:10:17 +0100</pubDate><guid>http://joomla.jogger.pl/2010/03/04/wbudowane-szablony-w-joomla/</guid><category>dev</category><category>joomla</category><category>szablony</category><category>Techblog</category></item><item><title>DomReady i MooTools 1.11</title><link>http://joomla.jogger.pl/2010/02/25/domready-i-mootools-1-11/</link><description>&lt;p&gt;Joomla! 1.5 oraz większość jej rozszerzeń w skryptach JavaScript korzysta z MooTools 1.11, które jak już &lt;a href="http://blog.dziudek.pl/2009/11/08/domcontentloaded/"&gt;kiedyś&lt;/a&gt; wspominałem ma czasem problem z obsługą zdarzenia &lt;strong&gt;DomReady&lt;/strong&gt; w przeglądarkach IE.&lt;/p&gt;
&lt;p&gt;Jeżeli nie chcemy oglądać błędów postaci:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;Wiadomość: HTML Parsing Error: 
Unable to modify the parent container element before the 
child element is closed (KB927917)
Wiersz: 0
Znak: 0
Kod: 0&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;To proponuję dodać poniższy fragment kodu na końcu pliku &lt;strong&gt;mootools.js&lt;/strong&gt; z katalogu &lt;strong&gt;media&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;Element.Events.domready = {
        add: function(fn){
                if (window.loaded){
                        fn.call(this);
                        return;
                }
                var domReady = function(){
                        if (window.loaded) return;
                        window.loaded = true;
                        window.timer = $clear(window.timer);
                        this.fireEvent('domready');
                }.bind(this);
                if (document.readyState &amp;amp;&amp;amp; window.webkit){
                        window.timer = function(){
                                if (['loaded','complete'].contains(document.readyState)) domReady();
                        }.periodical(50);
                } else {
                        window.addListener("load", domReady);
                        document.addListener("DOMContentLoaded", domReady);
                }
        }
};&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Zamiast szukać wszystkich skryptów z linijką:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;window.addEvent("domready", function(){&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I zamieniać jej na:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;window.addEvent("load", function(){&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;To rozwiązanie ma ten plus, że w normalnych przeglądarkach (innych niż IE) zdarzenie &lt;strong&gt;domready&lt;/strong&gt; będzie cały czas działało jako &lt;strong&gt;domready&lt;/strong&gt;, a tylko w IE zostanie od razu zamienione na zdarzenie &lt;strong&gt;load&lt;/strong&gt;.&lt;/p&gt;
</description><pubDate>Thu, 25 Feb 2010 00:12:03 +0100</pubDate><guid>http://joomla.jogger.pl/2010/02/25/domready-i-mootools-1-11/</guid><category>dev</category><category>joomla</category><category>mootools</category><category>szablony</category><category>Techblog</category><category>mootools szablony dev</category></item><item><title>Dla pewności</title><link>http://joomla.jogger.pl/2010/02/23/dla-pewnosci/</link><description>&lt;p&gt;Dziś krótki wpis z dosyć istotną wskazówką związaną ze stylowaniem rozszerzeń dla Joomla!. Otóż Joomla! oferuje nam dostęp do sekcji &lt;strong&gt;head&lt;/strong&gt; dokumentu, dzięki czemu z poziomu modułu/komponentu możemy w łatwy sposób dodać skrypt lub styl CSS. I niektórzy developerzy z tej możliwości chętnie korzystają żeby np. uniknąć osadzania elementów &lt;strong&gt;link&lt;/strong&gt; wewnątrz sekcji &lt;strong&gt;body&lt;/strong&gt; witryny (co zresztą powoduje błędy walidacji). Sam dostęp i operacje na sekcji &lt;strong&gt;head&lt;/strong&gt; szablonu dla Joomla! opiszę w jednym z najbliższych wpisów, gdyż jest to dość ważny i szeroki temat, a póki co mały trick, który może być przydatny gdy tworzymy np. szablon w wersji dla urządzeń mobilnych.&lt;/p&gt;
&lt;p&gt;Gdy tworzymy jakiś szablon okrojony z większości gadżetów - taki jak na przykład layout dla iPhone, chcemy mieć pewność, że załadujemy tylko te style CSS, których potrzebujemy (można by tu jeszcze uwzględnić kwestie oszczędności transferu). Jak wspominałem niektóre rozszerzenia np. K2 dodają style bezpośrednio do sekcji &lt;strong&gt;head&lt;/strong&gt; - jeżeli nie chcemy tworzyć ręcznie znaczników typu &lt;strong&gt;title&lt;/strong&gt;, &lt;strong&gt;meta&lt;/strong&gt; i po prostu bardzo potrzebujemy w naszym szablonie zapisu:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;jdoc:include type="head" /&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;a dodatkowo chcemy mieć pewność, że żaden zewnętrzny komponent nie będzie ładował w naszym szablonie swoich styli CSS, to musimy się ich pozbyć. Jak to zrobić ?&lt;/p&gt;
&lt;p&gt;Rozwiązaniem jest poniższy kod, który najlepiej umieścić gdzieś pod koniec kodu naszego szablonu:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;        &amp;lt;?php
                $document =&amp;amp; JFactory::getDocument();
                $headData = $document-&amp;gt;getHeadData();
                $headData["styleSheets"] = array();
                $document-&amp;gt;setHeadData($headData);
        ?&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Oczywiście jeżeli mamy zainstalowane na serwerze PHP5 to możemy pozbyć się operatora &lt;strong&gt;=&amp;amp;&lt;/strong&gt; z pierwszej linijki.&lt;/p&gt;
&lt;p&gt;Prezentowany skrypt wczytuje do zmiennej zawartość sekcji &lt;strong&gt;head&lt;/strong&gt; naszego szablonu, czyści tablicę styli CSS, a nastepnie zapisuje sekcję &lt;strong&gt;head&lt;/strong&gt; w nowej wersji. Dzięki temu mamy pewność, że użytkownik wchodząc na podstronę z komponentem nie zobaczy stylowania charakterystycznego dla danego komponentu, co w niektórych wypadkach bez usunięcia styli wyglądałoby dość tragicznie na telefonach.&lt;/p&gt;
&lt;p&gt;I jeszcze mała uwaga na koniec - w powyższym kodzie sekcję head rozumiemy jako pewną strukturę przechowującą informacje o różnych znacznikach umieszczanych potem na stronie poprzez zapis:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;jdoc:include type="head" /&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Owa struktura nie jest równoznaczna całej zawartości naszej sekcji &lt;strong&gt;head&lt;/strong&gt;, gdyż poza tym zapisem możemy sami ręcznie dodać własne style CSS lub skrypty, które w tej strukturze nie będą widoczne.&lt;/p&gt;
</description><pubDate>Tue, 23 Feb 2010 21:56:56 +0100</pubDate><guid>http://joomla.jogger.pl/2010/02/23/dla-pewnosci/</guid><category>dev</category><category>joomla</category><category>szablony</category><category>Techblog</category><category>joomla dev szablony</category></item></channel></rss>

