<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.invenzzia.org/pl/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Invenzzia... po polsku - Tag - development</title>
  <link>http://blog.invenzzia.org/pl/</link>
  <atom:link href="http://blog.invenzzia.org/pl/feed/tag/development/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>pl</language>
  <pubDate>sob, 15 sty 2011 22:56:54 +0100</pubDate>
  <copyright>Copyright &amp;copy; Invenzzia</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Co nowego w Invenzzii?</title>
    <link>http://blog.invenzzia.org/pl/post/Co-nowego-w-Invenzzii</link>
    <guid isPermaLink="false">urn:md5:9c9bd5d58a1f9b96ae7b62229ca96e88</guid>
    <pubDate>nie, 22 mar 2009 10:38:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Invenzzia</category>
        <category>development</category><category>invenzzia</category><category>OPT2</category><category>typefriendly</category><category>website</category>    
    <description>&lt;p&gt;Witam wszystkich! W ostatnich dniach sporo się działo wokół Invenzzii oraz jej projektów. Postanowiłem w tym zbiorczym wpisie omówić krótko najważniejsze rzeczy, dostępnym również w języku angielskim. Poruszymy temat OPT 2.0, nowego TypeFriendly, nowej strony Invenzzii oraz aktywności Invenzzii w &quot;serwisach wspomagania open-source&quot;, że tak to ładnie nazwę.&lt;/p&gt;    &lt;h2&gt;Open Power Template 2&lt;/h2&gt;


&lt;p&gt;Kilkanaście minut temu na SVN-ie znalazła się kolejna rewizja oznaczona numerem 66, efekt ostatnich czterech dni pracy. Jak na tak krótki okres, zakres wnoszonych poprawek i nowości jest zaiste imponujący.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Zdecydowałem się przepisać na nowo kod odpowiedzialny za kompilację sekcji. Poprzedni miał poważny problem z obsługą specyficznych atrybutów, którego nie dało się w takiej postaci przeskoczyć w żaden sposób. Dzięki tej akcji, poprawiłem znacznie prostotę oraz czytelność kodu, m.in. wyposażając go w phpdoc i upraszczając strukturę. Aby upewnić się, że nowy kod nie wyprodukuje nowych błędów w tym, co dotychczas działało, pojawiło się ponad 20 nowych testów sekcji sprawdzających poprawność obsługi rozmaitych warunków brzegowych oraz współpracy z innymi instrukcjami. Dlatego nowa implementacja nie powinna sprawiać większych niespodzianek, aczkolwiek błąd &lt;a href=&quot;http://bugs.invenzzia.org/task/51&quot; hreflang=&quot;en&quot;&gt;#51&lt;/a&gt; w dalszym ciągu pozostaje nienaprawiony.&lt;/li&gt;
&lt;li&gt;Przy okazji ostatecznie uporządkowałem projekt formatów danych, który też w końcu uzyskał formę, z której jestem zadowolony. Trzeba jeszcze napisać do tego wszystkiego kupę unit testów, ale jesteśmy już na dobrej drodze, by takie testy faktycznie powstały.&lt;/li&gt;
&lt;li&gt;Kolejna, dość spora partia kodu PHP została wyposażona w phpdoc. Dzięki temu IDE typu NetBeans i Eclipse będą w stanie jeszcze lepiej podpowiadać semantykę i użycie poszczególnych metod. Phpdoc w kodzie źródłowym został w większości wymuszony właśnie tą potrzebą, gdyż normalna i właściwa dokumentacja pisana jest w oparciu o TypeFriendly.&lt;/li&gt;
&lt;li&gt;Usunięte zostało kilka irytujących błędów.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ponadto, ulepszenia pojawiły się również w &lt;a href=&quot;http://www.invenzzia.org/docs/opt2-en/&quot; hreflang=&quot;en&quot;&gt;podręczniku użytkownika&lt;/a&gt;, gdzie pojawił się zupełnie nowy rozdział nazwany &quot;Podręcznik programisty&quot; (ang. &quot;Programmer's guide&quot;). Celem jest stworzenie kompletnego przewodnika po poszczególnych możliwościach OPT, który można czytać jak książkę i który zawiera różne praktyczne wskazówki, nie zawsze dające się opisać w zwykłej dokumentacji API. W poczet nowego rozdziału został włączony stary &quot;API Issues&quot;. Obecnie z nowego rozdziału można dowiedzieć się następujących rzeczy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Jak przygotować OPT do pracy?&lt;/li&gt;
&lt;li&gt;Jak pracować z widokami?&lt;/li&gt;
&lt;li&gt;Jak pracować z systemami wyjścia?&lt;/li&gt;
&lt;li&gt;Jak obsługiwać błędy oraz rozszerzać ich domyślną obsługę?&lt;/li&gt;
&lt;li&gt;Jak pracować z formatami danych.&lt;/li&gt;
&lt;li&gt;Jak tworzyć wielojęzyczne witryny.&lt;/li&gt;
&lt;li&gt;Jak podłączyć własną funkcję do escape'owania HTML-a w danych ze skryptu i zapobiegania atakom XSS?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lektura dostępna jest wyłącznie w języku angielskim.&lt;/p&gt;


&lt;h2&gt;TypeFriendly 0.1.1&lt;/h2&gt;


&lt;p&gt;Niecały tydzień temu został wydany TypeFriendly 0.1.1, nowa wersja systemu generowania podręczników użytkownika. Koncentruje się on przede wszystkim na poprawie znalezionych błędów. Teraz nasze wysiłki kierują się już ku wydaniu wersji 0.2 i mamy nadzieję, że ukaże się ona znacznie szybciej :).&lt;/p&gt;


&lt;h2&gt;Nowa witryna Invenzzii&lt;/h2&gt;


