<?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>Nowy poradnik OPT</title>
    <link>http://blog.invenzzia.org/pl/post/Nowy-poradnik-OPT</link>
    <guid isPermaLink="false">urn:md5:5fde939b5cedd43834aeddfebe01148d</guid>
    <pubDate>wto, 22 gru 2009 13:30:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Inne</category>
        <category>OPT2</category><category>poradniki</category>    
    <description>    &lt;p&gt;Opublikowałem dzisiaj nowy poradnik do Open Power Template. Pokazuje on, jak używać sekcji oraz formatów danych. Wybrałem ten temat, ponieważ zauważyłem, że niektórzy użytkownicy mają z nim problemy i że dodatkowy artykuł by im pomógł, Przed końcem roku spróbuję napisać jeszcze jeden tekst, tym razem poświęcony pracy z XML-em w OPT. Artykuł jest dostępny na stronie Invenzzii zarówno w polskiej, jak i angielskiej wersji językowej.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Nowy-poradnik-OPT#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Nowy-poradnik-OPT#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/67</wfw:commentRss>
      </item>
    
  <item>
    <title>Open Power Template 2.0-RC1</title>
    <link>http://blog.invenzzia.org/pl/post/Open-Power-Template-2.0-RC1</link>
    <guid isPermaLink="false">urn:md5:fa6d32181a6fb66b0d38b1c8e7c4614c</guid>
    <pubDate>wto, 12 maj 2009 13:17:00 +0200</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>nowe wersje</category><category>OPT2</category>    
    <description>&lt;p&gt;W końcu, po prawie półtorarocznych pracach zbliżamy się do szczęśliwego finału. Od dzisiaj do ściągnięcia jest Open Power Template w wersji 2.0-RC1. Biblioteka wygląda już na kompletną i wystarczająco stabilną do większości zastosowań, wliczając w to środowiska rozwojowe i produkcyjne. Wciąż istnieje szansa, że zostanie odkryty jakiś poważny błąd, ale osobiście nie sądzę, by doszło aż do tego. OPT przez ostatnie 4,5 miesiąca poddawany był szeroko zakrojonym beta-testom i szlifowaniu, zarówno poprzez liczącą już prawie pół tysiąca elementów kolekcję testów, jak i dwie rzeczywiste aplikacje, które zostały przy jego pomocy napisane.&lt;/p&gt;    &lt;h2&gt;Skąd ściągnąć?&lt;/h2&gt;


&lt;p&gt;Oczywiście biblioteka jest dostępna do pobrania z naszej &lt;a href=&quot;http://www.invenzzia.org/en/download&quot; hreflang=&quot;en&quot;&gt;strony WWW&lt;/a&gt;. Oprócz standardowych paczek, po raz pierwszy publikujemy również oficjalne archiwa PHAR. PHAR to skrót od &lt;em&gt;PHP ARchive&lt;/em&gt;, czyli paczek z gotowym do uruchomienia kodem PHP podobnych w działaniu do plików JAR w Javie. Odpowiednie rozszerzenie do ich wykonywania będzie częścią PHP od wersji 5.3.0, a istnieje możliwość jego doinstalowania również do dotychczasowych wersji. Ponieważ okazało się, że nasz dział Download nie bardzo radzi sobie z taką ilością różnorodnych plików, póki co odnośniki zamieszczam tutaj:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://static.invenzzia.org/files/opt-phar-2.0-rc1.tar.bz2&quot; hreflang=&quot;en&quot;&gt;PHAR-y w formacie TAR.BZ2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://static.invenzzia.org/files/opt-phar-2.0-rc1.tar.gz&quot; hreflang=&quot;en&quot;&gt;PHAR-y w formacie TAR.GZ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://static.invenzzia.org/files/opt-phar-2.0-rc1.zip&quot; hreflang=&quot;en&quot;&gt;PHAR-y w formacie ZIP&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Każda paczka zawiera dwa pliki PHAR: dla OPL oraz dla OPT, teksty licencji użytkownika oraz dokument README. Nie ma w niej dokumentacji.&lt;/p&gt;


&lt;h2&gt;Co dalej?&lt;/h2&gt;


&lt;p&gt;&lt;em&gt;Release Candidate&lt;/em&gt; nie oznacza końca rozwoju projektu - została przecież jeszcze choćby wersja stabilna, a w dalszej perspektywie mnóstwo planów do wydania 2.1. Jednak teraz na jakiś czas rozwój OPT zostanie spowolniony, gdyż w kolejce czekają również inne projekty. Musimy w dalszym ciągu rozbudowywać bazę poradników i artykułów, gdyż bez tego właściwie nie ma szans na przyciągnięcie nowych użytkowników. Ponadto na swoją kolej czekają Open Power Classes, Open Power Forms oraz port dla Zend Frameworka.&lt;/p&gt;


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


