<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Moja pasja programowanie...</title><link>http://blog.jkral.info/</link><description>Wpisy z dziennika internetowego Jogger, wspomaganego przez Jabbera</description><lastBuildDate>Sun, 08 Nov 2009 08:36:31 +0100</lastBuildDate><generator>JoggerPL</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Jony" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Moje jabłuszko - Macbook Pro 15,4''</title><link>http://feedproxy.google.com/~r/Jony/~3/yq0yODmUhmw/</link><description>Tydzień temu zamówiłem w sklepie internetowym nowy komputer. Co prawda na przesyłkę musiałem czekać prawie tydzień ale mniejsza z tym… W końcu otrzymałem paczkę.
 
W środku było ładne pudełko-walizeczka. W sumie nic specjalnego, ale zawartość była dość wyjątkowa - Macbook Pro 15.4''. Od razu zabrałem komputer do swojego pokoju i wziąłem się za testowanie sprzętu i systemu. Ponieważ MacOS X widziałem tylko kilka razy w sklepie, na screenach i filmikach tak na prawdę nie wiedziałem czego się mogę spodziewać. Mile się zaskoczyłem. Na starcie otrzymałem OS z pełnym zestawem niezbędnych aplikacji. Organizacja mojej, co prawda niezbyt wielkej, biblioteki zdjęciowej zajęła mi dosłownie 5 sekund. Wystarczyło, że uruchomiłem iPhoto i dzięki fukncji events (zdarzenia) fotogtafie zostały podzielone na coś w rodzaju albumów. Dzięki temu nie miałem już stosu kilkuset zdjęć, a ładnie posegregowane pliki. Podzielenie zdjęć na albumy zajęło mi niecałe 3 minuty, ponieważ można było wykorzystać wyżej wspomniane zdarzenia. Na wcześniejszym komputerze do słuchania muzyki używałem iTunes, dlatego tutaj nie odczułem żadnych zmian. Z racji tego, że lubię mieć porządek w plikach, system Apple bardzo mi przypadł do gustu pod tym względem.
Jeśli chodzi o narzędzia internetowe (Mail i Safari)… O ile nie jestem wybredny odnośnie klientów pocztowych i Mail jak najbardziej zaspokaja moje potrzeby, to nie mogę się przekonać do przeglądarki internetowej. Pewnie jest to kwestia czystego przyzwyczajenia, a nie złej funkcjonalności programu, ale zdecydowałem się pobrać Firefox'a. Może kiedyś jeszcze spróbuję Safari, na razie jednak usunąłem skrót z Docka.
A skoro mowa o Docku. Systemy Windows i Linux pozwoliły mi cieszyć się podobną funkcjonalnością. Nie mam jakichś specjalnych wrażeń z używania tego elementu systemu. Jedno co mnie szczególnie zainteresowało to funkcja stacks (stosy). Jednym kliknięciem mogę zajrzeć do ostatnio pobieranych plików, czy swoich dokumentów bez potrzeby grzebania w dzewie folderów i bez śmiecenia pulpitu (a raczej biurka :P). Poza tym programy minimalizowane do Dock'a wyglądają o niebo lepiej niż na belce systemowej.
Konfiguracja internetu, połączenia LAN i Bluetooth (z telefonem) nie sprawiła mi żadnych problemów. Wszystko to po prostu działa - nie muszę nic dodatkowo instalować, ani korzystać z lekko przydługawych konfiguratorów połączenia. Wybieram odpowiednią opcję, wprowadzam konieczne dane i połączenie jest gotowe do używania.
Wrócę może do samego komputera. Podczas pierwszego uruchomienia wbudowana kamera iSight robi nam zdjęcie i ustawia je w profilu. Fotka jest w bardzo dobrej jakości, co jest dość dużą zmianą względem mojego poprzedniego komputera. Będę jeszcze musiał ją przetestować w transmisji internetowej, ale raczej moje zdanie o wbudowanej kamerze się nie zmieni - jest bardzo fajna i nie zajmuje dodatkowego miejsca na biurku, ani nie wisi bzydko na obudowanie laptopa.
Klawiatura posiada przypisanych kilka funkcji do klawiszy F1-F12. Służą one między innymi do regulacji podświetlenia ekranu/klawiatury, sterowania multimediami i głośnością oraz do pokazywania Dashboard oraz Expose. Poza tym w najwyższym rzędzie mamy dodatkowy klawisz do wysuwania płyty z napędu. Jedyną moją bolączką jest inne położenie klawisza Alt, co powoduje nieco zamieszania przy szybkim pisaniu. Skróty kopiuj, wklej, zapisz, zmień okno(alt+tab) są obsugiwane przez klawisz cmd (czy jabłuszko jak ktoś woli), do czego też na razie nie mogę się przyzwyczaić.
Gładzik multitouch bardzo miło mnie zaskoczył. Poza standardową funkcjonalnością - sterowanie myszką - mamy kilka przydanych funkcji. Przesuwanie dwoma palcami w górę i w dół przesuwa aktualnie otwarty dokument, przesuwanie trzeba palcami pozwala zmieniać np. zdjęcia w prezentacji. Zsuwając i rozsuwając dwa palce możemy pomniejszać i powiększać miniaturki zdjęć w katalogu, a obracając dwoma palcami możemy obrócić aktualnie oglądany dokument (zdjęcie, pdf).
Podsmowując: jestem bardzo zadowolony z zakupu mimo dość wysokiej ceny. Sprzęt oraz system są pierwszej klasy i z powodzeniem wystarczy na kilka lat użytkowania. Poza tym laptop z nadgryzionym jabłkiem na klapie powoduje silną zazdrość u osób siedzących obok w przedziale pociągu :) Jeśli ktoś zastanawia się nad zakupem podobnego sprzętu to serdecznie polecam. Jeśli ktoś boi się przesiadki na nowy system, to powiem że moja migracja odbyła się praktycznie bezboleśnie.
</description><pubDate>Sun, 24 Aug 2008 16:25:47 +0200</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/08/24/moje-jabluszko-macbook-pro-15-4/</guid><category>Apple</category><category>Prywatne</category><category>macbook apple laptop zakup</category><feedburner:origLink>http://blog.jkral.info/2008/08/24/moje-jabluszko-macbook-pro-15-4/</feedburner:origLink></item><item><title>Kiedy parsowanie XML w Pythonie crashuje Apache...</title><link>http://feedproxy.google.com/~r/Jony/~3/pJlF_TUtYRw/</link><description>Ostatnio podczas próby napisania webowej aplikacji w Pythonie, która miała między innymi parsować pliki XML natrafiłem na bardzo dziwny problem. Skrypt oparty był o framework Django. Podczas użycia metody xml.dom.minidom.parse() aplikacja się wykładała - nie zwracała żadnych błędów, a w przeglądarce widać było tylko białe okno. Jak zwykle przekopywanie polskiego internetu w poszukiwaniu odpowiedzi nic nie dało.