&lt;p&gt;W końcu jesteśmy prawie gotowi do uruchomienia nowej strony Invenzzii. Wczoraj eXtreme odpalił ją na naszym serwerze i w chwili obecnej trwają testy oraz implementacja ostatnich funkcji. Witryna posiada zupełnie nowy design, logo (można je już podziwiać na &lt;a href=&quot;http://wiki.invenzzia.org&quot; hreflang=&quot;en&quot;&gt;wiki&lt;/a&gt;), nową, czytelniejszą nawigację oraz układ treści. Mamy nadzieję, że w przeciągu kilku następnych dni uda się ją udostępnić internautom.&lt;/p&gt;


&lt;h2&gt;OPT w Ohloh.net&lt;/h2&gt;


&lt;p&gt;Ohloh.net to nowatorski katalog projektów open-source założony przez dwójkę byłych pracowników Microsoftu, który nie tylko podaje informacje, że coś istnieje, ale pozwala również na szeroko rozumianą interakcję między użytkownikami i twórcami. Kilka dni temu założyłem w nim profil projektu &lt;a href=&quot;https://www.ohloh.net/p/open-power-template-2&quot; hreflang=&quot;en&quot;&gt;Open Power Template 2&lt;/a&gt;. W chwili obecnej monitoruje on RSS-y, pozwala śledzić bieżący dziennik prac uaktualniany przez Jabbera (jeśli jesteś ciekaw, co aktualnie, w tej konkretnej chwili grzebiemy w kodzie, zaprenumeruj go :)) oraz przejrzeć statystyki dotyczące bieżącego kodu źródłowego (niestety tylko w repozytorium &quot;trunk&quot;, które na razie się nie rozwija z wiadomych przyczyn). Jeśli posiadasz konto na Ohloh i jesteś użytkownikiem OPT, nie zapomnij zgłosić tego oraz ocenić projektu, gdyż m.in. dzięki temu projekt ma możliwość przyciągnięcia większej ilości użytkowników, co przełoży się na jakość samego kodu i dostępnych materiałów. Planujemy wydelegować na Ohloh również system downloadu tak, aby nie obciążać tym zadaniem naszego serwera i umożliwić zainteresowanym pobieranie projektu z rozmaitych mirrorów.&lt;/p&gt;


&lt;p&gt;PS. Przypominam prenumeratorom RSS-a, żeby przepisali się na wersję anglojęzyczną bloga, gdzie nowe wpisy pojawiają się znacznie częściej!&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Co-nowego-w-Invenzzii#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Co-nowego-w-Invenzzii#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/50</wfw:commentRss>
      </item>
    
  <item>
    <title>OPT: Raport z prac</title>
    <link>http://blog.invenzzia.org/pl/post/OPT%3A-Raport-z-prac</link>
    <guid isPermaLink="false">urn:md5:3ad4101153a2a87a8638d3b2b2d51009</guid>
    <pubDate>pią, 19 wrz 2008 14:13:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>development</category><category>OPT2</category>    
    <description>&lt;p&gt;Przyszła pora na złożenie kolejnego raportu z prac nad OPT. W ostatnim czasie biblioteka wzbogaciła się o kilka nowych opcji, zamkniętych zostało również kilka błędów z bugtrackera. Z najważniejszych zmian można powitać (w końcu) tryb tekstowy figurujący w anglojęzycznej terminologii jako Quirks Mode. Pojawiła się nowa sekcyjna instrukcja: opt:selector, która zastępuje opt:paginator. Natomiast jeśli chodzi o funkcje, dodane zostało pełne wsparcie dla zmiany kolejności argumentów wykonywanej przez kompilator, co pozwala uniknąć tworzenia nakładek tylko po to, by ujednolicić wszystko.&lt;/p&gt;    &lt;p&gt;Istotna zmiana dotyczy zasobów oraz dyrektywy &lt;code&gt;sourceDir&lt;/code&gt;. Zrezygnowałem z pojęcia zasobu oraz interfejsu &lt;code&gt;Opt_Resource_Interface&lt;/code&gt; na rzecz strumieni PHP, które również można dowolnie oprogramowywać, a przy okazji oferują one znacznie większe możliwości przy wykorzystaniu standardowych funkcji. Ich konfigurowanie odbywa się teraz poprzez dyrektywę &lt;code&gt;sourceDir&lt;/code&gt;, która może teraz przyjmować jako wartość również tablicę asocjacyjną:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;$tpl-&amp;gt;sourceDir = array(
   'file' =&amp;gt; '/sciezka/templates/',
   'db' =&amp;gt; 'database://moja_baza/'
);

// system plików
$tpl-&amp;gt;parse('szablon.tpl');

// baza danych
$tpl-&amp;gt;parse('db:szablon.tpl');
&lt;/pre&gt;


&lt;p&gt;Oczywiście we wspomnianym przykładzie trzeba ręcznie sobie strumień &quot;db&quot; utworzyć, a szczegóły znajdują się w dokumentacji PHP.&lt;/p&gt;


&lt;p&gt;Nowa instrukcja, &lt;code&gt;opt:selector&lt;/code&gt;, jest połączeniem sekcji oraz czegoś w rodzaju instrukcji &quot;switch&quot;. Umożliwia proste definiowanie różnych wariantów wyświetlenia elementu, a wybór odpowiedniego następuje na podstawie jednego z pól elementu, domyślnie o nazwie &quot;item&quot;. Od strony kodu, wygląda to bardzo podobnie do składni dawnej instrukcji &lt;code&gt;opt:paginator&lt;/code&gt;, którą nawiasem mówiąc można bardzo łatwo odtworzyć:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;opt:selector name=&amp;quot;strony&amp;quot;&amp;gt;
  &amp;lt;opt:page&amp;gt;[ &amp;lt;a parse:href=&amp;quot;$strony.adres&amp;quot;&amp;gt;{$strony.numer}&amp;lt;/a&amp;gt; ]&amp;lt;/opt:page&amp;gt;
  &amp;lt;opt:active&amp;gt;[ &amp;lt;a parse:href=&amp;quot;$strony.adres&amp;quot; class=&amp;quot;active&amp;quot;&amp;gt;{$strony.numer}&amp;lt;/a&amp;gt; ]&amp;lt;/opt:active&amp;gt;
  &amp;lt;opt:dots&amp;gt;...&amp;lt;/opt:dots&amp;gt;
&amp;lt;/opt:selector&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Całość współpracuje ze snippetami i posiada wszystkie inne właściwości sekcji, włącznie z &lt;code&gt;opt:selectorelse&lt;/code&gt;, a nawet atrybutem &lt;code&gt;opt:selector&lt;/code&gt; pozwalającym zmienić dowolny znacznik w tę instrukcję.&lt;/p&gt;


&lt;p&gt;System dziedziczenia szablonów został wzbogacony o nową możliwość, mianowicie dołączanie dodatkowego szablonu, tylko że w przeciwną stronę (coś na wzór szablonów kompilacyjnych z OPT 1.x):&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;!-- szablon.tpl --&amp;gt;
&amp;lt;opt:root include=&amp;quot;inny_szablon.tpl&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;Tutaj mamy jakiś kod...&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;I możemy użyć snippetów z pliku inny_szablon.tpl&amp;lt;/p&amp;gt;
  &amp;lt;opt:insert snippet=&amp;quot;foo&amp;quot; /&amp;gt;
&amp;lt;/opt:root&amp;gt;

&amp;lt;!-- inny_szablon.tpl --&amp;gt;
&amp;lt;opt:root&amp;gt;
  &amp;lt;opt:snippet name=&amp;quot;foo&amp;quot;&amp;gt;
    Treść snippetu.
  &amp;lt;/opt:snippet&amp;gt;
&amp;lt;/opt:root&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Niestety, ta jedna rzecz musi być kompilowana rekurencyjnie, przynajmniej na razie, dlatego odradzam robienie jakichś super-długich łańcuchów w stylu &quot;A dołącza B, który dołącza C, który dołącza D, który dołącza E&quot; itd. Na pocieszenie dodam, że i tutaj został zamontowany wykrywacz nieskończonej rekurencji, który przerwie dołączanie, jeśli stwierdzi, że doprowadzi to do zapętlenia.&lt;/p&gt;


&lt;p&gt;Ostatnia zmiana, to tryb quirks. Nie wiem, czy oczekiwany przez wszystkich, ale na pewno potrzebny, by OPT mógł sięgać tam, gdzie żaden zwykły kompilator XML nie sięgnie - do przetwarzania dowolnych dokumentów tekstowych. W skrócie - kompilator wyłapuje wtedy wyłącznie znaczniki należące do OPT (instrukcje), cała reszta traktowana jest natomiast jak zwykły tekst, podobnie jak to miało miejsce w OPT 1.1.x. Włączyć go można globalnie albo lokalnie dla pojedynczego szablonu:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;$tpl-&amp;gt;mode = Opt_Class::QUIRKS_MODE;
$tpl-&amp;gt;parse('szablon.tpl', Opt_Class::OUT_SCREEN, NULL, Opt_Class::QUIRKS_MODE);
&lt;/pre&gt;


&lt;p&gt;Najnowsza wersja kodu dostępna jest w SVN-ie, niedługo zaś pojawi się OPL 2.0.0-dev8.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/OPT%3A-Raport-z-prac#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/OPT%3A-Raport-z-prac#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/35</wfw:commentRss>
      </item>
    
  <item>
    <title>OPT 2.0.0-dev7</title>
    <link>http://blog.invenzzia.org/pl/post/OPT-200-dev7</link>
    <guid isPermaLink="false">urn:md5:b131a991b46030d10b663233a603ff4b</guid>
    <pubDate>śro, 20 sie 2008 11:31:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>development</category><category>dokumentacja</category><category>opt2</category><category>releases</category>    
    <description>&lt;p&gt;3 miesiące i 10 dni. Tyle zajęło przepisywanie dotychczasowego kodu OPT do nowej, lepszej wersji. Dziś w końcu uznałem, że dotarł on do punktu, w którym może aspirować do miana &quot;dev7&quot; i odpowiednia paczka znalazła się w działach &quot;Download&quot;. Zmian jest sporo, głównie związanych z API biblioteki, którą teraz się nieco inaczej inicjuje. Poprawiłem też nieco kompilator, dodając do szablonów parę nowych możliwości oraz znacząco rozbudowałem dokumentację, która zresztą dołączona jest do wydania.&lt;/p&gt;    &lt;h2&gt;Zmiany w API&lt;/h2&gt;


&lt;p&gt;Nowe OPT zupełnie inaczej się inicjuje. Biblioteka nie jest w pełni samodzielna - aby ułatwić późniejszą integrację z innymi produktami serii OPL, powstał pakiet OPL zawierający podstawowe interfejsy oraz klasy. Wyekspediowana tam została m.in. obsługa konsoli debugowej oraz konfiguracji, ponadto dodaje on autoloader z prawdziwego zdarzenia. Kod OPL dołączony jest domyślnie do paczki z OPT, tak więc w dalszym stopniu wystarczy skrypt tylko rozpakować.&lt;/p&gt;


&lt;p&gt;Aby nie być gołosłownym przedstawiam odrobinę kodu:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;&amp;lt;?php
    // OPL Initialization
    require('../../lib/opl/base.php');
    Opl_Loader::setDirectory('../../lib/');
    Opl_Registry::setState('opl_debug_console', true);
    Opl_Registry::setState('opl_extended_errors', true);
    spl_autoload_register(array('Opl_Loader', 'autoload'));
    
    try
    {
    	$tpl = new Opt_Class;
    	$tpl-&amp;gt;sourceDir = './templates/';
    	$tpl-&amp;gt;compileDir = './templates_c/';
    	$tpl-&amp;gt;charset = 'utf-8';
    	$tpl-&amp;gt;compileMode = Opt_Class::CM_REBUILD;
    	$tpl-&amp;gt;stripWhitespaces = false;
    	$tpl-&amp;gt;setContentType(Opt_Class::HTML);
    	$tpl-&amp;gt;setup();
    	
    	$tpl-&amp;gt;assign('foo', 'Blok');
    	$tpl-&amp;gt;parse('szablon.tpl');    
    }
    catch(Opt_Exception $exception)
    {
    	Opt_Error_Handler($exception);
    }
?&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Podstawowa inicjacja polega na załadowaniu głównego pliku biblioteki OPL, ustawieniu katalogu ze źródłami oraz autoloadera. Podany katalog musi zawierać zarówno foldery &quot;opl&quot;, jak i &quot;opt&quot;, gdyż inaczej nic się nam nie załaduje. Przy okazji możemy ustawić ogólne aspekty funkcjonowania wszystkich bibliotek OPL.&lt;/p&gt;


&lt;p&gt;Jak widać, zmienione zostało nazewnictwo klas. Musiałem to zrobić, ponieważ taki zapis jest znacznie łatwiej parsować w autoloaderze, a przy okazji ucieszy fanów Zend Frameworka. Zmieniłem także nazwy niektórym metodom, np. powyżej widać, że &lt;code&gt;httpHeaders()&lt;/code&gt; został przechrzczony na &lt;code&gt;setContentType()&lt;/code&gt;. Jeśli zajrzymy do katalogu &lt;code&gt;/lib/opt/&lt;/code&gt;, ujrzymy, że cały kompilator został zmodularyzowany, lecz i tak nie uchroniło to głównej klasy &lt;code&gt;Opt_Compiler_Class&lt;/code&gt; przed zajmowaniem 65 KB na dysku twardym. Tego się już bardziej odchudzić po prostu nie da, ale możecie się pocieszać, że do tego pliku właściwie tylko ja muszę zaglądać i się w nim orientować :).&lt;/p&gt;


&lt;p&gt;Tutaj mała uwaga: z OPT wyrzuciłem system cache. Doszedłem do wniosku, że zmuszanie tej biblioteki do zajmowania się jeszcze tym to lekkie przegięcie. Zamiast tego, pozostał bardzo prosty interfejs &lt;code&gt;Opt_Cache_Hook_Interface&lt;/code&gt;, który należy sobie zaimplementować, aby podłączyć dowolny inny system cache. W ten sposób biblioteka łatwiej będzie integrować się z frameworkami, które często obsługują ten element we własnym zakresie. Gdyby ktoś jednak czegoś takiego nie miał, dotychczasowy kod niebawem będzie dostępny z powrotem... lecz jako osobna biblioteka, dla której jeszcze nie wymyśliłem nazwy.&lt;/p&gt;


&lt;h2&gt;Zmiany w szablonach&lt;/h2&gt;


&lt;p&gt;Szablony powinny działać bez większych problemów, aczkolwiek przy okazji przepisywania pchnąłem lekko do przodu prace nad instrukcjami. Pojawił się &lt;code&gt;opt:tag&lt;/code&gt;, a &lt;code&gt;opt:extend&lt;/code&gt; w pełni obsługuje już escape'owanie. Nie ma jeszcze &lt;code&gt;opt:tree&lt;/code&gt;, &lt;code&gt;opt:grid&lt;/code&gt; i &lt;code&gt;opt:pagination&lt;/code&gt;, gdyż zmieniłem silnik sekcji i na razie zdążyłem go przetestować jedynie na &lt;code&gt;opt:section&lt;/code&gt;. Sekcje są teraz o tyle fajne, że obsługują tzw. klasy uchwytów (hook classes), dzięki którym można nauczyć je obsługi dowolnego formatu danych, jaki nam się tylko zamarzy. W finalnym wydaniu nie będzie żadnych problemów, żeby sekcja potrafiła odczytywać dane np. bezpośrednio z obiektów PHP-Doctrine lub różnych elementów frameworków. Wszelkie sprawy związane z wybranym formatem są zupełnie niewidoczne po stronie szablonu:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;opt:section name=&amp;quot;sekcja&amp;quot;&amp;gt;
  .... {$sekcja.blok}
&amp;lt;/opt:section&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Format natomiast wybieramy w skrypcie, np.&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;$tpl-&amp;gt;assign('sekcja', $PDOStatement, 'PDO');
&lt;/pre&gt;