&lt;p&gt;Na zakończenie pragniemy podziękować wszystkim dotychczasowym użytkownikom biblioteki za wytrwałość, szczególnie tym, którzy aktywnie włączyli się w proces rozwoju. Ta biblioteka powstaje właśnie dla was.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Open-Power-Template-2.0-RC1#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Open-Power-Template-2.0-RC1#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/59</wfw:commentRss>
      </item>
    
  <item>
    <title>Port dla Zend Frameworka jest dostępny!</title>
    <link>http://blog.invenzzia.org/pl/post/Port-dla-Zend-Frameworka-jest-dost%C4%99pny%21</link>
    <guid isPermaLink="false">urn:md5:8b0e3fb8f3c78c82c3c57c7189b9a8d4</guid>
    <pubDate>śro, 25 mar 2009 15:16:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Inne</category>
        <category>framework</category><category>OPL</category><category>OPT2</category><category>releases</category><category>zend framework</category>    
    <description>&lt;p&gt;Przed chwilą wrzuciłem na SVN-a pierwszą wersję portu bibliotek Open Power Libs integrującego je z Zend Frameworkiem. Serdecznie zapraszam wszystkich zainteresowanych do testów oraz nadsyłania uwag i propozycji. Port nie jest jeszcze w pełni gotowy, ale podstawowa funkcjonalność wydaje się działać dobrze i myślę, że niebawem jeszcze jej przybędzie. Szczegóły dotyczące oferowanych (i planowanych) możliwości znaleźć można na angielskim blogu oraz na wiki.&lt;/p&gt;    &lt;h2&gt;Jak go zdobyć?&lt;/h2&gt;


&lt;p&gt;Jeśli posiadasz klienta SVN, możesz go ściągnąć tak samo, jak każdy inny projekt:&lt;/p&gt;

&lt;pre&gt;
svn co http://svn.invenzzia.org/svn/opl4zf/trunk
&lt;/pre&gt;


&lt;p&gt;Przypominam, że kod wymaga do działania posiadania także paczki z Zend Frameworkiem oraz OPL-em.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Port-dla-Zend-Frameworka-jest-dost%C4%99pny%21#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Port-dla-Zend-Frameworka-jest-dost%C4%99pny%21#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/52</wfw:commentRss>
      </item>
    
  <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 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>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>
    
  <item>
    <title>Główna klasa OPT na ukończeniu</title>
    <link>http://blog.invenzzia.org/pl/post/Glowna-klasa-OPT-na-ukonczeniu</link>
    <guid isPermaLink="false">urn:md5:0e31e4a93c4e8d87810340a39dfbbd7a</guid>
    <pubDate>śro, 20 lut 2008 22:12:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>OPT2</category>    
    <description>&lt;p&gt;Owocem dzisiejszych zmagań z kodem źródłowym nowego OPT jest ukończenie pliku &lt;em&gt;opt.class.php&lt;/em&gt;, w którym (jak niektórym wiadomo) mieści się główna klasa parsera. Przyznam, że paradoksalnie plik ten był bardziej wymagający, niż kompilator. W tym drugim przypadku można sobie pozwolić na bardzo dużo, wystarczy pomysł na algorytm i przewidzenie, jak wpłynie on na resztę układu. Z główną klasą sprawa ma się troszeczkę inaczej. Jest ona dołączana za każdym razem, tak więc musi zawierać wszystko, co jest uruchamiane permanentnie. Musi to robić szybko, sprawnie i być nieduża. A tymczasem wymagania co do funkcjonalności rosną.&lt;/p&gt;    &lt;p&gt;Nowa wersja developerska będzie niekompatybilna z poprzednimi pod kątem interfejsu programistycznego. Aby zaimplementować cache tak, jak chciałem, musiałem przebudować niemal całą obsługę systemu wyjścia. W serii 1.x.x pojęcie systemu wyjścia w zasadzie nie istniało. To, czy wynik działania szablonu trafi na ekran, czy do zmiennej, zależało od wyboru odpowiedniej metody. Jakieś skomplikowane przełączenia i sztuczki kierowały wszystko do miejsca docelowego, aczkolwiek nie było w tym konsekwencji i strategia działania była średnio dopracowana. Cóż, tak wychodzi, jak się zaczyna od zachowywania podobieństw do Smarty'ego, a trzeba przypomnieć, że w początkowych, pionierskich czasach, było to jednym z założeń projektu. W OPTv2 istnieje jawnie zdefiniowany interfejs &lt;em&gt;ioptOutput&lt;/em&gt; pozwalający samodzielnie zaprogramować, co trzeba zrobić z wynikiem działania. Właśnie za jego pomocą realizowany będzie system cache, a jak - już tłumaczę.&lt;/p&gt;


