Dosłownie kilkanaście minut temu kompilator przetworzył na drzewko węzłów prosty plik XML oraz angielską dokumentację do pierwszej wersji biblioteki. Najważniejsze, że wszystkie znaczniki są otwierane i zamykane tak, jak powinny, a ich atrybuty rozpoznawane. Jedynie w niektórych miejscach dodatkowo znacznik dorzucany jest do węzła character data, ale to prawdopodobnie kwestia kilku regulacji. W załączniku zamieściłem screenshot przedstawiający fragment wczytanego drzewa.
Kompilator liczy w tej chwili około 12,5 kilobajtów kodu. Prawidłowo rozpoznaje znaczniki, przestrzenie nazw, komentarze i sekcje CDATA. Obsługa nagłówka dokumentu XML oraz DTD powinna dojść później. W ostatecznej wersji obsługa XML-a będzie prezentować się następująco:
- Nazwy znaczników i argumentów - standard XML dopuszcza stosowanie w nich sporej liczby znaków Unicode. OPT także będzie zezwalać na ich używanie w nazwach, ale po włączeniu stosownej dyrektywy. Powód to wydajność wyrażeń regularnych - według autorów przetwarzanie klas znaków UTF jest dużo wolniejsze, ponieważ PCRE musi skanować ogromne tablice z ich opisami. Tak więc jeśli mamy pewność, że z takich nie będziemy korzystać, będzie nam to niepotrzebnie spowalniać i tak niezbyt szybką kompilację.
- Sekcje CDATA - OPT traktuje je dokładnie tak, jak zaleca specyfikacja. Są one przepisywane bezpośrednio do drzewka tak, aby w wynikowym dokumencie także pozostały sekcjami CDATA.
- Nagłówek dokumentu i DTD - OPT będzie umiał sprawdzać ich składnię, natomiast na pewno nie będzie zawartych tam danych w żaden sposób przetwarzać. OPT domyślnie będzie wymagać dodawania takowych do szablonów, ale będzie to do wyłączenia w konfiguracji. W przypadku szablonu głównego zawierającego szkielet dokumentu, zostaną one przepisane na wyjście. W obrębie tych elementów możliwe będzie stosowanie bloków OPT, dzięki czemu można np. umieścić informację o kodowaniu czy języku.
- Komentarze - domyślnie zjadane w trakcie kompilacji, ale będzie możliwość przekierowania ich na wyjście.
- Domyślnie OPT także będzie wymagać obecności jednego elementu głównego, ale będzie to do wyłączenia. Istnieć będzie specjalny pusty znacznik, dzięki czemu szablony zawierające fragment treści strony nie będą musiały martwić się tym ograniczeniem.
- OPT będzie przetwarzać jedynie znaczniki, których przestrzenie nazw są zarejestrowane w bibliotece. Pozostałe będą przepisywane na wejście, aczkolwiek wykonywany będzie skan w poszukiwaniu atrybutów specjalnych.
- Składnia atrybutów będzie trzymać się ściśle XML-a, aczkolwiek będzie możliwe włączenie respektowania także atrybutów bez wartości znanych z HTML-a.
- Encje - będą.
Jak widać, istnieje kilka opcji, dzięki którym można włączyć pewne odstępstwa od standardu. Ich istnienie podyktowane jest albo wydajnością, albo zwyczajną wygodą. Przykładowo dla mnie nagłówki XML i ograniczenie jednego głównego elementu to zbędne utrudnienie, bo i tak tych szablonów nie będę w przeglądarce odpalać, ani przepuszczać przez sprawdzarki składni inne, niż OPT :). Jest też inny powód, mianowicie zarzucenie prac nad XHTML 2.0 na rzecz HTML-a 5. Aż się prosi o zacytowanie artykułu "Bez tytułu o CSS" napisanego przed półtora rokiem: Standardów nie publikuje się dla samego siebie, ale dla ludzi. Cieszę się, że ktoś tam na górze doszedł do tego samego wniosku i puknął się w czoło, choć wiem, że oznacza to dla mnie więcej pracy nad kompilatorem. Oczywiście szerokie ustępstwa wobec tolerancji HTML-a nie będą dopuszczalne. W trybie XML, nawet lekko uproszczonym, OPT będzie się bronić przed śmietnikiem w kodzie.
Wciąż do napisania jest tzw. quirks mode, czyli sposób pracy na wzór OPT 1, gdzie poza znacznikami jednoznacznie przeznaczonymi dla OPT cała reszta jest bezwzględnie traktowana jako statyczny tekst, nawet jeśli jest to XML. W związku z tym niektóre dodatkowe możliwości manipulacji nie będą dostępne, ale za to parser w dalszym ciągu będzie w stanie przetwarzać dokumenty niebędące XML-em. Implementacja będzie łatwiejsza, niż się początkowo wydawało. Wystarczy po wczytaniu znacznika sprawdzić, czy jest zarejestrowany i jak nie, przepisać na wyjście, zamiast przerobić na węzeł.
OPT2 w dalszym ciągu będzie kompilowany do postaci kodu PHP i zasada przetwarzania instrukcji oraz znaczników pozostanie mniej więcej taka sama, jak w starej wersji. Piszemy procesor instrukcji, rejestrujemy go, procesor informuje kompilator, jakie znaczniki potrafi przetwarzać i od tej pory OPT przekierowuje takowe do niego. Wielu zmianom uległo jednak API. Już teraz możliwa jest manipulacja drzewem węzłów na wzór DOM. Starałem się zachować z nim zgodność nazw i kolejności parametrów tam, gdzie to było możliwe, jednak istnieją pewne odstępstwa. Schemat klas jest uproszczony, inna jest także ogranizacja węzłów tekstowych i dostęp do atrybutów. Wynikają one ze specyficznych potrzeb kompilatora, które były głównym powodem, dla którego piszę go od zera, zamiast skorzystać z gotowych rozwiązań.
API biblioteki najbardziej interesujące programistę jest w powijakach, aczkolwiek da się nim już nieco podstawowych operacji wykonać. OPT2 posiada zupełnie zmieniony system wyjścia, który teraz jest obiektowy i konfigurowalny. Aby móc obsłużyć dane wygenerowane przez parser, piszemy klasę implementującą stosowny interfejs i w niej decydujemy, co z nimi robić. Domyślnie biblioteka udostępnia dwie takie klasy optNetOutput wypluwająca wynik na ekran z kompresją gZip i buforowaniem oraz optReturnOutput, czyli zwracanie wyniku przez metodę. Sprawa buforowania została ujednolicona i już nie powinno być z nim takich problemów i niejasności, jak w OPT 1.x.x. Zmiana ta implikuje również kasację filtrów, które są teraz po prostu niepotrzebne.
Dyrektywy konfiguracyjne zostały ujednolicone i podzielone na grupy, dzięki którym powinny być łatwiejsze w użyciu:
// Directory configuration public $sourceDir = NULL; public $compileDir = NULL; public $pluginDir = NULL; public $cacheDir = NULL; // Front-end configuration public $compileStatus = OPT_CS_DEFAULT; public $charset = 'utf-8'; public $contentType = 0; public $gzipCompression = true; public $debugConsole = false; // Compiler configuration public $mode = OPT_XML_MODE; public $unicodeNames = false; public $htmlAttributes = false; public $printComments = false; public $prologRequired = true;
Wprowadziłem też jedną dodatkową rzecz - musimy ręcznie odpalić metodę setup(), która dokona wstępnej konfiguracji - inaczej nic nie wygenerujemy. We wczesnych wersjach pierwszego OPT też coś takiego istniało, lecz zostało wywalone na wzór Smarty'ego. Jednak znajdujący się tam kod nie mógł być tak po prostu wywalony, gdzieś go trzeba było upchnąć i teraz wegetuje sobie w metodzie fetch(), gdzie parę tricków sprawuje nad nim pieczę tak, aby był uruchomiony tylko podczas przetwarzania pierwszego szablonu. Z pozostałych zmian - nie wiem, czy przypisywanie danych do bloków zrealizować poprzez assign(), czy metodami magicznymi. Myślę, że zadecyduje o tym jakiś pomiar wydajności każdego z rozwiązań.
PS. W nowym OPT nie będzie już dopisków, że jest to część większego projektu. Nie oszukujmy się, przy takim zaangażowaniu nie da się zrobić dobrego forum, tak więc niniejszym pro forma tylko ogłaszam to, co wiadomo od dawna - OpenPB jest zamknięty i rozwijane będą jedynie biblioteki. Jakoś nie uznaję tego za moją porażkę. Zgłosiłem się głównie, aby napisać do niego system szablonów i jako jedyny się z tego wywiązałem, zaś liderem całości zostałem zrządzeniem losu. Dodam, że Slump dalej będzie sprawować pieczę nad tym, co zostało. Strony internetowe zostaną zmienione, gdy OPT2 będzie się nadawać do normalnego użycia. Pracuję obecnie nad kilkoma innymi projektami. Kto wie, może jeśli będą wystarczająco dobre, to też je wypuszczę jako open-source?















Napisał Ktos w sobotę, 24 listopada 2007 o 10:06
Jest też inny powód, mianowicie zarzucenie prac nad XHTML 2.0 na rzecz HTML-a 5
Akurat ja mam wrażenie, że po prostu XHTML 2.0 oraz HTML 5.0 będą rozwijać się równolegle, XHTML2 nie został zarzucony - on ma inne koncepcje rozwoju niż HTML5 po prostu.