&lt;p&gt;OPT zajmie się całą resztą, czyli dopasowaniem formatu do sekcji, korzystając z podanej klasy uchwytów. Klasy uchwytów mogą również modyfikować działanie zwyczajnych bloków, a twórcy instrukcji mogą korzystać z ich API w swoich produkcjach. W samych sekcjach pojawił się nowy atrybut: &lt;code&gt;parent&lt;/code&gt;, który ułatwi tworzenie relacji. Przypomnę, że w dalszym ciągu sam fakt zagnieżdżenia jednej sekcji w innej tworzy między ich elementami relację przynależności, lecz jeśli domyślne zachowanie nam nie pasuje, możemy to zmienić:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;opt:section name=&amp;quot;sekcja1&amp;quot;&amp;gt;
   &amp;lt;opt:section name=&amp;quot;sekcja2&amp;quot;&amp;gt;
      &amp;lt;opt:section name=&amp;quot;sekcja3&amp;quot; parent=&amp;quot;sekcja1&amp;quot;&amp;gt;
         ....
      &amp;lt;/opt:section&amp;gt;
   &amp;lt;/opt:section&amp;gt;
&amp;lt;/opt:section&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Teraz elementy sekcji3 są przyłączone do sekcji1, a nie sekcji2. Ponadto, niedawno na forum Nowaker zaproponował, aby OPT zgodnie z logiką obsługiwał następujący blok sekcji: &lt;code&gt;{$sekcja.blok.elementTablicy}&lt;/code&gt;. Wola jego stała się faktem i teraz OPT skanuje cały taki blok w poszukiwaniu nazwy dowolnej aktywnej obecnie sekcji.&lt;/p&gt;


&lt;p&gt;Z innych nowości należy wymienić możliwość przypisania bloku do konkretnego szablonu. Dostęp jest realizowany poprzez &lt;code&gt;$this.blok&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;Dokumentacja&lt;/h2&gt;


&lt;p&gt;Spędziłem niedawno dużo czasu nad dokumentacją do OPT 2, a przede wszystkim nad przekonwertowaniem dotychczasowych wyczynów na TypeFriendly. Efekt jest następujący:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Na ukończeniu jest opis składni szablonów. Jedynie dwie instrukcje nie posiadają jeszcze dokumentacji i trochę funkcji.&lt;/li&gt;
&lt;li&gt;Opisana jest większość API biblioteki.&lt;/li&gt;
&lt;li&gt;Opisane są wszystkie aktualnie wykorzystywane i zatwierdzone dyrektywy konfiguracyjne.&lt;/li&gt;
&lt;li&gt;Na ukończeniu są strony opisujące migrację z: PHP, OPT 1.x oraz Smarty'ego. Szczególnie w OPT 1.1.x ludzie się krzywili na ostatni z wymienionych opisów, że głupoty opisuje, zamiast konkretów. Teraz się poprawiłem i różnica jakościowo-ilościowa powinna być widoczna gołym okiem.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dokumentacja dołączona jest do paczki, jest także możliwość przejrzenia jej on-line: &lt;a href=&quot;http://www.invenzzia.org/docs/opt2-pl/&quot; hreflang=&quot;pl&quot;&gt;on-line&lt;/a&gt;. Można także zapoznać się z zalążkiem angielskiej dokumentacji do &lt;a href=&quot;http://www.invenzzia.org/docs/opl2-en/&quot; hreflang=&quot;en&quot;&gt;OPL&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;Zakończenie&lt;/h2&gt;


&lt;p&gt;Wykaz paczek można znaleźć &lt;a href=&quot;http://libs.invenzzia.org/pl/download&quot; hreflang=&quot;pl&quot;&gt;tutaj&lt;/a&gt;. Na kolejną niestety znów przyjdzie trochę poczekać. W sobotę wyjeżdżam na tydzień, a zaraz później pochłonie mnie przeprowadzka do Krakowa i egzamin na uczelni, tak więc będę &quot;wolny&quot; dopiero za jakiś miesiąc. W tym czasie będę wrzucać jakieś mniejsze rzeczy na SVN i tam też będzie najświeższa wersja. Z drugiej strony, eXtreme już coś tam kombinuje z Open Power Classes, a konkretniej jego klasą &quot;Opc_Paginator&quot; do stronicowania. Myślę, że również Radzio w końcu zrobi swoje API dla Google Charts.&lt;/p&gt;


&lt;p&gt;Na koniec należy uczciwie zaznaczyć, że OPT 2.0.0-dev7 przeszedł z LGPL 3 na zmodyfikowaną licencję BSD, co Wam ułatwi później dodawanie go do projektów komercyjnych, a wszystkim utrudni życie z przyjmowaniem zewnętrznych patchów i poprawek. Licencja LGPL była o tyle fajna, że z definicji obejmowała sobą również wszystkie poprawki i patche. Zmodyfikowana BSD tak nie robi i będę musiał odmawiać ich dodania do SVN bez podpisanego papierka ze zgodą na wydanie ich na podanej licencji, tak jak to robi Zend ze swoim Frameworkiem. Coś za coś.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/OPT-200-dev7#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/OPT-200-dev7#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/34</wfw:commentRss>
      </item>
    
  <item>
    <title>OPT zbiera się do kupy</title>
    <link>http://blog.invenzzia.org/pl/post/OPT-zbiera-si-do-kupy</link>
    <guid isPermaLink="false">urn:md5:c0240785fe81bd52320a5b247080535d</guid>
    <pubDate>pią, 25 lip 2008 19:13:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>development</category><category>OPT2</category><category>optymalizacja</category>    
    <description>&lt;p&gt;Mija trzeci miesiąc, odkąd na tym blogu pojawiły się ostatnie wieści dotyczące Open Power Template'a 2.0.0. Czas ten nie był stracony, gdyż (pomijając sesję na uczelni) upłynął na ostrym przepisywaniu całego projektu. Wieści nie było, gdyż doprowadzenie nowego kodu do stanu uruchamialności nieco trwało, ale w końcu jest. Kompilator na nowo kompiluje szablony, i to już bez użycia rekurencji, zmory poprzednich wydań nawet, jeśli po części spowodowana ona była przez błąd w samym PHP :). Ale do rzeczy...&lt;/p&gt;    &lt;p&gt;Począwszy od dev7, OPT będzie niekompatybilny wstecz z wydaniami dev1 do dev6, ale tylko od strony API. Zmiany w sumie nie są wielkie i dotyczą bardziej mechanizmu inicjowania biblioteki. Załączam przykładowy kod:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;&amp;lt;?php 
    // OPL Initialization 
    require('../../lib/opl/base.php'); 
    Opl_Base::setDirectory('../../lib/'); 
    Opl_Base::setDebugMode(Opl_Base::DEBUG_ERROR); 
    spl_autoload_register(array('Opl_Base', 'autoload')); 
     
    try 
    { 
    	$tpl = new Opt_Class; 
    	$tpl-&amp;gt;sourceDir = './templates/'; 
    	$tpl-&amp;gt;compileDir = './templates_c/'; 
    	$tpl-&amp;gt;charset = 'utf-8'; 
    	$tpl-&amp;gt;compileMode = Opt_Class::CM_REBUILD; 
    	$tpl-&amp;gt;stripWhitespaces = false; 
    	$tpl-&amp;gt;httpHeaders(Opt_Class::HTML); 
    	$tpl-&amp;gt;setup(); 
    	 
    	$tpl-&amp;gt;assign('foo', 'I am a value.'); 
    	$tpl-&amp;gt;parse('test_parser_1.tpl');     
    } 
    catch(Opl_Exception $exception) 
    { 
    	Opl_Error_Handler($exception); 
    } 
?&amp;gt; 
&lt;/pre&gt;


&lt;p&gt;Jak widać, inny jest mechanizm inicjalizacji. Biblioteki doczekały się wspólnego rdzenia, autoloadera, lepszej hermetyzacji, lecz trzeba uczciwie zaznaczyć, że lekko odbije się to na wydajności. Cena postępu - albo przypakowana i zap***jąca jak gepard biblioteka, albo zwinniejsza lecz nieco wolniejsza antylopa GNU. Dokładniej, mamy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Autoloader&lt;/li&gt;
&lt;li&gt;Mechanizm rejestrowania obiektów (coś na wzór Zend_Registry)&lt;/li&gt;
&lt;li&gt;Tryb debugowania, w tym ujednolicona konsola debugowa. Jeśli ktoś będzie korzystać z np. 5 bibliotek OPL i włączy sobie takową, nie będzie mu wyskakiwać 5 pop-upów, tylko jeden zbiorczy.&lt;/li&gt;
&lt;li&gt;Ujednolicone mechanizmy konfiguracji&lt;/li&gt;
&lt;li&gt;Grupa wspólnych interfejsów: zasoby, cache, system tłumaczeń.&lt;/li&gt;
&lt;li&gt;Obsługa błędów, w pełni wykorzystująca możliwości systemu wyjątków.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Zmianie uległ system nazewnictwa klas, teraz jest on bardzo podobny do tego, co widzimy w Zend Framework. Różnice dotyczą drobnych szczegółów umożliwiających pakowanie kilku klas do jednego pliku i obsługę takich sytuacji przez autoloader. Wiadomo na pewno, że zmieni się sposób obsługi interfejsu tłumaczeń. Wiem, że co najmniej jedna inna biblioteka także będzie go wykorzystywać, dlatego uznałem, że zamiast rejestrować obiekt odpowiedniej klasy w każdym projekcie z osobna, wykorzystam do tego rdzeń OPL:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;Opl_Base::register('opl_translate', new MojaKlasaTlumaczen); 
&lt;/pre&gt;


&lt;p&gt;Wielu z Was z pewnością interesuje, co w tej chwili potrafi nowy kod OPT. Do jakiegokolwiek sensownego wykorzystania nie nadaje się on dalej, chociażby z tego powodu, że nie zaimplementowałem na nowo jeszcze żadnej instrukcji. Tak naprawdę dopiero przedwczoraj udało mi się skompilować pierwszy szablon, zaś dzisiaj dostrajałem kompilator wyrażeń po jego przeróbce na wersję nierekurencyjną. Zostało mu tylko 9 z 98 testów do zaliczenia i dotyczą one w zasadzie odwracania kolejności argumentów w funkcji oraz detekcji niektórych błędów składni związanych z nawiasami. Czyli takie techniczne duperele, które można naprawić w pół godziny przy dobrych wiatrach. Przepisywanie kompilatora poszłoby znacznie szybciej, ale postanowiłem, że skoro już przepisuję wszystko, pozbędę się do końca rekurencji. I dopiąłem swego, opanowując do perfekcji iteracyjną wersję przeszukiwania drzewa w głąb, hehehe. OPT nie jest już wrażliwy na głębokość jakiegokolwiek drzewa i na komunikat &quot;Nesting level too deep&quot; trzeba sobie zasłużyć zbyt pazernym własnym skryptem.&lt;/p&gt;