&lt;p&gt;Dotąd w kodzie były dwa systemy wyjścia: &lt;em&gt;optNetOutput&lt;/em&gt; wysyłające wszystko na ekran i pilnujące przed dwukrotnym wysłaniem szablonu w trybie XML, oraz &lt;em&gt;optReturnOutput&lt;/em&gt; zwracające przechwycony rezultat. Dodałem do obu możliwość dekorowania ich czym innym i utworzyłem &lt;em&gt;optCachedOutput&lt;/em&gt; koncentrujące się w całości na obsłudze cache. Możliwości pozostaną po staremu, natomiast zmieni się sposób wywoływania i niestety trochę się rozbuduje inicjacja:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;$cache = new optCachedOutput('./cache/'); // to jest cache, tu go konfigurujemy.
$tpl -&amp;gt; register(OPT_OUTPUT, 'my_cache', $cache);
$tpl -&amp;gt; decorate(OPT_OUT_SCREEN, 'my_cache');
$tpl -&amp;gt; decorate(OPT_OUT_RETURN, 'my_cache');

if(!$cache -&amp;gt; isCached('szablon.tpl', 'jakis_id'))
{
  // generuj dane
}

$cache -&amp;gt; setCache(5, 'jakis_id'); // włącz cache na 5 sekund
$tpl -&amp;gt; parse('szablon.tpl', 'my_cache');
&lt;/pre&gt;


&lt;p&gt;Spróbuję jakoś skrócić i uprościć to, co widać na początku, zwłaszcza że mi też się to specjalnie nie podoba. Ponadto muszę sprawdzić, czy dekoracji przypadkiem w niewłaściwą stronę (niezgodnie z logiką i intuicją) pod względem nazewnictwa nie zrobiłem :).&lt;/p&gt;


&lt;p&gt;Obsługa wtyczek nie jest jeszcze w pełni gotowa - ukończyłem jedynie część znajdującą się w &lt;em&gt;opt.class.php&lt;/em&gt;, jako że reszta może spokojnie być z pożytkiem dla wydajności wyekspediowana gdzie indziej. Podobnie, jak w OPT 1.1.3, będzie możliwość ustawienia kilku katalogów z pluginami, lecz parser nie będzie już żądać w nich praw do zapisu. Wrzucane tam były dodatkowe pliki opisujące zawartość katalogu i pozwalające załączyć jego zawartość bez konieczności jego skanowania. Jednak wiadomo, że im więcej include'ów, tym wolniej wszystko działa, a niektórzy potrafią tych wtyczek naprodukować tyle, że mają tam więcej plików, niż liczy sobie cały mój framework :D. Dlatego teraz OPT będzie ze wszystkich pluginów składać jeden mega-plik zawierający wszystko, czego potrzeba nam do szczęścia. Przy okazji będę mieć również nowy algorytm do następcy OPT Toolsetu, który teraz będzie obsługiwać już wszystkie biblioteki Open Power.&lt;/p&gt;


