<?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 - opt2</title>
  <link>http://blog.invenzzia.org/pl/</link>
  <atom:link href="http://blog.invenzzia.org/pl/feed/tag/opt2/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>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 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>
    
</channel>
</rss>