&lt;p&gt;Kod wraz z polską dokumentacją API kompilatora jest do ściągnięcia z repozytorium SVN. Trzymajcie kciuki za dev7...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/OPT-zbiera-si-do-kupy#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/OPT-zbiera-si-do-kupy#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/33</wfw:commentRss>
      </item>
    
  <item>
    <title>TypeFriendly 0.1.0 wydane</title>
    <link>http://blog.invenzzia.org/pl/post/TypeFriendly-010-wydane</link>
    <guid isPermaLink="false">urn:md5:150b7aad27160b6c415d7dc7bf5f53e9</guid>
    <pubDate>śro, 23 lip 2008 10:29:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>TypeFriendly</category>
        <category>development</category><category>releases</category><category>typefriendly</category>    
    <description>&lt;p&gt;W końcu zakończyliśmy tłumaczenie dokumentacji na język angielski i gotowy od kilkunastu dni kod wreszcie został wydany jako pierwsza wersja systemu generowania dokumentacji TypeFriendly. Można ją pobrać w dziale &lt;a href=&quot;http://www.invenzzia.org/pl/pliki&quot; hreflang=&quot;pl&quot;&gt;Pliki&lt;/a&gt; na stronie głównej. Dokumentacja dostarczana jest w wersji źródłowej i robi jednocześnie za przykład, dlatego nie obawiajcie się, że czegoś brakuje. Wszystkie informacje potrzebne do zbudowania HTML-owej wersji dokumentacji znajdują się w pliku &lt;code&gt;/info/README.txt&lt;/code&gt; - jest to kwestia wklepania jednego polecenia z konsoli. Trwają już prace nad nową stroną Invenzzii i znajdzie się tam miejsce na dokumentację on-line.&lt;/p&gt;    &lt;p&gt;O TypeFriendly pisałem dokładniej w poprzednim wpisie i tam znajdziecie więcej informacji. Tutaj dodam tylko, że eXtreme odwalił kawał świetnej roboty, wyczerpująco opisując po polsku &lt;strong&gt;całą składnię Markdown z dziesiątkami przykładów&lt;/strong&gt;. Z pewnością opis ten przyda się wielu osobom.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/TypeFriendly-010-wydane#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/TypeFriendly-010-wydane#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/31</wfw:commentRss>
      </item>
    
  <item>
    <title>TypeFriendly</title>
    <link>http://blog.invenzzia.org/pl/post/TypeFriendly</link>
    <guid isPermaLink="false">urn:md5:759da236043100759dab1375858eff8f</guid>
    <pubDate>śro, 02 lip 2008 20:51:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>TypeFriendly</category>
        <category>development</category><category>dokumentacja</category><category>typefriendly</category>    
    <description>&lt;p&gt;Z eXtremem ciężko pracujemy, by pierwsza wersja ujrzała w końcu światło dzienne i jesteśmy już bardzo blisko. W związku z tym chciałbym bliżej przedstawić ten projekt, który z pewnością powinni docenić inni programiści, autorzy rozmaitych skryptów i poszukujących sensownego narzędzia do generowania dokumentacji. Pomysł na napisanie TypeFriendly zrodził się w mojej głowie po nieudanych zmaganiach z dodaniem paru niezbędnych rzeczy do parsera XSLT dla DocBook. Widać choćby po dokumentacji PHP, co można z tym zrobić (kolorowanie składni, wiele różnych formatów, ogromna ilość pomocnych znaczników), ale nie dajmy się zwariować. To są wręcz tygodnie siedzenia, by osiągnąć podobny efekt. Pomijam już fakt, że byłby on słabo przenośny... wolałem poświęcić te tygodnie na stworzenie czegoś bardziej przydatnego.&lt;/p&gt;    &lt;p&gt;TypeFriendly jest więc systemem generowania dokumentacji, ale innego pokroju niż np. phpDocumentor, który skanuje kod źródłowy Twojego projektu i robi opisy do wszystkich napotkanych klas i funkcji. Tutaj rozdziały piszemy sami od A do Z i sami układamy je w żądanym porządku, podobnie jak w DocBooku. Na tym podobieństwa się kończą, ponieważ TF z definicji zawiera już wszystko, co potrzeba, a został tak zaprojektowany, by dokumentację pisało się intuicyjnie.&lt;/p&gt;


&lt;p&gt;Cechy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;W TF dokumentację tworzymy, pisząc tekst w zwykłych plikach tekstowych, korzystając ze składni Markdown. Dodatkowo, na początku umieszczamy różne dodatkowe tagi, dzięki którym możemy ustawić tytuł, informacje o wersji czy np. listę &quot;Zobacz także&quot;.&lt;/li&gt;
&lt;li&gt;TF automatycznie układa nasze pliki w rozdziały na podstawie ich nazwy i sortuje alfabetycznie. Jednak zawsze możemy wprowadzić własny układ - w pliku &quot;ze wskazówkami do sortowania&quot; definiujemy własną kolejność. To, czego tam nie zapisaliśmy, pozostanie alfabetycznie.&lt;/li&gt;
&lt;li&gt;TF posiada wbudowaną opcję kolorowania składni kodu źródłowego.&lt;/li&gt;
&lt;li&gt;TF samodzielnie generuje pełną nawigację pomiędzy rozdziałami, podobnie jak spis treści.&lt;/li&gt;
&lt;li&gt;TF jest zaprojektowany do rozwijania dokumentacji w kilku językach. Posiada nie tylko możliwość przetłumaczenia tekstów interfejsu, ale także proste narzędzie do sprawdzania aktualności &quot;pochodnych wersji językowych&quot;.&lt;/li&gt;
&lt;li&gt;TF umożliwia wygenerowanie wyjściowej dokumentacji w formacie XHTML (w wersji z wieloma podstronami lub na jednej). Przygotowujemy też specjalny format umożliwiający szybki import dokumentacji do bazy danych i udostępnienie np. możliwości jej komentowania on-line.&lt;/li&gt;
&lt;li&gt;TF oprawia dokumentację w bardzo ładną szatę graficzną, którą możecie podziwiać np. w dokumentacji do OPTv2 (robionej właśnie w TF).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Wprawdzie wydania żadnego jeszcze nie było, ale chętni mogą już teraz połączyć się z naszym nowym SVN-em i ściągnąć projekt stamtąd. Link do polecenia &lt;em&gt;checkout&lt;/em&gt; jest następujący: &lt;em&gt;http://svn.invenzzia.org/svn/typefriendly/trunk/&lt;/em&gt; - serdecznie zachęcam już teraz do testów. W repozytorium jest plik README oraz będąca już na ukończeniu dokumentacja w języku polskim.&lt;/p&gt;


&lt;p&gt;Żeby nie być gołosłownym, pokażę co ciekawsze opcje na przykładzie paru fragmentów. Pierwszym z nich będzie jeden z plików manuala OPTv2 (library.optnode.txt):&lt;/p&gt;

&lt;pre&gt;
Title: Klasa optNode
ShortTitle: optNode
Status: abstract
Extends: library.optcodebuffer
ExtendedBy:
 - library.optscannable
 - library.optcharacterdata
 - library.optexpression

----
Abstrakcyjna klasa węzła. Zapewnia obsługę podstawowych własności, jak rodzic i typ.

Pola klasy
----------
Wszystkie pola klasy są chronione.

 Nazwa         | Typ       | Opis
---------------|-----------|---------------------------------------
 $type         | Integer   | Numeryczny identyfikator typu.
 $parent       | optNode   | Rodzic węzła.

Dostępne identyfikatory typów:

1. `OPT_CDATA_NODE` - `optCharacterData`
2. `OPT_TEXT_NODE` - `optText`
3. `OPT_EXPRESSION_NODE` - `optExpression`
4. `OPT_ELEMENT_NODE` - `optElement`
5. `OPT_ROOT_NODE` - `optRoot`
&lt;/pre&gt;


&lt;p&gt;Na początku pliku znajduje się nagłówek, w którym umieszczamy tzw. tagi. Tam właśnie określany jest właściwy tytuł, a w tym wypadku również zależności między klasami. Zauważmy, że do innych klas odwołujemy się, podając identyfikatory rozdziałów, które je opisują. Oczywiście każdy z tych &quot;obiektowych&quot; tagów posiada także wersję, gdzie nazwy możemy wpisać bezpośrednio (np. gdybyśmy dziedziczyli po klasie wbudowanej w PHP). Dostępnych tagów jest więcej. Przykładowo, można bardzo łatwo zrobić listę &quot;Zobacz także&quot;, która wygląda mniej więcej tak:&lt;/p&gt;

&lt;pre&gt;
SeeAlso:
 - chapter.text1
 - chapter.text2
 - chapter.text3
&lt;/pre&gt;


&lt;p&gt;Gdy lista tagów dobiegnie końca, przechodzimy do właściwej treści pisanej w formacie &lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot; hreflang=&quot;pl&quot;&gt;Markdown&lt;/a&gt;. Autor zaprojektował go bazując na formatowaniu używanym powszechnie w rozmaitych plikach tekstowych czy e-mailach (można powiedzieć, że napisał parser do składni, która sama wyewoluowała :)). Tekst źródłowy jest przez to niesamowicie czytelny i na dobrą sprawę czyta się go niewiele gorzej, niż gdyby był faktycznie sformatowany. Trochę gorzej, gdy ktoś jest przyzwyczajony już do jakiejś składni wiki, bo MD nie zawsze takowe wiki przypomina (zwróćcie uwagę chociażby na sposób wykonania tabelki). Jednak można się dość łatwo przyzwyczaić - w Markdownie klepiemy również teksty na naszą stronę i muszę powiedzieć, że jest to całkiem przyjemne narzędzie, które z pewnością ujrzycie w niejednym produkcie Invenzzii. Jedyny mankament jest taki, że oficjalny parser obsługuje tylko jeden słuszny format - XHTML. O LaTeXu czy innych na razie trzeba niestety zapomnieć, ale na to już ostrzymy sobie zęby :).&lt;/p&gt;


&lt;p&gt;Najgorszy problem przy tworzeniu dokumentacji to nawigacja. Linki &quot;Poprzedni/Następny/W górę&quot; załatwia TypeFriendly, sekcję &quot;Zobacz także&quot; robimy za pomocą znaczników, a co z klikalnymi nazwami funkcji i klas? Myślałem nad tym i wymyśliłem rozwiązanie genialne w swej prostocie. W dodatkowym pliku tekstowym definiujemy kawałki tekstów, które mają zostać zamienione na odnośnik. Przykładowo, wpisujemy tam, że &lt;code&gt;`optClass::parse()`&lt;/code&gt; ma, oprócz nadania mu standardowego formatowania, zostać zmienione na odnośnik do &lt;em&gt;library.optclass.parse&lt;/em&gt; i już się niczym więcej przejmować nie musimy. Niestety, do takich przeróbek Markdowna jeszcze nie doszliśmy i pierwsza wersja tego bajeru nie będzie jeszcze zawierać. Wszystko w swoim czasie.&lt;/p&gt;


&lt;p&gt;TypeFriendly obsługiwany jest w całości z konsoli systemu operacyjnego. Testowaliśmy go na Linuksie i Windowsie - w obu systemach działa póki co bez zarzutów. Do działania potrzebny jest wyłącznie interpreter PHP. W połączeniu z intuicyjną składnią oraz wbudowanym wsparciem dla wielojęzyczności powinno to zachęcić wielu ludzi do pomocy przy tłumaczeniach, rozwoju oryginalnej wersji, a nawet tworzeniu nowych wyjść. Przetworzenie naszych plików na XHTML to kwestia wklepania jednego polecenia:&lt;/p&gt;