&lt;p&gt;Ostatnia sprawa dotyczy zestawu funkcji dostępnych w szablonach. Stormfly niedawno pisał na swoim blogu, że w OPT 1.1.x był on bezsensownie dobrany i w sumie miał rację. Popatrzyłem, co tam programiście daje Smarty i okazało się, że ma tam on w zanadrzu kilka ciekawych funkcji, które mogą być naprawdę przydatne. Wstępna lista zawiera zatem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;spacify&lt;/em&gt; - pomiędzy każde dwa sąsiednie znaki podanego ciągu wstawiany jest inny ciąg.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;indent&lt;/em&gt; - robi wcięcia w tekście.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;truncate&lt;/em&gt; - obcina tekst do maksymalnie podanej długości (można dodać nierozcinanie słów na pół)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;strip&lt;/em&gt; - redukuje wszystkie grupy białych znaków do pojedynczego znaku.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;capitalize&lt;/em&gt; - odpowiednik ucfirst()&lt;/li&gt;
&lt;li&gt;&lt;em&gt;upper&lt;/em&gt; - odpowiednik strtoupper()&lt;/li&gt;
&lt;li&gt;&lt;em&gt;lower&lt;/em&gt; - odpowiednik strtolower()&lt;/li&gt;
&lt;li&gt;&lt;em&gt;countWords&lt;/em&gt; - odpowiednik str_word_count()&lt;/li&gt;
&lt;li&gt;&lt;em&gt;countChars&lt;/em&gt; - odpowiednik strlen()&lt;/li&gt;
&lt;li&gt;&lt;em&gt;money&lt;/em&gt; - odpowiednik money_format(), lecz ustawienia można zapisać w konfiguracji OPT.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;number&lt;/em&gt; - odpowiednik number_format(), lecz ustawienia można zapisać w konfiguracji OPT.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;wordWrap&lt;/em&gt; - odpowiednik word_wrap()&lt;/li&gt;
&lt;li&gt;&lt;em&gt;replace&lt;/em&gt; - odpowiednik str_replace()&lt;/li&gt;
&lt;li&gt;&lt;em&gt;regexReplace&lt;/em&gt; - odpowiednik preg_replace(), lecz z ostatnim argumentem wysuniętym na początek, aby nie było niekonsekwencji.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;date&lt;/em&gt; - odpowiednik date() :)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;firstof&lt;/em&gt; - zwraca pierwszy niepusty element z podanych.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;nl2br&lt;/em&gt; - odpowiednik nl2br() :)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;array&lt;/em&gt; - tworzenie tablic po stronie szablonów.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;build&lt;/em&gt; - to, co w poprzednim OPT się nazywało apply(), ale jeszcze nie wiem, czy ostatecznie zostanie właśnie taka nazwa.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;W zestawie tym nie ma żadnych funkcji do escape'owania, ponieważ kompilator w wielu miejscach sam o to dba, a jeśli nie, będzie możliwość ręcznego zaznaczenia tego, aczkolwiek nie poprzez funkcję. W każdym razie chodzi o to, by kompilator wiedział, że coś jest escape'owane i z rozpędu sam czegoś od siebie nie dołożył, gdyż to równałoby się kaszanie na ekranie.&lt;/p&gt;


&lt;p&gt;Naprodukowałem całkiem sporo funkcjonalności, lecz koniec końców nie zdążyłem wszystkiego przetestować, tak więc nie mam pewności, czy cały ten kod w ogóle działa, jak należy, aczkolwiek jakichś specjalnych rewelacji się nie spodziewam. W końcu np. algorytmy cache'ujące zasadą działania nie różnią się specjalnie od tego, co było w poprzednich wersjach. Kolejny dev ukaże się już za parę dni.&lt;/p&gt;


&lt;p&gt;Na koniec mała statystyka:&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;- &lt;em&gt;opt.class.php&lt;/em&gt; - 24 KB i więcej już nie urośnie. W poprzedniej wersji plik ten był o całe 8 KB cięższy, a w sumie oferował mniej.&lt;br /&gt;
- &lt;em&gt;opt.compiler.php&lt;/em&gt; - 65 KB i wciąż rośnie.&lt;br /&gt;
- &lt;em&gt;opt.instructions.php&lt;/em&gt; - 25 KB i wciąż rośnie.&lt;/p&gt;&lt;/blockquote&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Glowna-klasa-OPT-na-ukonczeniu#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Glowna-klasa-OPT-na-ukonczeniu#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/13</wfw:commentRss>
      </item>
    
  <item>
    <title>OPT 2.0.0-dev3</title>
    <link>http://blog.invenzzia.org/pl/post/OPT-200-dev3</link>
    <guid isPermaLink="false">urn:md5:40f330500ef782c5627da5ebdf0d61ca</guid>
    <pubDate>pią, 15 lut 2008 13:26:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>OPT2</category>    
    <description>&lt;p&gt;Zgodnie z zapowiedzią częstszego publikowania postępów prac, udostępniamy dziś trzecią wersję developerską nowego Open Power Template'a, nad którą pracowałem przez ostatni tydzień. Tym razem poświęciłem sporo uwagi przetwarzaniu atrybutów OPT, które robią różne ciekawe rzeczy ze znacznikami, do których zostały dodane. Wstępna implementacja już była - nawet przykłady dotyczące &quot;opt:section&quot; znajdowały się już w paczce. Jednak aby w pełni spełniała oczekiwania, trzeba było rozbudować cały kod.&lt;/p&gt;    &lt;p&gt;Zamieszczam parę przykładów pokazujących, co ciekawego można już zrobić. Zacznijmy od czegoś prostego. W OPT do osadzania wyrażeń w treści służą nawiasy klamrowe, w których umieszczamy wyrażenie, np.&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;html&quot;&gt;tekst tekst tekst {$blok} tekst tekst tekst