Okazało się, że problem tkwi w bibliotece Expat. Jest ona używana przez moduł xml.dom do parsowania kodu XML. W logach Apache można znaleźć taki oto wpis:

[notice] child pid 3238 exit signal Segmentation fault (11)

Okazuje się, że Apache może domyślnie używać innej wersji expat`a niż Python. Dzieją się wtedy różne dziwne rzeczy, w które nie będę się wgłębiał, bo właściwie nie ma po co. Ale jak sprawdzić, czy to jest rzeczywiście źródłem naszego problemu?

Najpierw należy sprawdzić jakiej wersji biblioteki używa Apache. W tym celu wydajemy polecenie (ścieżka do httpd może się nieco różnić od podanej):

ldd /usr/sbin/httpd | grep expat

Jako wynik powinniśmy otrzymać coś w rodzaju:

libexpat.so.0 =&gt; /usr/lib/libexpat.so.0 (0xb7e8c000)

Interesuje nas tylko ścieżka podana po strzałce. Wskazuje ona na plik używany przez nasz serwer. Sama nazwa nam nic nie powie, dlatego należy wyciągnąć numer wersji:

strings /usr/lib/libexpat.so.0 | grep expat_

Otrzymana odpowiedź powinna być podobna do tej:

expat_1.95.8

Musimy się jeszcze upewnić, że żadne zmienne systemowe nie wpływają na ścieżkę bibliotek ładowanych do Apache (np. LD_LIBRARY_PATH) i dowiedzieć jaki proces uruchomił serwer. W tym celu wykonujemy polecenie:

ps aux | grep http | head -3

Uwagę należy zwrócić na drugą kolumnę, w której to pokazany jest identyfikator procesu. Następnie wykonujemy komendę:

sudo lsof -p PID | grep expat

, gdzie PID należy zastapić identyfikatorem właściwego procesu. W ten sposób otrzymaliśmy listę plików, używanych przez dany proces. Przykładowy wynik polecenia:

httpd   3625 root  mem    REG     253,0   123552    6409040 /usr/lib/libexpat.so.0.5.0

Jak widać plik używany przez Apache okazał się nieco inny niż otrzymany wcześniej. Aby sprawdzić ostatecznie wersję Expat`a wykonujemy wcześniej już używane polecenie strings:

strings /usr/lib/libexpat.so.0.5.0 | grep expat_