&lt;pre&gt;
php ./typefriendly.php -l pl -o xhtml ./sciezka/do/dokumentacji/
&lt;/pre&gt;


&lt;p&gt;Porównajmy to z DocBookiem - sam format jest nieco bardziej rozwlekły, ale stosunkowo łatwy do opanowania. Do konwersji jednak potrzeba trochę więcej narzędzi - DTD, sam zestaw DocBok XSL Stylesheet i wreszcie sam parser XSLT. Jego wybór jest nie bez znaczenia, gdyż ze zwykłym, szybkim i łatwym w użyciu xsltproc nie dostaniemy np. kolorowania składni. Użytkownicy Windowsa natomiast mają kompletnie prze.... jeśli autor projektu dodatkowo zrobi na DocBooku framework do budowania dokumentacji, w którym część narzędzi napisana jest w... Bashu. Nie trzeba takich kwiatków daleko szukać - jak myślicie, co odpowiada za dokumentację PHP? :) Z chęcią bym do niej coś popisał, gdyby choć raz udało mi się uruchomić ichniejszy framework i cokolwiek przetworzyć.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/TypeFriendly#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/TypeFriendly#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/29</wfw:commentRss>
      </item>
    
  <item>
    <title>SVN uruchomiony</title>
    <link>http://blog.invenzzia.org/pl/post/SVN-uruchomiony</link>
    <guid isPermaLink="false">urn:md5:b069e5e0e7b55faeecfa3fd56ebdc85a</guid>
    <pubDate>pon, 30 cze 2008 08:08:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Invenzzia</category>
        <category>development</category><category>svn</category>    
    <description>    &lt;p&gt;Niestety porządna konfiguracja systemu kontroli wersji na naszym serwerze nie jest tak łatwa i przyjemna, jak na Sourceforge.net, aczkolwiek w końcu znalazłem czas i pomysł, jak to wykonać. Repozytorium działa pod adresem http://svn.invenzzia.org/ z tym, że nie została jeszcze zainstalowana żadna porządna jego przeglądarka. W ciągu dnia wrzucę tam aktualny kod przebudowywanych Open Power Libs oraz bliskie ukończenia pierwszej wersji 0.1.0 TypeFriendly do tworzenia dokumentacji, zaś wszystkie informacje odnośnie połączenia znajdą się na stronie głównej.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/SVN-uruchomiony#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/SVN-uruchomiony#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/27</wfw:commentRss>
      </item>
    
  <item>
    <title>OPT 2.0.0-dev6</title>
    <link>http://blog.invenzzia.org/pl/post/OPT-200-dev6</link>
    <guid isPermaLink="false">urn:md5:e3094cab72537f268ece4f7353879f33</guid>
    <pubDate>sob, 10 maj 2008 14:15:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>development</category><category>dokumentacja</category><category>opt2</category>    
    <description>&lt;p&gt;Do ściągnięcia dostępna jest wreszcie kolejna wersja rozwojowa OPT. Jej zawartość opisałem w poprzednim wpisie, dlatego tu dodam tylko, że wbrew zapowiedziom, nie ma jeszcze instrukcji &lt;code&gt;opt:grid&lt;/code&gt; z powodów, które zaraz wyjaśnię. Ponadto nie da się jeszcze ustawiać statusu escape'owania dla pojedynczego szablonu, ale takowy z globalnej konfiguracji i ustawień wyrażenia w klamerkach już działa ładnie. Za to dodałem implementację instrukcji &lt;code&gt;opt:capture&lt;/code&gt; i częściową &lt;code&gt;opt:cycle&lt;/code&gt;. Polskich użytkowników z pewnością ucieszy informacja, że podczas długiego weekendu doprowadziłem do względnego porządku nasz nowy system dokumentowania TypeFriendly i OPT 2 ma już nową, ładną dokumentację :)&lt;/p&gt;    &lt;p&gt;Dostałem niedawno parę pytań, czy można już powoli zacząć używać OPT 2 w rzeczywistych projektach. Odpowiadałem, że większość rzeczy już jest gotowa i w nich raczej zmian nie będzie, aczkolwiek nic nie gwarantuję. W kolejnym devie okaże się, że dobrze zrobiłem, nic nie gwarantując, ponieważ OPT wymaga paru drastycznych zmian.&lt;/p&gt;


&lt;h2&gt;Sekcje&lt;/h2&gt;


&lt;p&gt;Od strony szablonu wszystko zostaje po staremu, za to zmieni się trochę interfejs skryptowy. W OPT już od pewnego czasu istnieją elementy pozwalające uniezależnić szablony od interfejsów skryptu, dzięki czemu zmiany w silniku nie muszą iść w parze z przepisywaniem wszystkich szablonów, co jest bolączką innych parserów (w tym Smarty'ego, gdzie na forach widziałem już takie cudaczne konstrukcje, że aż głowa może rozboleć). Sekcje już od dawna stanowiły jedną z nich, gdyż skrywały sposób łączenia sekcji podrzędnych i nadrzędnych, a także zawierały obsługę generowania danych &quot;w locie&quot; oraz alternatywny format tablic. Wszystko to było jednak zakodowane na sztywno w kodzie, a dodanie doń czegoś nowego jest kłopotliwe. Przecież formaty danych mogą być jeszcze inne, stąd pomysł, by wprowadzić modularyzację samych sekcji. Instrukcja jako taka zapewnia wyłącznie szkielet podpinający wszystko, gdzie trzeba w drzewku XML. My natomiast za pomocą pluginów możemy łatwo nauczyć sekcję, żeby np. pobierała dane np. bezpośrednio z PHP-Doctrine czy też iterowała po obiekcie :). Zastosowanie:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;opt:section name=&amp;quot;foo&amp;quot;&amp;gt;
 {$foo.bar}
&amp;lt;/opt:section&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Nie musimy się już martwić, czy element &lt;code&gt;foo&lt;/code&gt; jest obiektem, a my odwołujemy się do pola &quot;bar&quot;, czy też tablicą. Po stronie szablonu &lt;code&gt;foo.bar&lt;/code&gt; oznacza blok &quot;bar&quot; w elemencie &quot;foo&quot;, natomiast zadaniem skryptu jest nadanie mu jakiegoś konkretnego znaczenia (tablica, obiekt itd.). Analogicznie, nie obchodzi nas również budowa danych dla sekcji jako takiej - czy to jest sekcja dynamiczna, czy tablica w jakimś formacie, czy też obiekt... Wszystko będzie można łatwo zaprogramować.&lt;/p&gt;


&lt;p&gt;Po stronie skryptu pojawi się metoda w stylu &lt;em&gt;setSectionType&lt;/em&gt; służąca do określenia, jak OPT powinien przetworzyć daną sekcję:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;$tpl -&amp;gt; setSectionType('foo', 'mojPluginObiektowy');
$tpl -&amp;gt; assign('foo', new obiektPoKtorymMoznaIterowac);
&lt;/pre&gt;


&lt;p&gt;Gdy nie określiliśmy typu, OPT wybierze standardową postać tablicową.&lt;/p&gt;


&lt;p&gt;Zalety:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Po stronie szablonu już nas kompletnie nic nie obchodzi. Sekcje możemy kopiować metodą Ctrl+C, a one bez zmiany jednego znaku w pełni dostosują się do sytuacji w nowym szablonie bez naszej ingerencji.&lt;/li&gt;
&lt;li&gt;Koniec narzekań, czemu sekcje nie obsługują czegośtam, albo że format jest debilny :)&lt;/li&gt;
&lt;li&gt;Jednolita kontrola obsługi po stronie skryptu.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Modularyzacja kompilatora&lt;/h2&gt;


&lt;p&gt;Kompilator zostanie rozbity na większą ilość mniejszych plików, gdyż jest on ładowany raz na jakiś czas i zyski ze zbicia wszystkiego w dwa mega-pliki są znikome. Wpływ na skrypty korzystające z OPT powinien być zerowy.&lt;/p&gt;


&lt;h2&gt;Zmiany w obsłudze błędów&lt;/h2&gt;


&lt;p&gt;Niebawem pojawi się Open Power Classes 1.0.0-dev1, a w planach są też inne projekty. Jeśli ma to być coś więcej, niż tylko zbiór bibliotek o podobnej nazwie, trzeba ujednolicić niektóre elementy. Oczywiście wspólną częścią jest obsługa błędów - każda z bibliotek musi więc zawierać taki sam plik z odpowiednim współdzielonym kodem, który może być używany przez wszystkie z nich jednocześnie. Jeżeli poza przechwytywaniem wyjątku optException i kierowaniem go do &lt;code&gt;optErrorHandler()&lt;/code&gt; nie robisz z nim nic więcej, wtedy zmiana nie powinna Cię dotknąć.&lt;/p&gt;


&lt;h4&gt;Poprawa hermetyzacji klasy głównej!!&lt;/h4&gt;


&lt;p&gt;Rzecz musi zostać ujednolicona, żeby nie powstała kolejna niedorzeczność pod postacią &quot;dlaczego jedne dane są chronione, choć potrzebuje ich kompilator, a inne nie&quot;. Jeśli odwoływałeś się wyłącznie do pól konfiguracyjnych, zmiana nie powinna Cię dotknąć.&lt;/p&gt;


&lt;h2&gt;Nowa dokumentacja&lt;/h2&gt;


&lt;p&gt;Jak pisałem, wreszcie OPT 2 posiada nową, zapowiadaną jakiś czas temu dokumentację. Za jej generowanie odpowiada napisany w PHP silnik TypeFriendly obsługujący m.in. kolorowanie składni. Zostanie on wydany na licencji GNU GPL, gdy tylko uporządkuję trochę jego kod i napiszę dokumentację pokazującą, jak z niego korzystać. Tak czy inaczej jego obecność pozwoli nawet na takie bajery, jak wersja on-line dokumentacji z komentarzami użytkowników.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/OPT-200-dev6#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/OPT-200-dev6#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/26</wfw:commentRss>
      </item>
    
  <item>
    <title>Co nowego w OPT</title>
    <link>http://blog.invenzzia.org/pl/post/Co-nowego-w-OPT</link>
    <guid isPermaLink="false">urn:md5:4836080a510835be9e024045bcef96b6</guid>
    <pubDate>nie, 27 kwi 2008 13:06:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>development</category><category>opt2</category>    
    <description>&lt;p&gt;Minęło już trochę czasu od ostatnich wieści z frontu, dlatego naprawiam zaległości. Za jakiś tydzień pojawi się kolejna wersja developerska. Prace posunęły się jeszcze dalej do przodu. Obejmują one zaimplementowanie kolejnych &quot;brakujących&quot; elementów, a także (co powinno niektórych ucieszyć) - zmniejszanie zużycia zasobów serwera w trakcie kompilacji. Zobaczmy zatem, z czym będziemy mieli do czynienia.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Pochodne sekcji&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Nowe pochodne sekcji: &lt;code&gt;opt:tree&lt;/code&gt; oraz &lt;code&gt;opt:grid&lt;/code&gt;. Pierwszą z nich znamy już z OPT 1 i służy do renderowania drzew. Zmianie uległa jej składnia, ponieważ na nowym kompilatorze nie da się tak beztrosko szlachtać HTML-a, nie domykając znaczników. Z drugiej strony wymusiło to wprowadzenie bardziej czytelnego formatu. Popatrzmy na to:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;  &amp;lt;opt:tree name=&amp;quot;mytree&amp;quot;&amp;gt;
  	&amp;lt;opt:list&amp;gt;&amp;lt;ul&amp;gt;&amp;lt;opt:content/&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/opt:list&amp;gt;
  	&amp;lt;opt:node&amp;gt;&amp;lt;li&amp;gt;{$mytree.title} &amp;lt;opt:content /&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/opt:node&amp;gt;  
  &amp;lt;/opt:tree&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Czyli innymi słowy - definiujemy wygląd listy, definiujemy wygląd węzła i mówimy, w którym miejscu mogą się one zagnieżdżać. Algorytm przetwarzania takiego drzewa, jaki OPT wstawia do skompilowanego szablonu, opiera się na pewnej sztuczce, ale jest skuteczny. Oczywiście format danych jest taki sam, jak w poprzednich wersjach - do danych sekcji musimy dołączyć pole &quot;depth&quot; z głębokością elementu.&lt;/p&gt;