&lt;/pre&gt;


&lt;p&gt;Istnieje także instrukcja opt:put, która na pierwszy rzut oka wykonuje dokładnie to samo:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;html&quot;&gt;tekst tekst tekst &amp;lt;opt:put value=&amp;quot;$blok&amp;quot;/&amp;gt; tekst tekst tekst
&lt;/pre&gt;


&lt;p&gt;Jednak dzięki temu, że to jest instrukcja, a nie nawiasy klamrowe, można z nią zrobić parę fajnych rzeczy przy pomocy atrybutów. Przypuśćmy, że chcemy uzyskać coś w stylu &quot;Wartość 1 / Wartość 2 / Wartość 3&quot;. Wystarczy nam do tego instrukcja opt:put, sekcja i separator:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;html&quot;&gt;&amp;lt;p&amp;gt;&amp;lt;opt:put value=&amp;quot;$sekcja.wartosc&amp;quot; opt:section=&amp;quot;sekcja&amp;quot; str:separator=&amp;quot; / &amp;quot;/&amp;gt;&amp;lt;/p&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Jak widać, taka sekcja obejmuje także znacznik, do którego została doklejona i możemy umieszczać wartości elementów w pozostałych atrybutach. Separator domyślnie akceptuje wyrażenia, lecz gdy nie mamy ochoty na pisanie &lt;em&gt;separator=&quot;'cośtam'&quot;&lt;/em&gt; (cudzysłów, a później apostrof), zmieniamy po prostu przestrzeń nazw na &quot;str&quot;.&lt;/p&gt;


&lt;p&gt;Ukończyłem również implementację odwróconych apostrof, które w stosunku do poprzedniej wersji zmieniają swoje działanie. Tym razem programista może samodzielnie zaprogramować ich obsługę, pisząc zwykłą funkcję i przekazując jej nazwę do parsera. Można to wykorzystać np. do eleganckiej implementacji systemu językowego a'la gettext:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;html&quot;&gt;&amp;lt;p&amp;gt;{`Parę przydatnych informacji...`}&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;{`Autor:`} {$autor}&amp;lt;/p&amp;gt;
&lt;/pre&gt;


&lt;p&gt;W końcu ostatnia ze zmian. Skoro mamy parser XML, potrzebujemy paru instrukcji, które umożliwią twórcy szablonów bezpośrednie manipulowanie drzewem, np. dodanie atrybutu o zmiennej nazwie. OPT będzie zawierać dwie instrukcje do tego celu: &lt;em&gt;opt:tag&lt;/em&gt; oraz &lt;em&gt;opt:attribute&lt;/em&gt;. Ta druga została dodana do najnowszej wersji developerskiej. Możemy jej użyć, aby móc wczytać nazwę atrybutu z bloku:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;html&quot;&gt;&amp;lt;div&amp;gt;
  &amp;lt;opt:attribute name=&amp;quot;$nazwa&amp;quot; value=&amp;quot;$wartosc&amp;quot;/&amp;gt;
  Treść...
&amp;lt;/div&amp;gt;
&lt;/pre&gt;


&lt;p&gt;To nie koniec - w połączeniu z sekcją uzyskujemy szybkie narzędzie do masowego dodawania atrybutów:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;html&quot;&gt;&amp;lt;div&amp;gt;
  &amp;lt;opt:attribute name=&amp;quot;$atrybut.nazwa&amp;quot; value=&amp;quot;$atrybut.wartosc&amp;quot; opt:section=&amp;quot;atrybut&amp;quot;/&amp;gt;
  treść...
&amp;lt;/div&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Jeśli do takiej sekcji wyślemy tablicę: &lt;code&gt;array(0 =&amp;gt; array('nazwa' =&amp;gt; 'class', 'wartosc' =&amp;gt; 'dude'), array('nazwa' =&amp;gt; 'id', 'wartosc' =&amp;gt; 'lol'))&lt;/code&gt;, uzyskamy:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;html&quot;&gt;&amp;lt;div class=&amp;quot;dude&amp;quot; id=&amp;quot;lol&amp;quot;&amp;gt;
  treść...
&amp;lt;/div&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Dość dużo czasu poświęciłem na rozwój dokumentacji. Wprawdzie dalej jest ona nieco z tyłu za kodem, ale powoli zaczyna go doganiać. Na ukończeniu jest opis sekcji, pojawiły się omówienia metod chronionych w &lt;em&gt;optClass&lt;/em&gt;, a nawet zalążki opisu kompilatora. Muszę też porządkować już istniejący kod, aby pasował do aktualnego stanu kodu oraz moich zamierzeń. Zachęcam do testowania i nadsyłania swych uwag.&lt;/p&gt;