Sprawdzenie wersji expat`a używanej przez Pythona jest nieco łatwiejsze:

python
&gt;&gt;&gt; import pyexpat
&gt;&gt;&gt; pyexpat.version_info

W odpowiedzi możemy dostać:

(1, 95, 7)


Jak widać Apache i Python używają różnych wersji Expat (odpowiednio 1.95.8 i 1.95.7). Sprawienie, aby oba programy ładowały odpowiednią wersji biblioteki wykonujemy polecenie:

LD_PRELOAD=/usr/lib/libexpat.so.0.5.0

Można teraz ponownie sprawdzić wersję ładowaną przez Pythona wykonując kroki opisane w poprzednim paragrafie.

Źródło: http://www.dscpl.com.au/wiki/ModPython/Articles/ExpatCausingApacheCrash
</description><pubDate>Wed, 11 Jun 2008 16:08:07 +0200</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/06/11/kiedy-parsowanie-xml-w-pythonie-crashuje-apache/</guid><category>Linux</category><category>Python</category><category>Techblog</category><category>apache expat xml crash python linux</category><feedburner:origLink>http://blog.jkral.info/2008/06/11/kiedy-parsowanie-xml-w-pythonie-crashuje-apache/</feedburner:origLink></item><item><title>Firefox Download Day</title><link>http://feedproxy.google.com/~r/Jony/~3/Wsb311jfSK0/</link><description>Jak się okazuje dzień udostępnienia nowej wersji aplikacji nie musi być zwykłym dniem. Mozilla ogłosiła datę udostępnienia Firefox`a 3 dniem pobierania. Planowane jest pobicie rekordu Guinnessa w ilości pobrań programu komputerowego w ciągu 24 godzin. Można już teraz zadeklarować chęć pobrania Firefox`a. Jeśli w deklaracji umieścimy swój adres e-mail dostaniemy powiadomienie o dokładnej dacie udostępnienia nowej wersji przeglądarki spod znaku płonącego liska. To jednak nie wszystko. Można zarejestrować imprezę dla pobierających FF w dniu premiery.
Jak widać Mozilla potrafi zadbać o promocję swojego najnowszego produktu. Chyba nawet prezentacja nowych systemów z rodziny Windows nie budzi aż takich emocji. Pozostaje jednak pytanie, czy premiera nowej wersji programu powinna być traktowana jako święto? W końcu to tylko udostępnienie "kilku" skompilowanych linijek kodu.
</description><pubDate>Thu, 29 May 2008 16:50:46 +0200</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/05/29/firefox-download-day/</guid><category>Inicjatywy</category><category>Ogólne</category><category>firefox</category><category>moziia</category><category>premiera</category><category>download day</category><feedburner:origLink>http://blog.jkral.info/2008/05/29/firefox-download-day/</feedburner:origLink></item><item><title>Trochę o OOP</title><link>http://feedproxy.google.com/~r/Jony/~3/YZkRVu78RIA/</link><description>OOP jest już dostępne w coraz to większej ilości języków programowania. Właściwie język bez obsługi OOP, chociaż w podstawowym stopniu, nie ma już racji bytu. Prawdziwy bum na programowanie obiektowe miał miejsce, gdy pojawiła się nowa wersja PHP oznaczona numerem 5 (co prawda wcześniejsze wersje też udostępniały klasy i obiekty, ale nie można było tego nazwać nawet szczątkową obsługą OOP). Gros osób piszących właśnie w tym języku odkryło możliwości jakie niosła ze sobą, zupełnie nowa dla niektórych, funkcjonalność. Zauważyłem jednak, że wielu młodych programistów nie rozumie na czym tak na prawdę polega programowanie obiektowe. W internecie znajduje się wiele "kursów" używających sławnych już przykładów "pojazd - rower" lub "roślina - kwiat". Nie zawsze jednak takie porównania pozwalają w pełni zrozumieć ideę OOP.
Chcę jeszcze pokrótce wyjaśnić dlaczego warto zainteresować się programowaniem zorientowanym obiektowo. Pierwszym, i chyba najważniejszym, jest abstrakcyjność. Kiedy używamy jakiejś klasy/obiektu nie musimy znać dokładnie sposobu w jaki on funkcjonuje. Wystarczy, że opanujemy dostępne w nich metody, aby skutecznie nimi manipulować. Drugą ważną cechą jest łatwość późniejszego rozwoju aplikacji. Aby wprowadzić nową funkcjonalność, lub stworzyć nową nie trzeba modyfikować kodu w wielu miejscach. W pewien sposób cecha ta łączy się z pierwszą. Wszystkie zmiany można ukryć wewnątrz klas, co umożliwi nam pozostawienie właściwego kodu aplikacji bez zmian. Ostatnią własnością OOP jest lepsze odzwierciedlenie sposobu myślenia zwykłego człowieka. Zamiast wywoływania funkcji, nie mających wiele wspólnego z rzeczywistością wykonuje się operacje na "realnych obiektach" takich jak plik, pozycja w menu strony, lub też użytkownik serwisu internetowego.
Zakładam, że znane są Ci pojęcia takie jak klasa, obiekt, metoda itp. Nie będę ich tutaj objaśniał, gdyż w internecie dostępnych jest mnóstwo materiałów na ten temat. Na początek chcę rozdzielić dwa, najczęściej używane typy klas. Od strony technicznej nie różnią się one od siebie niczym, cały mankament tkwi w podejściu do użyteczności klasy. Pierwszy typem (określanym przeze mnie jako typ podstawowy) jest klasa rzeczywista. Są to klasy reprezentujące "realne obiekty" wymienione w poprzednim akapicie. Można je określić jako opis własności każdego z tych przedmiotów. Dodatkowo wewnątrz takiej klasy możemy stworzyć metody (operacje) realizujące różne czynności związane z obiektem. Posłużę się często używanym w praktyce przykładem, który powinien w lepszym stopniu odzwierciedlać ideę klasy rzeczywistej.

Klasa news:
# własności
- identyfikator
- tytuł
- treść
- autor
- data dodania
- grafika

#metody
- zapisz
- skasuj
- ustaw tytuł
- ustaw treść
- ustaw autora
- ustaw datę dodania
- ustaw grafikę
- konstruktor #pobiera z bazy dane newsa o podanym identyfikatorze, jeśli nie podany żaden identyfikator pozostawia pusty obiekt

Jak widać powyższa klasa określa prostego newsa, na którego składają się podstawowe elementy - własności. Do obsługi (tj. zmiany, usunięcia) obiektów tej klasy służą zdefiniowane metody. Oto przykład praktycznego użycia tej klasy (nazwy metod i własności zostały nieco zmienione ze względu na wymagania języka programowania).

{geshi lang=php}



{/geshi}Jeśli jesteś początkującym programistą PHP to widzisz, że kod staje się bardziej przejrzysty. Ominięta została warstwa obsługi bazy danych - to jest właśnie abstrakcja. Cała logika operacji została usunięta z kodu programu. Jeśli chcesz zmienić sposób łączenia się z bazą wystarczy zmodyfikować klasę, a program pozostaje bez zmian.

Drugim typem klas są klasy biblioteczne. W przeciwieństwie do typu omawianego przed chwilą, ten nie reprezentuje żadnego "rzeczywistego" obiektu, a jest jedynie zbiorem funkcji (metod). Można na przykład stworzyć klasę realizują różne sposoby szyfrowania i deszyfrowania danych.

Klasa szyfrowanie:
- szyfruj md5
- szyfruj sha
- szyfruj RSA
- deszyfruj RSA

Metody zawarte w tej klasie zwane są metodami statycznymi. Oznacza to, że nie wykonują operacji na konkretnej instancji danej klasy (tj. na konkretnym obiekcie). Można je wywoływać bez tworzenia obiektu.

{geshi lang=php}

{/geshi}
Podsumowując... klasa powinna reprezentować pewien obiekt (rzeczywisty lub wirtualny), wtedy jest nazywana klasą rzeczywistą. Innym celem użycia klas może być zgromadzenie funkcji o podobnym zastosowaniu w jednym miejscu w celu łatwiejszego ich późniejszego użycia, wtedy mówimy o klasie bibliotecznej. Mam nadzieję, że nieco przybliżyłem główną ideę programowania obiektowego i chociaż część młodych programistów czytających ten wpis zrozumie o co w tym wszystkim chodzi :)
Na koniec mam jeszcze dość ważną uwagę do wszystkich (doświadczonych i tych początkujących). Użyte pojęcia, które są pochylone nie są powszechnie znane, ani używane. Są jedynie moim własnym wymysłem i mają na celu łatwiejszy przekaz mojego sposobu rozumowania i łatwiejszego kojarzenia niektórych elementów.
</description><pubDate>Thu, 22 May 2008 19:32:19 +0200</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/05/22/troche-o-oop/</guid><category>Ogólne</category><category>PHP</category><category>Techblog</category><category>OOP obiekty klasy programowanie</category><feedburner:origLink>http://blog.jkral.info/2008/05/22/troche-o-oop/</feedburner:origLink></item><item><title>J2ME problem z nagłówkiem http Content-Length</title><link>http://feedproxy.google.com/~r/Jony/~3/S1VYQDxnCHg/</link><description>Próbując napisać prostą aplikację na komórki, która łączyłaby się z zewnętrznym serwerem natknąłem się na dość interesujący problem. Serwer za każdym zwracał błąd 411 - Content Length Required. Kod wydawał mi się poprawny, headery zgodne ze specyfikacją, dlatego postanowiłem zasięgnąć rady Pana Googla. Wyniki jego poszukiwań były dość marne. W sumie dowiedziałem się tylko tyle, że problem jest znany. Nie znalazłem jednak żadnej konkretnej informacji jak sobie z nim poradzić.
Używam narzędzia Wireless Toolkit, w którym odkryłem opcję "śledzenia" tego co robi nasza aplikacja. Szybko okazało się, że nagłówek Content-Length w ogóle nie jest wysyłany do serwera. Co dziwne, problem występował tylko podczas używania protokołu http/1.1. Kiedy emulator używał http/1.0 wszystko działało poprawnie. Głębsze poszukiwania w wynikach google nasunęły dwie możliwe przyczyny takiego zachowania. Pierwszą z nich mogła być metoda OutputStreamWriter.flush(). Podobno zastąpienie jej metodą close(); rozwiązywało problem. Jednak w moim przypadku tak się nie stało. Drugi trop wskazywał na błąd w nagłówku Content-Type. Jak się później okazało wystarczy ustawić wartość application/x-www-form-urlencoded zamiast multipart/form-data, aby aplikacja działała poprawnie zarówno przy użyciu http/1.0 jak i http/1.1
Mam nadzieję, że mój wpis zaoszczędzi kilku godzin szukania innym osobom zaczynającym swoją przygodę z J2ME (nie wiem, czy w innych edycjach Javy ten problem też występuje). Jeśli ktoś znający się na rzeczy ma pomysł dlaczego tak się dzieje, to bardzo bym prosił o komentarz.
</description><pubDate>Wed, 23 Apr 2008 21:46:24 +0200</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/04/23/j2me-problem-z-naglowkiem-http-content-length/</guid><category>Java</category><category>Techblog</category><category>j2me</category><category>411</category><category>error</category><category>length</category><category>required</category><feedburner:origLink>http://blog.jkral.info/2008/04/23/j2me-problem-z-naglowkiem-http-content-length/</feedburner:origLink></item><item><title>Z okazji CSS Naked Day...</title><link>http://feedproxy.google.com/~r/Jony/~3/O4Uu9ILWtIk/</link><description>dziś nie ma ostylowania strony. Chyba nie wygląda aż tak strasznie :P
</description><pubDate>Wed, 09 Apr 2008 11:24:56 +0200</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/04/09/z-okazji-css-naked-day/</guid><category>Inicjatywy</category><category>Ogólne</category><category>CSS Naked Day</category><feedburner:origLink>http://blog.jkral.info/2008/04/09/z-okazji-css-naked-day/</feedburner:origLink></item><item><title>Projektowanie serwisu cz.2 - layout</title><link>http://feedproxy.google.com/~r/Jony/~3/3HHLMNAng1g/</link><description>Ten wpis miał się pojawić dobry miesiąc temu. Niestety pokonał mnie brak czasu, za co przepraszam. Żeby nie przedłużać od razu przejdę do właściwego tematu.
Layout w dużym uproszczeniu jest planem jak ma wyglądać nasza strona internetowa. Zazwyczaj umieszcza się na nim jedynie statyczny model strony. Z własnego doświadczenia wiem jednak, że dobrze jest także zaznaczyć sobie wygląd linku po najechaniu myszką, czy linku do strony już odwiedzanej.
Ważną sprawą jest przyjęcie na początku pewnych założeń. Np. podkreślanie/pogrubienie linku tekstowego, obramowanie obrazka będącego odnośnikiem, zaznaczenie działu, w którym obecnie znajduje się użytkownik itp. Nie należy jednak wprowadzać zbyt ekstrawaganckich rozwiązań. Dzięki ustandaryzowaniu pewnych elementów odwiedzający nie będzie miał wątpliwości, czy dany tekst jest linkiem, czy nie. Dobrym rozwiązaniem jest wyróżnienie linków w dłuższym tekście innym kolorem, ponieważ samo podkreślenie nie zawsze rzuca się w oczy. Oczywiście nie powinien być to kolor jaskrawy, a raczej nieco inny odcień koloru zwykłej czcionki.
O kolorystyce stron można by się rozpisać na kilkanaście stron - zwłaszcza jeśli ktoś zajmuje się tworzeniem layoutów na poważnie. Ponieważ w tej dziedzinie nie jestem ekspertem napiszę tylko kilka swoich uwag i spostrzeżeń. Przede wszystkim strony nie powinny być "zimne". Mamy czasy WEB 2.0, strona internetowa powinna być ciepła, miła dla oka, stonowana. Nie należy jednak przesadzać w drugą stronę. Kolory zbyt pstrokate przeszkadzają w skupieniu się na treści, a po dłuższym czasie przebywania na takiej stronie mogą po prostu boleć oczy. Dobrym rozwiązaniem może okazać się połączenie kolorów zimnych i ciepłych. Np. szarość przeplatana z odcieniami czerwieni, zieleni, czy niebieskości. Uzyskamy w ten sposób efekt stonowanej kolorystycznie strony, która cieszy oko, a jednocześnie nie odwraca zbytnio uwagi od treści.
Przejdźmy może teraz do tworzenia wyglądu serwisu od strony technicznej. Przede wszystkim nie należy przesadzać z obrazkami. Co prawda obecnie mało kto ma internet wolniejszy niż 256kbps, jednak po co przedłużać czas ładowania się strony. Kiedy dysponujemy słabszym serwerem, a ilość odwiedzin jest stosunkowo duża każdy zbędny kilobajt to dodatkowe sekundy ładowania się strony. Czasami nawet lepiej jest zrezygnować z jakiegoś "bajeru", który zaplanowaliśmy sobie w layoucie graficznym, a zastąpić go prostszym rozwiązaniem html+css. Uzyskanie niektórych efektów jest po prostu tak kosztowne, że korzyści z niego płynące nie są adekwatne do pracy w nie włożone. Poza tym takie rozwiązania często są dość nieeleganckie pod względem jakości kodu i mogą nie działać pod każdą przeglądarką tak samo (kolejna praca na napisanie odpowiednich hacków dla przeglądarek).
A teraz mój ulubiony temat: semantyka :) Niewiele osób tworzących strony internetowe zdaje sobie sprawy z tego jak wiele znaczników znajduje się w specyfikacji html i xhtml. Oczywiście uczenie się ich wszystkich nie jest najlepszym pomysłem, ale odgraniczanie się do div, ul, li i a to z kolei zwykłe marnotrawstwo. Warto od czasu do czasu zajrzeć w specyfikację i sprawdzić, czy przypadkiem pewnych elementów naszej strony nie można zastąpić innymi znacznikami. Płyną z tego dwie duże korzyści. Po pierwsze ograniczymy ilość klas i elementów posiadających własne id w stylach kaskadowych. Dzięki większej ilości różnych znaczników o wiele łatwiej będzie określać konkretny element strony poprzez wskazanie jego rodziców, lub po prostu przez samą nazwę znacznika, który zazwyczaj prezentuje podobną treść (i ma wyglądać podobnie). Drugą korzyścią jest to, że roboty sieciowe o wiele lepiej indeksują strony, kiedy treść jest zawarta w odpowiednich dla niej znacznikach. Po prostu robot nie jest człowiekiem i trzeba mu powiedzieć, że ten element jest nagłówkiem, ten prezentuje adres pocztowy, a inny wskazuje na cytat. Z kolei stosowanie pewnych znaczników tylko z tego powodu, że ich domyślne style pasują do wyglądu naszej strony może spowodować efekt całkowicie odwrotny. Mówię tutaj o popularnym błędzie podczas używania znacznika nagłówków  (,  ...). Często zdarza się tak, że na stronie występują znaczniki , a nigdzie nie można się doszukać  ani . Kolejne znaczniki nagłówków (z większym indeksem) służą do oznaczania podrozdziałów w tekście. Na przykład:

Rozdział 1
  Część 1
    Wstęp
    Kilka słów wstępu
    Wprowadzenie
    Jakieś wprowadzenie
    Podsumowanie
    Podsumowanie działu
  Część 2

i tak dalej i tak dalej.

Mam nadzieję, że powyższy tekst pozwoli młodym twórcom stron uniknąć błędów, które ja sam często popełniałem. Dobrze jest uczyć się na błędach, ale nie koniecznie na swoich :) Oczywiście jeśli ktoś nie zgadza się z tym co napisałem, lub ma jakiejś zastrzeżenia/uwagi, lub po prostu chce rozwinąć jakiś temat, to zapraszam do komentowania.
</description><pubDate>Thu, 28 Feb 2008 20:30:04 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/02/28/projektowanie-serwisu-cz-2-layout/</guid><category>Projektowanie serwisu</category><category>Techblog</category><category>projektowanie serwisu layout</category><feedburner:origLink>http://blog.jkral.info/2008/02/28/projektowanie-serwisu-cz-2-layout/</feedburner:origLink></item><item><title>Projektowanie serwisu cz.1 - ogólny zarys</title><link>http://feedproxy.google.com/~r/Jony/~3/iFb6AVeERSs/</link><description>Pierwszy wpis z tej serii będzie nieco ogólny i teoretyczny. Co należy sobie przygotować zanim w ogóle zacznie się pracę z pisaniem kodu? Przede wszystkim należy mieć pomysł. Trzeba wcześniej już sobie wyobrazić jak serwis ma funkcjonować, jakie ma spełniać zadania itp. - oczywiście dość ogólnie.
Następnie najlepiej jest rozpisać na kartce poszczególne moduły/funkcjonalności. Według mnie najważniejszy jest system uprawnień, dlatego planowanie powinno się zacząć od niego. To jak będzie wyglądał zależy od rodzaju serwisu jaki planujemy, ale też od jego wielkości i tego, kto nim będzie zarządzał. Zazwyczaj wystarczają 3 lub 4 poziomy uprawnień - admin, moderator, użytkownik i gość. Jeśli chcemy możemy pokusić się o dynamiczne uprawnienia, czyli oddzielne przyznawane dla każdego zarejestrowanego. Jeżeli mamy na przykład serwis podzielony na kilka działów możemy poszczególnym moderatorom/redaktorom przyznać uprawnienia dodawania/edycji tylko w dziale, którym się zajmują. Takie rozwiązanie ma swoje wady i zalety. Główną zaletą jest to, że przestrzegamy tzw. zasady minimalnych uprawnień. Wadą, dość poważną jeśli admin nie ma doświadczenia w prowadzeniu serwisu, może okazać się skomplikowany interface nadawania uprawnień. Wszystko zależy jednak od sposobu w jaki go zaimplementujemy. Poza tym dość uciążliwe może okazać się nadawanie oddzielnych uprawnień kilkunastu moderatorom. Dobrym rozwiązaniem jest równoległe zastosowanie kilku predefiniowanych modeli uprawnień. W innym wypadku administracja serwisem mogłaby okazać się na prawdę uciążliwa.
Dobrą sprawą jest podzielenie całego serwisu na oddzielne moduły. Dzięki rozdzieleniu niektórych elementów strony będzie można w większym stopniu później nimi manipulować i nadawać specyficzne uprawnienia. Jako moduł w tym wypadku rozumiem na przykład: menu, artykuły, newsy, czat/shoutbox, każdy element panelu administratora. Takie rozwiązanie w połączeniu z odpowiednio rozplanowanym systemem uprawnień pozwoli na zaawansowaną obsługę dostępu do modułów. Jeśli zastosujemy zaawansowany system uprawnień z poprzedniego akapitu będziemy w stanie w bardzo prosty sposób zablokować użytkownikowi dostęp(pełny lub częściowy)do dowolnego modułu. Wystarczy, że każdy moduł będzie sprawdzał uprawnienia użytkownika odnośnie tej części witryny. Dużym ułatwieniem w takim rozwiązaniu jest programowanie obiektowe, ponieważ można stworzyć klasę rodzica - wzór modułu. Każdy nowy moduł dziedziczący z niej nie będzie już musiał martwić się np. o sprawdzanie uprawnień itp. Dodatkowym plusem jest fakt, że zmiana sposobu zapisywania uprawnień nie zmusza nas do edycji kilkudziesięciu(albo i nawet kilkuset)linijek kodu w kilku(nastu)różnych plikach.
Wracając do rozpisywania funkcjonalności. Ja zawsze każdą część strony zapisuję w mniej więcej takiej postaci:

NAZWA MODUŁU
co - czyli krótki opis tego, do czego ma nam się przydać
jak - można sobie ew. pod spodem narysować jakiś niewielki rysunek
kto - dokładne opisanie uprawnień dla poszczególnych grup

W ten sposób uzyskamy klarowny zapis funkcjonalności serwisu. Będziemy w stanie w przystępny sposób przekazać naszą wizję komuś innemu. Po określeniu tego podstawowego planu dobrze jest schować go do szuflady na 4-5 dni. Po tym okresie jeszcze raz go przejrzeć i przemyśleć. W ten sposób będziemy pewni, iż umieściliśmy takie elementy, które pozwolą nam osiągnąć maksimum funkcjonalności.
Ostatnim etapem jest dokładne zaplanowanie każdego modułu serwisu. W szkicu powinno uwzględnić się każdy możliwy do przewidzenia scenariusz zachowania użytkownika skryptu i wypracować odpowiednią odpowiedź. Należy starać się przewidzieć nietypowe zachowania odbiorcy. W końcu nie każdy musi myśleć tak jak my. Dobrze jest pokazać taki plan innej osobie znającej zagadnienie, aby w razie braków dodać nową akcję i reakcję. Podobnie jak opis całego projektu dobrze jest zostawić szkice modułów na kilka dni, żeby się "przegryzły". Po pewnym czasie zaczynamy patrzeć na pewne sprawy z innej strony, dzięki czemu zredukujemy prawdopodobieństwo pomyłki do minimum.
Jak już wspomniałem wpis ten jest nieco teoretyczny, jednak faza projektowania funkcjonalności jest bardzo ważna. Pozwala uniknąć nagłych zmian koncepcji podczas, gdy część kodu jest już gotowa. Jednym słowem - oszczędzamy czas i energię. Mam nadzieję, że całość nie jest napisana zbyt chaotycznie i niezrozumiale. Proszę także o wyrozumiałość, ponieważ jest to mój pierwszy wpis tego typu.
</description><pubDate>Wed, 09 Jan 2008 17:34:34 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/01/09/projektowanie-serwisu-cz-1-ogolny-zarys/</guid><category>Projektowanie serwisu</category><category>Techblog</category><category>projektowanie serwisu zarys</category><feedburner:origLink>http://blog.jkral.info/2008/01/09/projektowanie-serwisu-cz-1-ogolny-zarys/</feedburner:origLink></item><item><title>Seria tematyczna - planowanie serwisu internetowego</title><link>http://feedproxy.google.com/~r/Jony/~3/zt0ugWNNSVQ/</link><description>Ostatnio trochę zaniedbałem swojego bloga. 1-2 notki miesięcznie to mniej niż planowałem na początku. Do głowy wpadł mi pomysł, aby napisać serię wpisów tematycznych. Temat: "Planowanie serwisu internetowego". Na Joggerze widziałem już kilka serii o podobnej tematyce, jednak ja chcę podejść do sprawy tak, aby ktoś z niewielkim doświadczeniem mógł się dowiedzieć jakich błędów należy unikać.
Zazwyczaj będę podchodził do sprawy bardziej teoretycznie, ale myślę, że nie zabraknie przykładów. Będą to na pewno sprawdzone rozwiązania, których sam używam. Przy okazji sam będę mógł zweryfikować niektóre kody źródłowe, które napisałem wcześniej, z punktu widzenia programisty już nieco bardziej doświadczonego.
Od przyszłego tygodnia planuję dodawać 1-2 wpisy miesięcznie tak, żeby każdy mógł przemyśleć to co napisałem i ew. mnie poprawić. W końcu nie ma ludzi nieomylnych, a ja z kolei nie jestem jakimś mega weteranem webmasteringu, który ma szerokie pojęcie w każdej dziedzinie. Dlatego liczę na Waszą pomoc, jakieś sugestie, poprawki.
Mam nadzieję, że moje wpisy przypadną Wam do gustu i, że niektórzy czegoś się z nich nauczą.
</description><pubDate>Wed, 09 Jan 2008 12:25:54 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/01/09/seria-tematyczna-planowanie-serwisu-internetowego/</guid><category>Projektowanie serwisu</category><category>seria</category><category>planowanie serwisu</category><category>porady</category><feedburner:origLink>http://blog.jkral.info/2008/01/09/seria-tematyczna-planowanie-serwisu-internetowego/</feedburner:origLink></item><item><title>Moje Jabłuszko</title><link>http://feedproxy.google.com/~r/Jony/~3/gMsLORPZpO0/</link><description>Niedawno został wydany pierwszy numer nowego czasopisma "Moje Jabłuszko". Traktuje ono jak można się domyślić o komputerach pod znaku nadgryzionego jabłka. Wydawane jest w wersji elektronicznej (PDF), jest darmowe, więc każdy może sobie ściągnąć i przeczytać. Jeśli ktoś nie lubi czytać na komputerze zawsze może sobie wydrukować.
Oprawa graficzna jest moim zdaniem ładna. Nie odwraca uwagi od treści, choć czasem obrazki są zbyt dużej, zajmują większą część strony, tekst jest wciśnięty gdzieś pod spodem i wtedy ciężko się go czyta. Poza tym ogólnie zdjęcia mogłyby być nieco mniejsze, ale to nie jest problem.
Co do treści... zauważyłem, że w pierwszym numerze autorzy postawili nieco na przekonanie użytkowników PC-tów do komputerów Mac. Moim zdaniem nie jest to głupi pomysł, bo nawet w okresie dużego zainteresowania firmą Apple krążą po internecie pewne stereotypy - podobnie zresztą jak w przypadku systemu GNU/Linux. Na pewno podbudowujący jest artykuł o nowej klawiaturze, która posiada już prawy Alt. Pokazane jest, że ludzie pracują na tych komputerach od lat i jest im dobrze, że nie muszą cały czas kombinować żeby coś działało, nie mają problemu z niedziałającym systemem itp. Dodatkowo opisane są "miejsca" w internecie, w których można znaleźć więcej informacji, ew. jakąś pomoc dotyczącą produktów firmy Apple. To również wpływa pozytywnie w oczach czytelnika, ponieważ sam może się przekonać np. jakie problemy mają systemu Mac OS X po przesiadce z Windowsa. Mnie w każdym razie takie podejście cieszy, gdyż odbiorca jest świadomy tego, że redaktorzy czasopisma nie mydlą mu oczu propagandowymi hasłami, tylko mają poparcie swoich słów na konkretnych stronach.
Ogólnie pomysł czasopisma mi się podoba. Podobno kiedyś było już jakieś wydawane, ale inicjatywa upadła. Miejmy nadzieję, że tym razem projekt utrzyma się długo i zbierze pewną społeczność wokół siebie.
</description><pubDate>Thu, 03 Jan 2008 19:57:04 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2008/01/03/moje-jabluszko/</guid><category>Apple</category><category>Inicjatywy</category><category>Ogólne</category><category>moje jabłuszko</category><category>czasopismo</category><feedburner:origLink>http://blog.jkral.info/2008/01/03/moje-jabluszko/</feedburner:origLink></item><item><title>[Linux - Debian]Słynny już problem z nowym kernelem</title><link>http://feedproxy.google.com/~r/Jony/~3/3tBdQy3DhlY/</link><description>Jak już pisałem wcześniej od niedawna mam zainstalowanego Debiana. System bardzo mi się spodobał, nie miałem żadnych problemów z konfiguracją i instalacją dodatkowego oprogramowania. Szczerze mówiąc zdziwiłbym się gdyby było inaczej, gdyż do sprawnego funkcjonowania nie potrzeba mi więcej niż edytor tekstu, komunikator, odtwarzacz muzyki, klient ftp i konsola :)
Problem pojawił się, kiedy zapragnąłem uaktualnić swoje "jajko" do najnowszej wersji. Otóż okazuje się, że w nowym kernelu zmieniono podejście do dysków (czy coś koło tego - nie znam się na tym zbytnio) i przez to dyski zmieniają swoje oznaczenia z hdx* na sdx*. Nie byłby to problem, gdyby wszystko działało jak należy. Próbowałem już kilka razy ustawiać /etc/fstab i /boot/grub/menu.lst, ale za każdym razem podczas uruchamiania systemu z nowym jądrem system staje na: "Waiting for root file system...". Po około 6-7 minutach czekania pokazuje się komunikat podobny do tego (skopiowany od użytkownika z podobnym problemem):

Waiting for root file system... ... 
Done.
         Check root=bootrarg cat /proc/cmdline
         or missing modules, devices: cat /proc/modules ls /dev

ALERT! /dev/sdc2 does not exist. Dropping to a shell!

BusyBox v1.1.3 (Debian 1:1.1.3-4) Built-in shell (ahs)
Enter 'help' for a list of built-in commands.

/bin/sh: can't access tty; job control turned off
(initframs) [i tutaj konsolka jakaś dziwna]

Oczywiście kiedy w konsoli wylistuję sobie zawartość /dev to bez problemu znajduje /dev/sdc2 i wszystkie inne partycje. Jeśli ktoś zna rozwiązanie tego problemu bardzo proszę o pomoc.

</description><pubDate>Wed, 19 Dec 2007 20:25:22 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2007/12/19/linux-debian-slynny-juz-problem-z-nowym-kernelem/</guid><category>Komputery</category><category>Linux</category><category>Prywatne</category><category>debian kernel filesystem problem</category><feedburner:origLink>http://blog.jkral.info/2007/12/19/linux-debian-slynny-juz-problem-z-nowym-kernelem/</feedburner:origLink></item><item><title>Od jutra zagości u mnie Debian</title><link>http://feedproxy.google.com/~r/Jony/~3/4ybF1b2_EuM/</link><description>Od dłuższego czasu noszę się z zamiarem aktualki Ubuntu do 7.10, ale jakoś nie miałem wcześniej czasu. Jak zwykle pewnie coś by się mi sypnęło w systemie i musiałbym instalować go od nowa. Dlatego pomyślałem sobie, czy nie warto byłoby spróbować jakiejś innej dystrybucji? Wybór padł na Debiana - przede wszystkim dlatego, że jest stabilny i podobny do Ubuntu (a właściwie to Ubuntu jest podobne do Debiana).
Dzisiaj już kupiłem sobie płytkę i miałem właściwie zabrać się za instalację, ale wiadomo jak to jest... sobota wieczór - myślałem, że gdzieś się wybiorę, więc nawet nie nagrałem obrazu na CD. Pewnie bym siedział do późnych godzin nocnych (a może i wczesnych rannych) i przeglądał system, konfigurował, ściągał programy, konfigurował, uruchamiał serwer, konfigurował...
Jest jeszcze jeden plus tego, że do instalacji zabiorę się dopiero jutro. Kiedy rodzice będą chcieli mnie zgonić z komputera i np. pograć sobie w pasjansa będę mógł im udzielić Standardowej Odpowiedzi "Komputerowca" nr 194: "Oczywiście, że mogę zejść, ale jeszcze nie ustawiłem wszystkiego, więc nie uda Ci się włączyć Windowsa". Zazwyczaj takie tłumaczenie wystarcza, a czasem trzeba zacząć tłumaczyć, że jest coś takiego jak GRUB i jeśli nie jest on dobrze ustawiony ciężko jest odpalić komputer.
Życzcie mi powodzenia, żeby mi się wszystkie partycje nie wyczyściły jak to miało miejsce pewnego razu :P
</description><pubDate>Sat, 15 Dec 2007 19:35:03 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2007/12/15/od-jutra-zagosci-u-mnie-debian/</guid><category>Komputery</category><category>Ogólne</category><category>Prywatne</category><category>debian linux ubuntu migracja</category><feedburner:origLink>http://blog.jkral.info/2007/12/15/od-jutra-zagosci-u-mnie-debian/</feedburner:origLink></item><item><title>Python vs PHP</title><link>http://feedproxy.google.com/~r/Jony/~3/wVdfSx6ns7s/</link><description>Jeśli wszystko potoczy się po mojej myśli niedługo zacznę pracę nad nowym, sporym projektem. Podczas rozmowy z "szefem" rzuciłem pomysł napisania wszystkich skryptów w Pythonie. Później sam zacząłem się zastanawiać dlaczego właściwie odstąpić od dobrze wszystkim znanego PHP na rzecz stosunkowo mało popularnego Pythona.
Poczytałem trochę w internecie i rozszerzyłem swoją wiedzę na ten temat. Wcześniej miałem już styczność z pajtonem, ale nie można było tego nazwać tworzeniem skryptów, a raczej dziecinną zabawą. Z PHP za to walczę już od kilku dobrych lat, więc raczej nic mnie już zaskoczyć nie może (choć mogę się mylić :P ). Postanowiłem zebrać w punktach dlaczego warto zostać przy PHP:

język znam już od dawna
duże doświadczenie w tworzeniu skryptów
łatwość implementacji algorytmów
posiadam masę gotowych funkcji, metod i klas, które znacznie ułatwiają mi pracę

Dla równowagi zebrałem sobie też punkciki przemawiające za tym, aby odejść od PHP:

pod względem ilości funkcji dostępnych w języku PHP zostaje w tyle (brak przestrzeni nazw, raczkująca obiektowość)
PHP jest stosunkowo wolno rozwijane minie dużo czasu, zanim PHP nadrobi te straty
czasem dziwne i nieintuicyjne nazwy funkcji


Python i Django oferują programiście połączenie łatwego i schludnego języka, oraz rozbudowanego frameworka do tworzenia serwisów WWW. Na wstępie mamy do dyspozycji prosty (ale zawsze!) panel admina, oraz interface do implementacji systemu użytkowników. Poza tym ORM wysokiego poziomu, który według mnie jest łatwiejszy w obsłudze, bardziej intuicyjny, a przede wszystkim bardziej obiektowy niż PHP-owy PDO. Aplikacje w Pythonie mogą być wielowątkowe, co także pozwala na zwiększenie wydajności naszej aplikacji. Dodatkowym atutem przemawiającym za przestawieniem sie na pajtona jest to, że nie jest on językiem stworzonym przede wszystkim do pisania stron. Dzięki temu będzie można łatwo zintegrować np. bota gg/irc z serwisem WWW.
Podsumowująć... PHP jest stworzony do pisania stron internetowych i jest do tego celu bardzo dobry. Z drugiej strony nie oferuje on programiście funkcjonalności dostępnych w innych językach już od bardzo dawna. Co prawda developerzy wypuszczają nowe wersje, jednak jak sami twierdzą implementacja niektórych funkcjonalności nie jest możliwa bez całkowitego przebudowania języka. Python nie był tworzony z myślą o podboju internetu. Dzięki takim frameworkom jak Django, czy Pylons stał się do tego celu dobrym narzędziem. Na wstępie oferuje narzędzia przydatne podczas tworzenia serwisów internetowych. Odciąża programistę od zabawy z SQL-em, wiele rzeczy robi automatycznie. Dlatego moim zdaniem warto jest zmienić przyzwyczajenia i poznać alternatywne rozwiązania.
</description><pubDate>Mon, 26 Nov 2007 18:34:32 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2007/11/26/python-vs-php/</guid><category>PHP</category><category>Python</category><category>Techblog</category><category>frameworki</category><feedburner:origLink>http://blog.jkral.info/2007/11/26/python-vs-php/</feedburner:origLink></item><item><title>Tani hosting poszukiwany</title><link>http://feedproxy.google.com/~r/Jony/~3/yPRikjE0TQ8/</link><description>W styczniu (czy na początku lutego) kończy mi się hosting. Przez ten rok moje wymagania co do serwera uległy zmianie, dlatego muszę pomyśleć o zmianie dostawcy. Jak wiadomo usługi polecone przez kogoś są zazwyczaj lepsze aniżeli wygrzebane gdzieś z najgłębszych zakamarków Gugla.
Nie znam się zbytnio na serwerach, ale opiszę może do czego będę go potrzebował:

Hostowanie strony (MySQL, PHP5)
Magazynowanie niewielkich plików (kilka fotek, kilka pliczków tekstowych)
Uruchamianie własnych aplikacji (przede wszystkim python i o ile się orientuję potrzebny jest także dostęp do shella)
więcej grzechów nie pamiętam... :P

Do tego serwer nie powinien być zbytnio drogi (max 60zł/rok). Jeśli ktoś może polecić mi jakiegoś dobrego dostawcę to bardzo proszę.

</description><pubDate>Thu, 15 Nov 2007 12:23:34 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2007/11/15/tani-hosting/</guid><category>Ogólne</category><category>Prywatne</category><feedburner:origLink>http://blog.jkral.info/2007/11/15/tani-hosting/</feedburner:origLink></item><item><title>JAGallery 1.0</title><link>http://feedproxy.google.com/~r/Jony/~3/rkC9EaCYoJQ/</link><description>Jak pisałem wcześniej prace nad skryptem prostej galerii zostały zakończone. Do nowych ficzerów należy zaliczyć możliwość wyświetlenia losowego zdjęcia i ilości plików w folderze w ekranie wyboru galerii. Całość przetestowałem i działa sprawnie w (chyba) każdej możliwej konfiguracji. Do najważniejszych założeń na przyszłość należy skrypt, który podczas wyświetlania dużego zdjęcia skaluje je tak, aby nie wychodziło poza ekran. W następnej wersja ta opcja będzie już na pewno dostępna.
Skrypt udostępniony jest na zasadach licencji by-sa.

Co można:
kopiować, rozpowszechniać, odtwarzać i wykonywać
tworzyć utwory zależne


Czego nie można:
modyfikować skryptu i rozpowszechniać go jako własny
rozpowszechniać skryptu i jego modyfikacji na innej licencji


Download: JAGallery.rar Sample: http://jony.com.pl/galeria
</description><pubDate>Wed, 14 Nov 2007 15:20:23 +0100</pubDate><guid isPermaLink="false">http://blog.jkral.info/2007/11/14/jagallery-1-0/</guid><category>JavaScript, AJAX</category><category>PHP</category><category>Techblog</category><category>JAGallery</category><category>galeria</category><category>JComponents</category><feedburner:origLink>http://blog.jkral.info/2007/11/14/jagallery-1-0/</feedburner:origLink></item><language>en-us</language><media:rating>nonadult</media:rating></channel></rss>