&lt;p&gt;Całkowitą nowość stanowi &lt;code&gt;opt:grid&lt;/code&gt;. Jego działanie opiszę na przykładzie. Z pewnością każdy widział internetowe galerie zdjęć. Miniaturki są tam ułożone w tabelce, np. po 5 w jednym wierszu. Rzadko się zdarza, by liczba elementów była wielokrotnością tejże piątki, dlatego przeważnie część ostatniego wiersza będzie pusta. Można to rozwiązać za pomocą CSS-a (sposób podał niedawno na naszym forum eXtreme), lecz czasem po prostu trzeba narysować rzeczywistą tabelę. Sam algorytm opiera się na sprawdzaniu reszty z dzielenia indeksu, ale &lt;em&gt;dlaczego ma się tym w ogóle zajmować szablon?&lt;/em&gt; Zgodnie z filozofią OPT, powinniśmy przecież mówić tylko, co chcemy zrobić, a nie instruować krok po kroku - JAK. Stąd też instrukcja &lt;code&gt;opt:grid&lt;/code&gt;:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;table&amp;gt;
&amp;lt;opt:grid name=&amp;quot;tabelka&amp;quot; cols=&amp;quot;3&amp;quot;&amp;gt;
 &amp;lt;tr&amp;gt;
  &amp;lt;opt:item&amp;gt;
   &amp;lt;td&amp;gt;&amp;lt;img parse:src=&amp;quot;$tabelka.zdjecie&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;
  &amp;lt;/opt:item&amp;gt;
  &amp;lt;opt:emptyItem&amp;gt;
   &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;
  &amp;lt;/opt:emptyItem&amp;gt; 
 &amp;lt;/tr&amp;gt;
&amp;lt;/opt:grid&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Instrukcją obejmujemy cały wiersz, a w nim dodatkowo zaznaczamy, jak mają się wyświetlać poszczególne komórki. Mamy tu dwa warianty. &lt;code&gt;opt:item&lt;/code&gt; mówi, jak wygląda komórka z danymi, zaś &lt;code&gt;opt:emptyItem&lt;/code&gt; - jak komórka bez danych. Wprawieniem tego w ruch zajmuje się OPT. Instrukcja gridu przyjmuje identyczny format danych, jak zwykła sekcja.&lt;/p&gt;


&lt;p&gt;Skoro przy sekcjach jesteśmy, zmienia się składnia wywołań z &quot;else&quot; w nazwie. Dotąd były to znaczniki bez treści, wizualnie rozdzielając zawartość rodzica na dwie części. Okazało się jednak, że z paru powodów muszę zrezygnować z takiego zapisu na rzecz następującej konstrukcji:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;opt:section name=&amp;quot;foo&amp;quot;&amp;gt;
  Tutaj treść sekcji

  &amp;lt;opt:sectionelse&amp;gt;
      Tutaj to, co się dzieje, gdy lista jest pusta.
  &amp;lt;/opt:sectionelse&amp;gt;

&amp;lt;/opt:section&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Miejsce umieszczenia tego znacznika jest teraz bez znaczenia - OPT sam sobie go przesunie tam, gdzie trzeba, żeby wygenerowany z tego kod PHP miał sens.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Automatyczne escape'owanie&lt;/strong&gt;
OPT 1 w ogóle nie zajmował się escape'owaniem danych ze skryptu podczas ich wyświetlania. Zmianę jakościową wprowadzi teraz OPT 2, zaś twórca szablonów będzie mieć nad tym procesem pełną kontrolę. Założenia są następujące:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Wszystko, co próbujemy wyświetlić we wnętrzu atrybutu XML, musi być escape'owane przez &lt;em&gt;htmlspecialchars()&lt;/em&gt; i od tego nie ma &quot;zlituj&quot; w trybie XML.&lt;/li&gt;
&lt;li&gt;Wyrażenia w klamerkach domyślnie także są escape'owane, lecz nad tym procesem programista ma kontrolę. Status escape'owania może być zdefiniowany globalnie w konfiguracji OPT, w głównym znaczniku szablonu (jego zasięg obejmie wtedy tylko aktualny szablon) lub też pojedyncze wyrażenie za pomocą dwóch modyfikatorów &lt;em&gt;e&lt;/em&gt; lub &lt;em&gt;u&lt;/em&gt; wstawionych na jego początek. Przykłady: &lt;code&gt;{e:$blok}&lt;/code&gt; oraz &lt;code&gt;{u:$blok}&lt;/code&gt;. Oczywiście działa to inteligentnie, tzn. jeśli włączyliśmy escape'owanie globalnie, dodanie modyfikatora nie spowoduje, że blok zostanie przetrawiony dwukrotnie. Dostępna będzie również specjalna funkcja &lt;em&gt;esc()&lt;/em&gt; pozwalająca na escape'owanie tylko konkretnego elementu wyrażenia.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;System językowy&lt;/strong&gt;
OPT 2 zawiera zmieniony interfejs do integracji z systemem językowym, lecz dotąd nie był on w ogóle nigdzie przez kod wykorzystywany. Obsługa pojawi się w najnowszym devie, w składni identycznej, jak w OPT 1.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;System stronicowania&lt;/strong&gt;
Zmianom uległ także interfejs integracji z systemem stronicowania oraz po części składnia instrukcji &lt;code&gt;opt:pagesystem&lt;/code&gt;. W tej chwili szczegóły jeszcze dopracowujemy. Obie te rzeczy pojawiają się teraz dlatego, gdyż równolegle z OPT 2.0.0-dev6 ukaże się pierwsza wersja developerska nowego projektu o nazwie &lt;em&gt;Open Power Classes&lt;/em&gt;. Jest to zbiór niewielkich klas o różnych zadaniach, które są zbyt małe, by je pakować i szumie ogłaszać jako kolejne projekty (każdy projekt Open Power XXX musi posiadać unikalny kod literowy, a ilość liter w alfabecie jest niestety ograniczona :)). Na dzień dobry znajdą się tam dwie klasy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;opcPagination&lt;/code&gt; - system stronicowania kompatybilny z OPT autorstwa eXtreme'a.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;opcCharts&lt;/code&gt; - API dla Google Charts stworzone przez Radzia&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;W późniejszych wersjach dojdzie jeszcze m.in. system językowy.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Optymalizacje&lt;/strong&gt;
Optymalizacji jest kilka:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Zużycie pamięci. Polega ono na wyszukiwaniu miejsc, w którym skrypt mógłby zwalniać pamięć i obiekty, ale jednak tego nie robi. W kompilatorze rezygnuję również z domyślnej inicjacji pustych tablic, gdyż każda taka struktura to strata rzędu przynajmniej 400 bajtów, a często nie są one potrzebne.&lt;/li&gt;
&lt;li&gt;Głębokość rekurencji - jakiś czas temu pisałem o zbyt szybkim zjadaniu stosu przez OPT z powodu użycia rekurencyjnego algorytmu przetwarzania węzłów drzewa. W OPT 1 nie było z tym problemu, gdyż węzłami były jedynie instrukcje, zaś tutaj domagał się tego każdy znacznik HTML. Wdrożyłem dlatego algorytm hybrydowy, który robi rekurencyjne wywołanie tylko wtedy, gdy faktycznie jest ono do czegoś potrzebne, zaś w przeciwnym wypadku wykorzystuje mechanizm kolejki u jednego z już pracujących przetwarzaczy. W praktyce każdy znacznik, który nie jest bezpośrednio obsługiwany przez OPT, przetwarzany jest teraz w ten sposób, dzięki czemu oszczędzamy stos. Również niektóre instrukcje mogą tak pracować.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Inne&lt;/strong&gt;
Nowy dev będzie zawierać także trochę pomniejszych poprawek. Zacząłem w końcu tworzyć zestaw testów dla poszczególnych instrukcji, dzięki czemu jestem w stanie sprawdzić zachowanie biblioteki dla znacznie większej liczby możliwych kombinacji i wychwycić rozmaite kretyńskie zachowania.&lt;/p&gt;


&lt;p&gt;PS. Pewnie niektórzy zauważyli, że mój blog zniknął z sieci. Informuję, że niebawem zostanie on przywrócony pod dotychczasowym adresem, zatem bez obaw.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Co-nowego-w-OPT#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Co-nowego-w-OPT#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/25</wfw:commentRss>
      </item>
    
  <item>
    <title>Wymagania OPT</title>
    <link>http://blog.invenzzia.org/pl/post/Wymagania-OPT</link>
    <guid isPermaLink="false">urn:md5:d0e794006c5d5f0728882df9a161f559</guid>
    <pubDate>sob, 05 kwi 2008 09:32:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>development</category><category>OPT2</category><category>optymalizacja</category>    
    <description>&lt;p&gt;Na bugtrackerze pojawiło się ostatnio zgłoszenie informujące o błędzie &quot;Nesting level too deep - recursive dependency&quot; przy próbie uruchomienia jednego z przykładów w najnowszej wersji rozwojowej OPTv2. Po dokładniejszych oględzinach wyszło na jaw, że winny jest zbyt wyśrubowany limit ustawiony w konfiguracji PHP przez autora zgłoszenia (ponad czterokrotnie mniejszy, niż wartość domyślna). Jednak przy tej okazji myślę, że warto trochę bardziej przyjrzeć się temu, jakie wymagania postawi nowy OPT interpreterowi i wyjaśnić kilka spraw z tym związanych.&lt;/p&gt;    &lt;p&gt;Optymalizacje, jakie implementuję w OPT, dotyczą przede wszystkim głównej klasy parsera oraz kompilatora. Pierwsza z nich, jako część kodu ładowana każdorazowo, ma narzucone bardzo wyśrubowane wymagania. Nie ma tutaj wyszukanych algorytmów, dlatego przyspieszanie działania dotyczy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zmniejszania objętości kodu.&lt;/li&gt;