&lt;p&gt;Download: &lt;a href=&quot;http://blog.invenzzia.org/pl/post/&quot; hreflang=&quot;pl&quot;&gt;http://www.invenzzia.org/download/opt-2.0.0-dev3.tar.gz&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/OPT-200-dev3#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/OPT-200-dev3#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/12</wfw:commentRss>
      </item>
    
  <item>
    <title>Nowy dev</title>
    <link>http://blog.invenzzia.org/pl/post/Nowy-dev</link>
    <guid isPermaLink="false">urn:md5:c99861121699affab67843d24771ede7</guid>
    <pubDate>sob, 09 lut 2008 10:52:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>OPT2</category>    
    <description>&lt;p&gt;Dodałem do strony dział &quot;Download&quot;, przy okazji umieszczając w nim nową wersję rozwojową Open Power Template'a. Znalazł się tam również nieduży skrypcik &quot;docgen&quot;, którego używamy do uruchamiania automatycznego parsowania dokumentacji w DocBooku. Nowe wersje rozwojowe będą teraz już publikowane znacznie częściej; w okresie dużego nasilenia prac być może nawet co dwa, trzy dni. Powód, dla którego nie były one dotąd tak częste, był brak automatyzacji, a przygotowanie takiej paczki pochłania trochę czasu (dla przykładu, umieszczenie nowej wersji OPT w Internecie zajmuje kilka godzin).&lt;/p&gt;    &lt;p&gt;W kolejnym devie znajduje się wszystko, co zaimplementowałem w przeciągu ostatniego miesiąca:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Niemal ukończone sekcje.&lt;/li&gt;
&lt;li&gt;Separatory.&lt;/li&gt;
&lt;li&gt;Pętle &quot;for&quot; i &quot;foreach&quot;.&lt;/li&gt;
&lt;li&gt;W większości ukończone dziedziczenie szablonów.&lt;/li&gt;
&lt;li&gt;Zarządzanie nagłówkami HTTP.&lt;/li&gt;
&lt;li&gt;Częściowo ukończone parsowanie prologu.&lt;/li&gt;
&lt;li&gt;Trochę poprawek w kompilatorze.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;W katalogu &quot;dev&quot; można znaleźć skrypty, za pomocą których testuję poprawność działania poszczególnych instrukcji. Są też unitTesty: gotowy zestaw do testów parsera wyrażeń oraz częściowo ukończony test API. Próbuję także opracować automatyczny tester poprawności działania samych instrukcji, żeby nie bawić się w ręczne wywoływanie. Problemy stwarzają nowe linie i białe znaki w kodzie wynikowym, które wprowadzają straszny zamęt w przypadku porównywania rezultatu z wzorcówką, przez co przygotowanie jednego głupiego testu zabiera dużo czasu. Jednak coś się wymyśli. Do działania wymagana jest instalacja pakietu phpUnit 3 z repozytorium PEAR.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Nowy-dev#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Nowy-dev#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/9</wfw:commentRss>
      </item>
    
  <item>
    <title>Dziedziczenie szablonów</title>
    <link>http://blog.invenzzia.org/pl/post/Dziedziczenie-szablonow</link>
    <guid isPermaLink="false">urn:md5:11eedc715a12fa05aa1c92aaf21f291d</guid>
    <pubDate>sob, 02 lut 2008 12:14:00 +0100</pubDate>
    <dc:creator>Zyx</dc:creator>
        <category>Open Power Template</category>
        <category>OPT2</category>    
    <description>&lt;p&gt;Przeważnie kod wynikowy strony komponuje się z kilku mniejszych szablonów zawierających fragmenty kodu. Istnieje wiele technik ich łączenia. W parserach dla PHP królują jak dotąd dwa rodzaje: ręczne uruchamianie szablonów we właściwej kolejności z poziomu kodu PHP oraz dyrektywa &lt;em&gt;include&lt;/em&gt;. Podobnie było także w poprzedniej wersji OPT, jednak w nowym wydaniu pierwszy ze sposób właściwie idzie do kasacji - o ile nie korzystamy z quirks mode, parser nie dopuści do tego, by wywołać metodę &lt;em&gt;parse()&lt;/em&gt; dwukrotnie. Początkowo miałem zamiar zrekompensować to, rozbudowując &lt;em&gt;include&lt;/em&gt; o tzw. sekwencje, lecz dnia pewnego na moim blogu Coldpeer zapytał się mnie, czy będzie dziedziczenie szablonów. Poszukałem, popatrzyłem i stwierdziłem, że to może być niezłe. Tak zaczęły się eksperymenty z implementacją.&lt;/p&gt;    &lt;p&gt;Dziedziczenie szablonów pojawiło się, z tego co wiem, w systemie szablonów pythonowego frameworka Django. Idea jest wzięta z programowania obiektowego, gdzie można dziedziczyć klasy, dodając do nich nowe metody, pola oraz nadpisując istniejące. Tutaj jest podobnie. Mamy szablon główny, w którym zaznaczamy pewne charakterystyczne miejsca i wypełniamy je standardową zawartością. Drugi szablon dziedziczy po głównym i może nadpisać wybrane miejsca własną treścią. Po nim może iść kolejny szablon i tak dalej.&lt;/p&gt;