&lt;li&gt;Minimalizacji odwołań do dysku twardego.&lt;/li&gt;
&lt;li&gt;Wykorzystaniem najwydajniejszych elementów języka.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chodzi o to, aby załadowanie biblioteki było jak najmniej obciążające dla interpretera, a w konsekwencji używającego ją skryptu.&lt;/p&gt;


&lt;p&gt;Nieco inaczej sprawa wygląda z kompilatorem, który ładowany jest tylko okazjonalnie, zatem może być obszerny i rozbity na więcej składowych (aczkolwiek bez zbędnej przesady). Tutaj kluczową rolę zaczynają odgrywać limity ustawione w konfiguracji PHP, gdyż przy szczególnie złych wiatrach może się zdarzyć, że kompilator zużyje wszystkie dostępne zasoby. Niestety, powiększona funkcjonalność kosztuje, a skoro użytkownicy pragnęli mieć parsowanie także XML-owych znaczników, muszą liczyć się z tym, że dla każdego z nich trzeba teraz tworzyć obiekt węzła i dla każdego z nich trzeba wykonać trochę prac przygotowawczych. Moją rolą jest tutaj uczynienie tego zużycia tak małego, jak to tylko jest możliwe.&lt;/p&gt;


&lt;p&gt;Elementy, które mogą się wyczerpać podczas używania kompilatora to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stos&lt;/li&gt;
&lt;li&gt;Pamięć operacyjna&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wykorzystywane algorytmy, z racji operowania na strukturze zwanej drzewem, korzystają dość mocno z rekurencji, przez co liczba aktualnie wykonywanych funkcji i metod szybko rośnie. W PHP domyślnym limitem narzuconym na głębokość rekurencji jest 64 i do pracy z OPT najlepiej zostawić go na takim poziomie, a już na pewno nie bawić się w jego zmniejszanie do jakichś śmiesznych wartości pokroju &quot;16&quot;, co zresztą zaszkodziłoby nie tylko OPT, ale i wielu innym skryptom :). Każdą rekurencję można jednak zastąpić iteracyjną wersją, która może i nie zużywa mniej pamięci, ale przynajmniej jest niezależna od wspomnianego limitu. Odpowiednie przeróbki wprowadzone są już teraz do wielu metod, które zamiast wywoływać się rekurencyjnie, korzystają np. z kolejek. Najgorzej sprawa wygląda z dwoma algorytmami:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Przetwarzanie drzewa przez procesory instrukcji&lt;/li&gt;
&lt;li&gt;Kompilacja wyrażeń&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;W pierwszym z nich mamy następującą sytuację: odnajdujemy węzeł jakiejś instrukcji i musimy go przetworzyć. Kierujemy go więc do odpowiedniego procesora (klasa pochodna od &lt;code&gt;optInstruction&lt;/code&gt;), on generuje do niej kod PHP i decyduje, co zrobić z dziećmi danego węzła. Zazwyczaj decyduje się na ich obróbkę. Tu wkracza wywołanie rekurencyjne i cały proces powtarza się od początku. Trudności to rozrzucenie całego algorytmu po mnóstwie klas, które mogą być na dokładkę oficjalnie rozbudowywane przez zainteresowanych programistów. Co więcej, niektóre instrukcje wymagają, aby przetwarzanie rozpoczęło się natychmiast wraz z wywołaniem metody przetwarzającej, ponieważ od tego, jaki kod PHP wygenerują sobie potomkowie, zależy dalsza obróbka ich rodzica. Eliminuje to w oczywisty sposób kolejkę. Stworzenie eleganckiego zamiennika byłoby proste, gdybyśmy mieli dostęp do programowania niskopoziomowego, lecz tak nie jest.&lt;/p&gt;


&lt;p&gt;Popatrzmy, jak to wpłynie na kompilację. Mamy jakiś rozbudowany szablon, w którym znaczniki zagnieżdżone są aż do głębokości 30. Sam OPT z kompilatorem może w porywach zużyć dodatkowe 10 zagnieżdżeń, zaś w najgłębszym miejscu jest na dokładkę jeszcze skomplikowane wyrażenie z nawiasami. Zatem całość zużyje ok. 45 wywołań, z dostępnych 64, czyli ponad 70% limitu! I choć przypadek jest dość pesymistyczny, bo prawdę mówiąc mi się nigdy nie zdarzyło, żebym musiał robić jakiś plik HTML z 30-ma zagnieżdżonymi znacznikami, to jednak pokazuje on, że kompilacja to proces wymagający.&lt;/p&gt;


&lt;p&gt;Skoro bez brzydkich sztuczek, które nie spodobałyby się na pewno twórcom instrukcji, nie da się usunąć rekurencji, to jak sobie z tym poradzić? Wpadłem na pomysł, gdzie rekurencji nie usuwamy, lecz za to drastycznie ją ograniczamy. Korzystam tutaj z faktu, że natychmiastowy dostęp do tego, co wykompilowały dzieci, jest potrzebny tylko kilku instrukcjom, natomiast np. zwyczajnym znacznikom XML/HTML jest to po grzyba, gdyż one i tak nie wiedzą, co z tym zrobić. Mamy więc sporą szansę, że gdy wybierzemy losowy węzeł z drzewa, trafimy na taki, któremu rekurencja jest niepotrzebna. Dlaczego więc nie zaproponować dwóch wersji algorytmu: imperatywnej i rekurencyjnej, w zależności od potrzeb? Tam, gdzie instrukcje robią czary, mogą sobie zażyczyć prawdziwej rekurencji, natomiast normalnie wszystko idzie poprzez kolejki. Wtedy przy dobrych wiatrach, takie drzewo o głębokości 30, może być przetworzone na jeden raz, bez żadnej rekurencji! W normalnych warunkach natomiast zejdzie ona na głębokość 3, 4, co jest już akceptowalne.&lt;/p&gt;