&lt;p&gt;Okazało się, że spora część niezbędnej funkcjonalności była już w OPT 1.x - instrukcje &lt;em&gt;bind&lt;/em&gt; oraz &lt;em&gt;insert&lt;/em&gt; pozwalały przenosić całe fragmenty kodu w inne miejsce, także pomiędzy szablonami. Niestety, nie było tam odpowiedniego mechanizmu detekcji, czy zaszły jakieś modyfikacje w plikach i to trochę psuło całą koncepcję. Tak samo jego opracowanie dla nowej wersji było najtrudniejszym zadaniem, ponieważ nie wystarczy teraz jedynie sprawdzić, czy zaszły zmiany w szablonie, który wywołujemy, ale także czy coś nowego nie pojawiło się w szablonach bazowych! Z zamiarem definitywnego rozwiązania tego problemu siadłem do kodu wczoraj i parę godzin temu wszystko zadziałało tak, jak powinno:&lt;/p&gt;


&lt;p&gt;Szablon bazowy (&lt;em&gt;test_inherited_a.tpl&lt;/em&gt;):&lt;/p&gt;
&lt;pre name=&quot;code&quot; class=&quot;html&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;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;
	   &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;

&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot; lang=&amp;quot;en_US&amp;quot; xml:lang=&amp;quot;en_US&amp;quot;&amp;gt;
 &amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Instruction test: snippet and insert&amp;lt;/title&amp;gt;
 &amp;lt;/head&amp;gt;
 &amp;lt;body&amp;gt;
  &amp;lt;opt:insert snippet=&amp;quot;header&amp;quot;&amp;gt;
   &amp;lt;h1&amp;gt;I'm a standard header&amp;lt;/h1&amp;gt;
   &amp;lt;p&amp;gt;Foo bar joe&amp;lt;/p&amp;gt;  
  &amp;lt;/opt:insert&amp;gt;
  
  &amp;lt;hr/&amp;gt;
  
  &amp;lt;opt:insert snippet=&amp;quot;content&amp;quot;&amp;gt;
  	&amp;lt;p&amp;gt;Well, i'm also a standard content.&amp;lt;/p&amp;gt;
  
  &amp;lt;/opt:insert&amp;gt;
  
  &amp;lt;hr/&amp;gt;
  
  &amp;lt;opt:insert snippet=&amp;quot;footer&amp;quot;&amp;gt;
  	&amp;lt;p&amp;gt;And I'm a footer.&amp;lt;/p&amp;gt;  
  &amp;lt;/opt:insert&amp;gt;
  
  &amp;lt;p&amp;gt;&amp;amp;copy; Pasteright 2008 by LMAO, It seems to work!&amp;lt;/p&amp;gt;
 &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Szablon dziedziczący po nim (&lt;em&gt;test_inherit_1.tpl&lt;/em&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;/opt:snippet&amp;gt;

	&amp;lt;opt:snippet name=&amp;quot;content&amp;quot;&amp;gt;
		&amp;lt;p&amp;gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus ut tellus id nulla adipiscing eleifend. Sed dictum accumsan ante. Nullam at nisl vitae elit aliquet fringilla. Praesent egestas eros eget tellus. Praesent id odio a sapien rhoncus vehicula. Nunc fringilla, diam eget euismod tempor, tortor metus tincidunt sapien, eu cursus magna tellus at risus. Praesent non tellus eget magna facilisis pulvinar. Praesent libero mi, adipiscing a, pharetra eget, condimentum sodales, mi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Donec ac elit. Duis iaculis tortor a metus. Aliquam id purus et eros faucibus fringilla. Praesent quis quam. In lectus urna, fringilla sit amet, iaculis eget, aliquet ac, quam. Donec vulputate dui sit amet lectus. Aenean tempor, orci at pretium ornare, tortor tortor venenatis ligula, eget blandit nisi risus eget dolor. Duis nunc neque, sodales porta, viverra non, tristique eu, sem. Curabitur magna neque, blandit ullamcorper, congue quis, tristique ut, felis.&amp;lt;/p&amp;gt;
	&amp;lt;/opt:snippet&amp;gt;

	&amp;lt;opt:snippet name=&amp;quot;footer&amp;quot;&amp;gt;
		&amp;lt;p&amp;gt;Bye!!!&amp;lt;/p&amp;gt;
	&amp;lt;/opt:snippet&amp;gt;
&amp;lt;/opt:extend&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Do tego kod PHP:&lt;/p&gt;

&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;&amp;lt;?php

	define('OPT_DIR', '../lib/');
	require(OPT_DIR.'opt.class.php');

	try
	{
		$tpl = new optClass;
		$tpl -&amp;gt; sourceDir = './templates/';
		$tpl -&amp;gt; compileDir = './templates_c/';
		$tpl -&amp;gt; stripWhitespaces = false;
		$tpl -&amp;gt; printComments = false;
		$tpl -&amp;gt; setup();
		
		$tpl -&amp;gt; parse('test_inherit_1.tpl');
	}
	catch(optException $e)
	{
		optErrorHandler($e);
	}
?&amp;gt;
&lt;/pre&gt;


&lt;p&gt;A rezultat widać poniżej:&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://blog.invenzzia.org/public/images/template_inheritance.png&quot;&gt;&lt;img src=&quot;http://blog.invenzzia.org/public/images/.template_inheritance_m.jpg&quot; alt=&quot;Template inheritance&quot; style=&quot;display:block; margin:0 auto;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Parę faktów:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Jeżeli zmodyfikujemy dowolny z szablonów, po którym nasz szablon dziedziczy, OPT wykona rekompilację i zmiana zostanie natychmiast uwzględniona.&lt;/li&gt;
&lt;li&gt;Jeżeli usuniemy dowolną z instrukcji &quot;opt:snippet&quot;, wyświetli nam się domyślna zawartość zdefiniowana wewnątrz &quot;opt:insert&quot;.&lt;/li&gt;
&lt;li&gt;Istnieje możliwość nadpisania już zdefiniowanego snippeta przez leżący wyżej w hierarchii szablon. Będę implementował mechanizm odwołania się do zawartości rodzica (jakaś instrukcja &quot;opt:parent&quot;).&lt;/li&gt;
&lt;li&gt;Można to mieszać z &quot;opt:include&quot; oraz &quot;opt:sequence&quot; (mechanizm sekwencji).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ponadto bardzo możliwe, że dziedziczenie szablonów w ostatecznym rozrachunku może działać szybciej, niż tradycyjna metoda, aczkolwiek kosztem miejsca na dysku. Po prostu jak mamy dziedziczenie &quot;A po  B po C&quot;, wywołując szablon A, caluteńki kod wynikowy ze wszystkich szablonów jest zrzucany właśnie do A. Zmniejsza to ilość odwołań do dysku, gdyż uruchomienie jednego wielkiego szablonu jest mniej kosztowne, niż tej samej treści rozbitej na 3 mniejsze pliki. Z drugiej strony, w podstawowym trybie OPT wciąż sprawdza czasy modyfikacji (tyle że robi mniej testów). Póki co są to jedynie przypuszczenia. Dopiero po skończeniu i zrobieniu porządnego benchmarku będę w stanie podać konkretne liczby. Chociaż dodam, że z ciekawości puściłem sobie prosty test (lista 15 elementów):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;OPT 1.x: 1850 req/s&lt;/li&gt;
&lt;li&gt;OPT 2.0: 2100 req/s&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nie są to wyniki ostateczne - trzeba wziąć pod uwagę, że nowy plik &lt;em&gt;opt.class.php&lt;/em&gt; wciąż nie ma sporej części opcji, które trochę zwiększą jego objętość, a ponadto nie zaimplementowałem jeszcze niektórych optymalizacji. Tak więc można się spodziewać, że nowe możliwości nie odbiją się niekorzystnie na wydajności, a nawet jest szansa na coś odwrotnego - nowa wersja będzie szybsza.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.invenzzia.org/pl/post/Dziedziczenie-szablonow#comment-form</comments>
      <wfw:comment>http://blog.invenzzia.org/pl/post/Dziedziczenie-szablonow#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.invenzzia.org/pl/feed/atom/comments/5</wfw:commentRss>
      </item>
    
</channel>
</rss>