&lt;p&gt;Druga sprawa dotyczy zużycia pamięci. Wprawdzie nie jest tu aż tak tragicznie, ale da się zauważyć wyraźne zwiększenie zapotrzebowania w porównaniu z kompilatorem do OPT 1.x, nawet pomimo wykorzystania patentów z tamtego projektu. Większość tego zajmuje oczywiście samo drzewo. Mierzyłem ostatnio zużycie pamięci generowane przez pojedyncze obiekty węzłów i wyniki wahały się w granicach 2 kilobajtów na pusty obiekt bez udziwnień, natomiast przy dodaniu atrybutu, rosło średnio o kilobajt. Gdy instrukcje zaczną dopisywać do buforów kod PHP, sprawa się pogarsza, ale dotyczy to tylko wybranych węzłów w całym szablonie. Okazuje się, że możemy tu trochę zaoszczędzić. Obiekty wykorzystują kilka tablic, które dotąd były automatycznie inicjowane na samym początku, na przykład:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;abstract class optScannable extends optNode implements Iterator
{
	protected $subnodes = array();
&lt;/pre&gt;


&lt;p&gt;W większości węzłów część tych tablic stoi pusta, więc nie ma sensu, aby były one cały czas stworzone. Poprawiłem kod tak, aby odpowiednie metody tworzyły pustą tablicę dopiero, gdy będzie ona potrzebna, zaś z deklaracji wywaliłem dopiski &lt;code&gt;= array()&lt;/code&gt;. Dało to ciekawy efekt: na jednej tak wywalonej tablicy zacząłem oszczędzać 400 bajtów. Nowe rezultaty pomiarów są następujące:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Węzeł bez atrybutów: 1400 b.&lt;/li&gt;
&lt;li&gt;Węzeł z jednym atrybutem: 2350 b.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dodatkowa oszczędność może zostać osiągnięta dzięki pamiętaniu o kasacji niepotrzebnych już danych o dużej objętości, jak np. treść szablonu.&lt;/p&gt;


&lt;p&gt;O czym należy pamiętać, korzystając z nowego OPT, jeśli chodzi o kwestie wydajnościowe:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Z wyśrubowanymi limitami kompilator na pewno będzie się wysypywać. Myślę, że 16 MB pamięci dla skryptu (aktualny domyślny limit) to wartość na tyle rozsądna, by kompilator mógł odwalić dobrą robotę nawet z całkiem rozbudowanym szablonem oraz jednocześnie aby zostało coś dla skryptu.&lt;/li&gt;
&lt;li&gt;Parsowanie szablonu najlepiej uruchamiać na końcu, kasując przedtem w skrypcie niepotrzebne już dane o dużej objętości.&lt;/li&gt;
&lt;li&gt;Kompilacja szablonów z dziedziczeniem może wymagać więcej pamięci, szczególnie przy nadpisywaniu już istniejących snippetów (parser musi trzymać w pamięci również nadpisane wersje).&lt;/li&gt;
&lt;li&gt;Niezaimplementowany jeszcze tryb tekstowy (quirks mode) wymagać będzie znacznie mniej pamięci dzięki uproszczonemu drzewu (brak znaczników XML).&lt;/li&gt;
&lt;li&gt;Kompilacja uruchamiana jest raz na długi czas; podczas normalnej pracy można spokojnie zapomnieć o istnieniu tych wszystkich wymagań.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Myślę, że ten wpis dość dobrze pokazuje, o ilu aspektach trzeba pamiętać, pisząc porządną bibliotekę. Klucz to wiedzieć, na ile można sobie w danym miejscu pozwolić i że oprócz biblioteki, gdzieś tam ma jeszcze w tej samej pamięci, w tej samej płaszczyźnie pracować wykorzystujący ją skrypt, który także ma swoje wymagania.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Wymagania-OPT#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Wymagania-OPT#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/23</wfw:commentRss>
      </item>
    
  <item>
    <title>OPT 2.0.0-dev5</title>
    <link>http://blog.invenzzia.org/pl/post/OPT-200-dev5</link>
    <guid isPermaLink="false">urn:md5:7470fd5526a958ad88c9f3399bb23080</guid>
    <pubDate>czw, 20 mar 2008 14:27:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>development</category><category>komponenty</category><category>OPT2</category>    
    <description>&lt;p&gt;Upłynęło trochę więcej czasu, niż planowałem, od ostatniej wersji dev, lecz poniekąd w ramach rekompensaty dodałem do OPT sporą liczbę nowych rzeczy. Rozwiązanie sprawy DTD, prologów XML, obsługi sekcji CDATA i escape'owania kodu, dokończenie parsera wyrażeń czy wreszcie pełna implementacja komponentów są moim zdaniem znaczącym krokiem naprzód. Do końca prac jest już bliżej, niż dalej. Na zakodowanie czeka już tylko kilka instrukcji, prawie wszystkie pozostałe są już ukończone. Kompilator działa bardzo dobrze, na ukończeniu jest cały interfejs programistyczny, przechodząc ostatnie szlify. Niebawem planuję rozpocząć pierwsze testy bojowe na bazie mojej własnej strony domowej, a także rozpocząć tworzenie biblioteki Open Power Forms zgodnej z nową wersją.&lt;/p&gt;    &lt;p&gt;Nowy Open Power Template posiada całkowicie zmieniony mechanizm komponentów, który jest teraz znacznie bardziej elastyczny i pozwala na uzyskiwanie wielu ciekawych efektów niewielkim kosztem. Fundamentalne zasady działania pozostały, zmieniła się cała reszta. Oto przykładowa próbka pokazująca, jak teraz będzie wyglądać praca z formularzami budowanymi na bazie komponentów:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;opt:snippet name=&amp;quot;componentView&amp;quot;&amp;gt;
  &amp;lt;com:div class=&amp;quot;field&amp;quot; invalid=&amp;quot;field error&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;{$opt.component.title}: &amp;lt;opt:display /&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;p class=&amp;quot;desc&amp;quot; opt:if=&amp;quot;$opt.component.description&amp;quot;&amp;gt;{$opt.component.description}&amp;lt;/p&amp;gt;
    &amp;lt;opt:onEvent name=&amp;quot;error&amp;quot; message=&amp;quot;info&amp;quot;&amp;gt;
      &amp;lt;p class=&amp;quot;error&amp;quot;&amp;gt;{@info}&amp;lt;/p&amp;gt;
    &amp;lt;/opt:onEvent&amp;gt;
  &amp;lt;/com:div&amp;gt;
&amp;lt;/opt:snippet&amp;gt;

&amp;lt;div class=&amp;quot;form&amp;quot;&amp;gt;
&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;skrypt.php&amp;quot;&amp;gt;

&amp;lt;opt:input name=&amp;quot;imie&amp;quot; template=&amp;quot;componentView&amp;quot;&amp;gt;
   &amp;lt;opt:set name=&amp;quot;title&amp;quot; str:value=&amp;quot;Podaj swoje imię&amp;quot; /&amp;gt;
   &amp;lt;opt:set name=&amp;quot;description&amp;quot; str:value=&amp;quot;Przynajmniej 3 litery&amp;quot; /&amp;gt;
&amp;lt;/opt:input&amp;gt;

&amp;lt;opt:input name=&amp;quot;nazwisko&amp;quot; template=&amp;quot;componentView&amp;quot;&amp;gt;
   &amp;lt;opt:set name=&amp;quot;title&amp;quot; str:value=&amp;quot;Podaj swoje nazwisko&amp;quot; /&amp;gt;
   &amp;lt;opt:set name=&amp;quot;description&amp;quot; str:value=&amp;quot;Przynajmniej 3 litery&amp;quot; /&amp;gt;
&amp;lt;/opt:input&amp;gt;

&amp;lt;opt:input name=&amp;quot;wiek&amp;quot; template=&amp;quot;componentView&amp;quot;&amp;gt;
   &amp;lt;opt:set name=&amp;quot;title&amp;quot; str:value=&amp;quot;Podaj swój wiek&amp;quot; /&amp;gt;
   &amp;lt;opt:set name=&amp;quot;description&amp;quot; str:value=&amp;quot;Przedział: 10-99 lat&amp;quot; /&amp;gt;
&amp;lt;/opt:input&amp;gt;

&amp;lt;div class=&amp;quot;foot&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Wyślij&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Nowa implementacja w pełni wykorzystuje możliwości, jakie stwarza instrukcja &lt;code&gt;opt:snippet&lt;/code&gt; oraz dziedziczenie szablonów. Gdyby ktoś chciał, mógłby zaprogramować obiekty komponentów w ten sposób, że zbędne stanie się nawet ręczne podawanie opisów poszczególnych pól. Komponent może obsługiwać zdarzenia, wyświetlanie samego siebie oraz swojego otoczenia, zarządzać parametrami, a nawet ingerować w atrybuty wybranych znaczników HTML (do tego służy przestrzeń nazw &lt;code&gt;com&lt;/code&gt;). OPT sam z siebie zawierać będzie jedynie mechanizm, lecz nie będzie w nim ani jednego gotowego komponentu (poza przykładami, ale te nie są bezpośrednio częścią biblioteki). Po prostu aby w pełni wykorzystać cały potencjał, klasy komponentów powinny być zintegrowane z systemami kontroli formularzy, obsługą błędów, systemem językowym itd., a to wykracza daleko poza dziedzinę biblioteki. Gotową do natychmiastowego użycia implementacją komponentów będzie Open Power Forms.&lt;/p&gt;


&lt;p&gt;Niestety, w nowym devie lekko zawalona jest sprawa z dokumentacją. Po prostu TypeFriendly jeszcze specjalnie nie potrafi generować tego, co chcemy, a DocBookowej wersji nie rozwijałem, pisząc już wszystko w nowym formacie. Dlatego mam nadzieję, że nikomu nie stanie się krzywda, gdy zobaczy... zbiór źródłowych plików TXT, które trzeba przeglądać narzędziami notatnikopodobnymi :). Na pocieszenie dodam, że składnia Markdowna Extra jest bardzo czytelna dla człowieka (w sumie zaprojektowano ją właśnie na wzór &quot;formatowań&quot; stosowanych właśnie w e-mailach, plikach README itd.), dlatego poza brakiem nawigacji oraz kolorów nie powinno to być aż takie trudne w lekturze. Trzeba jedynie pamiętać o ustawieniu (na wszelki wypadek) uniksowych zejść do nowej linii i kodowania UTF-8.&lt;/p&gt;


&lt;p&gt;Wraz z publikacją nowej wersji, zamieściłem też na stronie bibliotek pierwszą partię oficjalnych, praktycznych porad do OPT. Oto linki do najważniejszych miejsc:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://libs.invenzzia.org/pl/download&quot; hreflang=&quot;pl&quot;&gt;Download&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://libs.invenzzia.org/pl/porady/open-power-template&quot; hreflang=&quot;pl&quot;&gt;Porady&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/OPT-200-dev5#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/OPT-200-dev5#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/20</wfw:commentRss>
      </item>
    
  <item>
    <title>OPT 2.0.0-dev4</title>
    <link>http://blog.invenzzia.org/pl/post/OPT-200-dev4</link>
    <guid isPermaLink="false">urn:md5:6305be4ea0eddac6cb766e2d3fd21899</guid>
    <pubDate>nie, 02 mar 2008 11:14:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>development</category><category>dziedziczenie</category><category>OPT2</category>    
    <description>&lt;p&gt;Do ściągnięcia jest już czwarta wersja developerska Open Power Template'a. Projekt zaczyna nabierać kształtów, jako że na ukończeniu jest już główna klasa parsera. Oprócz wzmiankowanego wcześniej cache'u, zaimplementowałem nowe instrukcje oraz skończyłem prace nad snippetami tak, że w zasadzie już całe dziedziczenie szablonów działa, jak należy. Mam nadzieję, że pod koniec miesiąca biblioteka będzie już w takim stanie, że będzie nadawać się do ostrożnego użycia. Rzeczywiste projekty będą potrzebne, aby wykryć błędy oraz końcowe niedociągnięcia.&lt;/p&gt;    &lt;p&gt;W snippetach pojawiła się możliwość wstawienia zawartości rodzica za pomocą znacznika &lt;code&gt;opt:parent&lt;/code&gt;:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot; ?&amp;gt;
&amp;lt;opt:extend file=&amp;quot;test_inherited_a.tpl&amp;quot;&amp;gt;
	&amp;lt;opt:snippet name=&amp;quot;header&amp;quot;&amp;gt;
		&amp;lt;h1&amp;gt;Webmaster Of Puppets&amp;lt;/h1&amp;gt;
		&amp;lt;p&amp;gt;Here is the parent content:&amp;lt;/p&amp;gt;
		&amp;lt;opt:parent/&amp;gt;
		&amp;lt;p&amp;gt;End of the parent content&amp;lt;/p&amp;gt;
	&amp;lt;/opt:snippet&amp;gt;
&amp;lt;/opt:extend&amp;gt;
&lt;/pre&gt;


&lt;p&gt;W tym wypadku, jeżeli w pliku &lt;em&gt;test_inherited_a.tpl&lt;/em&gt; zdefiniowaliśmy snippet o identycznej nazwie, jego zawartość trafi na miejsce znacznika &lt;code&gt;opt:parent&lt;/code&gt;. Takie zagnieżdżanie działa wielopoziomowo. Gdyby i w tamtym snippecie użyto tego mechanizmu, OPT sięgnąłby jeszcze głębiej i tak dalej. Możliwe jest nawet wyciągnięcie domyślnej zawartości bloku &lt;code&gt;opt:insert&lt;/code&gt;, do którego ostatecznie snippet będzie wstawiony. Do całości dodałem na dokładkę prosty kod wykrywający nieskończoną rekurencję. Gdy taka zostanie wykryta, programista otrzyma elegancki, czerwony komunikat błędu :).&lt;/p&gt;


&lt;p&gt;Przy korzystaniu z nowego OPT powinna znacząco przydać się nowa konsola debugowa, rozszerzona w stosunku do analogicznej opcji w OPT 1.1.x. Główna zmiana dotyczy rozbicia listy wykonanych szablonów na mniejsze listy, które pokazują różne informacje:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Lista wykonanych szablonów&lt;/li&gt;
&lt;li&gt;Lista aktualnie przekompilowanych szablonów&lt;/li&gt;
&lt;li&gt;Lista szablonów wczytanych z cache'u.&lt;/li&gt;
&lt;li&gt;Lista dziedziczenia szablonów - pokazuje użyte łańcuch zależności wraz z informacją, czy były one właśnie rekompilowane, czy nie.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dodatkowo, konsola wyświetla wszystkie ostrzeżenia, które w tej wersji nie są już bezczelnie ładowane na ekran. Można się do nich dostać jedynie poprzez konsolę debugową lub komunikat błędu, o ile ustawiliśmy odpowiedni poziom debugowania.&lt;/p&gt;


&lt;p&gt;Sprawa wydajności przedstawia się bardzo dobrze. Ostatecznie zamknąłem plik &lt;em&gt;opt.class.php&lt;/em&gt; w około 25 KB, w porównaniu do 32 KB z poprzedniej wersji, a na chwilę obecną wpływ jego rozmiaru jest dość dobrze widoczny w wynikach, jako że PHP musi załadować taki parser i go wstępnie skompilować do wewnętrznego bajtkodu. Naturalnie, gdy pozałączamy dużo szablonów, nie będzie to aż takie widoczne, ale mimo wszystko cieszę się z uzyskanego efektu.&lt;/p&gt;


&lt;p&gt;Paczkę można ściągnąć &lt;a href=&quot;http://www.invenzzia.org/download/opt-2.0.0-dev4.tar.gz&quot; hreflang=&quot;pl&quot;&gt;stąd&lt;/a&gt;. Zawiera ona również częściowo ukończoną polską dokumentację.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/OPT-200-dev4#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/OPT-200-dev4#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/17</wfw:commentRss>
      </item>
    
</channel>
</rss>
