<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Jaros&#322;aw Zabie&#322;&#322;o - BLOG: Tag mvc</title>
    <link>http://blog.zabiello.com/articles/tag/mvc</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <item>
      <title>Szablony i wzorzec MVC - cz. III</title>
      <description>&lt;p&gt;W &lt;a href="http://blog.zabiello.com/articles/2007/01/06/templates-and-mvc-2"&gt;poprzedniej cz&#281;&#347;ci&lt;/a&gt; om&#243;wiono szablony dedykowane g&#322;&#243;wnie do wsp&#243;&#322;pracy z designerami boj&#261;cymi si&#281; programowa&#263;. By&#322;y to albo szablony wk&#322;adaj&#261;ce swoj&#261; logik&#281; do znacznik&#243;w &lt;span class="caps"&gt;XML&lt;/span&gt;/XHTML (ZPT, SimpleTAL, Kid, Genshi, MasterView, &lt;span class="caps"&gt;PHP TAL&lt;/span&gt;), albo szablony posiadaj&#261;ce sw&#243;j w&#322;asny, specjalizowany j&#281;zyk (Smarty, Django, Jinja, Liquid). W za&#322;o&#380;eniu taki j&#281;zyk mia&#322; by&#263; prostym substytutem j&#281;zyka u&#380;ywanego w warstwie kontrolera. Szablony tego typu mo&#380;e s&#261; wygodne dla designera, ale na pewno nie dla programisty, kt&#243;ry musi je &lt;strong&gt;przygotowa&#263;&lt;/strong&gt;. Po pierwsze, trzeba si&#281; uczy&#263; kolejnego j&#281;zyka&amp;#8230; szablon&#243;w. Po drugie, wszystkie tego typu j&#281;zyki s&#261; ograniczaj&#261;ce dla programisty. Mimo &#380;e pozornie prostsze, w praktyce s&#261; bardziej z&#322;o&#380;one i to nawet dla designera. Np. szablony Django i Jinja nie posiadaj&#261; &#380;adnej sk&#322;adni na okre&#347;lenie trywialnego warunku wi&#281;kszo&#347;ci, mniejszo&#347;ci:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_django "&gt;{{ x }} jest 
{% if x &amp;gt; y %} 
    wi&#281;ksze 
{% else %} 
    mniejsze 
{% endif %} 
od {{ y }}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Powoduje to mas&#281; k&#322;opot&#243;w dla programisty&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;. Prymitywna sk&#322;adnia szablonu wymusza wi&#281;c kup&#281; dodatkowej pracy. O ile&#380; pro&#347;ciej jest u&#380;y&#263; po prostu pe&#322;nej sk&#322;adni j&#281;zyka tak jak to robi&#261; szablony Cheetah:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_cheetah "&gt;$x jest 
# if x &amp;gt; y 
    wi&#281;ksze 
# else 
    mniejsze 
# endif  
od $y&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Dochodzimy tu wi&#281;c do sytuacji kiedy by&#347;my chcieli co&#347; bardziej elastycznego &amp;#8211; pe&#322;nego dost&#281;pu do j&#281;zyka programowania. Taka sytuacja jest po&#380;&#261;dana wtedy kiedy i tak szablony buduj&#261; programi&#347;ci na podstawie dostarczonego czystego kodu &lt;span class="caps"&gt;HTML&lt;/span&gt; od designer&#243;w.&lt;/p&gt;


	&lt;h2&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;J&#281;zyk &lt;span class="caps"&gt;PHP&lt;/span&gt; jest dosy&#263; specyficzny, bo w istocie jest to j&#281;zyk szablon&#243;w. Tzn. pierwotnie tak zosta&#322; stworzony, ale z czasem si&#281; skomplikowa&#322; &#380;e dost&#261;pi&#322; miana j&#281;zyka skryptowego. Ale jego korzenie wida&#263; w sk&#322;adni, kt&#243;ra z definicji jest zagnie&#380;d&#380;aniem instrukcji &lt;span class="caps"&gt;PHP&lt;/span&gt; wewn&#261;trz kodu &lt;span class="caps"&gt;HTML&lt;/span&gt;. Id&#261;c tym tropem, niekt&#243;rzy pomy&#347;leli, &#380;e nie ma sensu wymy&#347;la&#263; dodatkow&#261; sk&#322;adni&#281;. Wystarczy u&#380;y&#263; &lt;span class="caps"&gt;PHP&lt;/span&gt; w odpowiedni spos&#243;b. I tak powsta&#322;y szablony &lt;a href="http://phpsavant.com/yawiki/"&gt;&lt;strong&gt;Savant&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;W&#322;a&#347;ciwie to Savant nie powinny nazywa&#263; si&#281; szablonami, bo to nic innego jak &lt;span class="caps"&gt;PHP&lt;/span&gt; u&#380;yty w taki spos&#243;b, aby rozdzieli&#263; warstw&#281; prezentacji, od wartwy logiki biznesowej. A skoro to &lt;span class="caps"&gt;PHP&lt;/span&gt;, to odpada nauka dodatkowej sk&#322;adni oraz potrzeby kompilacji specjalizowanego j&#281;zyka szablon&#243;w do ko&#324;cowego kodu &lt;span class="caps"&gt;PHP&lt;/span&gt; (jak to ma miejsce w szablonach &lt;a href="http://smarty.php.net"&gt;Smarty&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;Czy takie podej&#347;cie jest lepsze, czy gorsze, to ju&#380; ka&#380;dy mo&#380;e sobie oceni&#263;. Moim zdaniem &lt;span class="caps"&gt;PHP&lt;/span&gt; ma na tyle m&#281;tn&#261; sk&#322;adni&#281;, &#380;e warstwa prezentacji u&#380;ywaj&#261;ca Smarty&lt;sup&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt; jest bardziej czytelna ni&#380; czysty &lt;span class="caps"&gt;PHP&lt;/span&gt; jaki u&#380;ywaj&#261; Savant.&lt;/p&gt;


	&lt;h2&gt;Ruby&lt;/h2&gt;


	&lt;p&gt;Kiedy m&#243;wimy o Ruby w kontek&#347;cie stron internetowych to najcz&#281;&#347;ciej mamy na my&#347;li jego najs&#322;ynniejszy framework &amp;#8211; &lt;a href="http://rubyonrails.org"&gt;Rails&lt;/a&gt;. Ruby sam w sobie nie jest zwi&#261;zany z &lt;span class="caps"&gt;HTML&lt;/span&gt; tak jak &lt;span class="caps"&gt;PHP&lt;/span&gt;. Rails do szablon&#243;w u&#380;ywa biblioteki &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/"&gt;&lt;strong&gt;ERb&lt;/strong&gt;&lt;/a&gt; (ang. &amp;#8220;embed Ruby&amp;#8221;,  czyli &amp;#8220;zagnie&#380;d&#380;ony Ruby&amp;#8221;) Sk&#322;adnia jest bardzo podobna do &lt;span class="caps"&gt;PHP&lt;/span&gt;, &lt;a href="http://java.sun.com/products/jsp/"&gt;&lt;span class="caps"&gt;JSP&lt;/span&gt;&lt;/a&gt; czy &lt;span class="caps"&gt;ASP&lt;/span&gt;. Ruby jest tu j&#281;zykiem zagnie&#380;d&#380;onym w &lt;span class="caps"&gt;HTML&lt;/span&gt;.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="punct"&gt;&amp;lt;%=&lt;/span&gt;&lt;span class="string"&gt; x %&amp;gt; jest 
&amp;lt;% if x &amp;gt; y %&amp;gt; 
    wi&#281;ksze 
&amp;lt;% else %&amp;gt;
    mniejsze 
&amp;lt;% end %&amp;gt;
od &amp;lt;%&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt; &lt;span class="punct"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h2&gt;Python&lt;/h2&gt;


	&lt;p&gt;Je&#347;li chodzi o Pythona to istnieje &lt;a href="http://wiki.python.org/moin/Templating"&gt;ca&#322;a masa system&#243;w szablonowych&lt;/a&gt;. Ogranicz&#281; si&#281; do paru, tych bardziej interesuj&#261;cych.&lt;/p&gt;


	&lt;h3&gt;Spyce&lt;/h3&gt;


	&lt;p&gt;Szablony &lt;a href="http://spyce.sourceforge.net/"&gt;Spyce&lt;/a&gt; zosta&#322;o stworzone jako pythonowa konkurencja dla &lt;span class="caps"&gt;PHP&lt;/span&gt;. Podobnie potrafi&#261; przeplata&#263; j&#281;zyk (tu: Pythona) z tagami &lt;span class="caps"&gt;HTML&lt;/span&gt;. Najbardziej oczywista przewaga Spyce wynika z faktu u&#380;ywania j&#281;zyka &lt;a href="http://python.org"&gt;Python&lt;/a&gt;, kt&#243;ry jest znacznie lepiej zaprojektowany i posiada du&#380;o wi&#281;cej mo&#380;liwo&#347;ci ni&#380; &lt;span class="caps"&gt;PHP&lt;/span&gt;. Spyce potrafii budowa&#263; w&#322;asne znaczniki (custom tags, podobnie jak to potrafi&#261; javowe &lt;span class="caps"&gt;JSP&lt;/span&gt;) oraz &#322;atwiej w nich zbudowa&#263; komponenty, kod  do wielokrotnego u&#380;ytku.&lt;/p&gt;


	&lt;h3&gt;Myghty&lt;/h3&gt;


	&lt;p&gt;Szablony &lt;a href="http://myghty.org"&gt;Myghty&lt;/a&gt; powsta&#322;y pierwotnie jako pythonowa implementacja systemu komponentowego &lt;a href="http://masonhq.com"&gt;Mason&lt;/a&gt; dla &lt;a href="http://www.perl.org/"&gt;Perla&lt;/a&gt;. Mimo wielu podobie&#324;stw, Myghty s&#261; znacznie pot&#281;&#380;niejsze o Masona, np. intensywnie wykorzystuj&#261; &lt;strong&gt;obiektowo&#347;&#263;&lt;/strong&gt; Pythona (zobacz &lt;a href="http://www.myghty.org/docs/technical.myt#technical_differences"&gt;r&#243;&#380;nice&lt;/a&gt;). Od pocz&#261;tku Myghty powsta&#322;o z my&#347;l&#261; o du&#380;ych obci&#261;&#380;eniach, ci&#281;&#380;kich, profesjonalnych zastosowaniach. Maj&#261; doskona&#322;y w&#322;asny cache, s&#261; bardzo szybkie, odporne na w&#261;tki, &#347;wietnie si&#281; nadaj&#261; do tworzenia komponent&#243;w.&lt;/p&gt;


	&lt;p&gt;Programi&#347;ci Pythona bardzo ceni&#261; sobie filozofi&#281; tego j&#281;zyka (kt&#243;ra podkre&#347;la prostot&#281;, oczywisto&#347;&#263; i elegancj&#281; sk&#322;adni).  Problem w tym, &#380;e Myghty dla pythonowc&#243;w jest zbyt podobne do Perla. S&#261; za ma&#322;o &amp;#8220;pythonic&amp;#8221; &amp;#8211; pythonowe. Dodatkowo, poprzez podkre&#347;lanie swojej komponentowo&#347;ci, Myghty niekt&#243;rym zbyt kojarzy si&#281; z filozofi&#261; komponentow&#261; frameworku &lt;span class="caps"&gt;ASP&lt;/span&gt;.NET (a wzorzec &lt;span class="caps"&gt;MVC&lt;/span&gt; wydaje si&#281; by&#263; bardziej przejrzysty ni&#380; wzorzec sterowanych zdarzeniami komponent&#243;w).  Myghty, jako system komponentowy, mo&#380;e by&#263; u&#380;ywane w stylu &lt;span class="caps"&gt;MVC&lt;/span&gt;, ale nie jest to takie naturalne i oczywiste. (Na szcz&#281;&#347;cie, wszystko zmieni&#322; &lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt; kt&#243;ry zapewnia przejrzyst&#261; prac&#281; zgodn&#261; z wzorcem &lt;span class="caps"&gt;MVC&lt;/span&gt; i Myghty s&#261; tam zredukowane tylko do obs&#322;ugi szablon&#243;w szablon&#243;w. Sterowaniem zajmuj&#261; si&#281; kontrolery Pylonsa a nie Myghty).&lt;/p&gt;


	&lt;h3&gt;Cheetah&lt;/h3&gt;


	&lt;p&gt;Szablony &lt;a href="http://cheetahtemplate.org"&gt;Cheetah&lt;/a&gt; posiadaj&#261; jedn&#261; z najbardziej czytelnych i eleganckich sk&#322;adni. Autorzy wzorowali si&#281; troch&#281; na javowych Velocity i Webmacro. Tym, kt&#243;rzy ceni&#261; sobie czysto&#347;&#263; Pythona z prostot&#261; sk&#322;adni szablon&#243;w z pewno&#347;ci&#261; Cheetah mog&#261; przypa&#347;&#263; do gustu. Przez d&#322;u&#380;szy czas by&#322;y moimi ulubionymi szablonami i do te pory lubi&#281; ich klarowno&#347;&#263;. Cheetah posiadaj&#261; eleganck&#261; sk&#322;adni&#281; obiektowego budowania szablon&#243;w potomnych na bazie ju&#380; istniej&#261;cych. Myghty te&#380; to potrafi, ale Cheetah to ma bardzo czytelnie zrobione. Cheetah s&#261; r&#243;wnie&#380; bardzo szybkie.&lt;/p&gt;


	&lt;h3&gt;Mako&lt;/h3&gt;


	&lt;p&gt;&lt;a href="http://makotemplates.org"&gt;Mako&lt;/a&gt; to najm&#322;odsze dziecko stworzone przez programist&#243;w &lt;a href="http://pylonshq.com"&gt;Pylons&#243;w&lt;/a&gt;. Powsta&#322;y na bazie do&#347;wiadcze&#324; i najlepszych cech szablon&#243;w Myghty, Cheetah, Django/Jinja czy Smarty. Najwi&#281;ksz&#261; ich zalet&#261; jest &lt;strong&gt;ogromna szybko&#347;&#263; i pythonowa filozofia pracy&lt;/strong&gt;. Programi&#347;ci Pythona mog&#261; zauwa&#380;y&#263;, &#380;e sk&#322;adnia Mako jest bardzo bliska sposobowi pracy w samym j&#281;zyku Python. Mako posiadaj&#261; wielk&#261; &#322;atwo&#347;&#263; tworzenia komponent&#243;w, ale w spos&#243;b bardzo podobny do tego jak Python wykorzystuje swoje modu&#322;y. Szablony mo&#380;na tak&#380;e rozszerza&#263; na drodze obiektowego dziedziczenia. Dziedziczenie szablon&#243;w mo&#380;e by&#263; okre&#347;lane w spos&#243;b dynamiczny (tego ju&#380; nie potrafi&#261; np. Cheetah). Dowolny fragment szablonu mo&#380;na r&#243;wnie&#380; zamieni&#263; na komponent z w&#322;asnym cache. Mako posiadaj&#261; tak&#380;e sk&#322;adni&#281; modyfikator&#243;w, kt&#243;re spopularyzowane zosta&#322;y przez Smarty. Dzia&#322;aj&#261; one jak uniksowe pipes (${zmienna|filter}.&lt;/p&gt;


	&lt;p&gt;Mako automatycznie kompiluj&#261; sw&#243;j kod do modu&#322;&#243;w Pythona. Mo&#380;na je wi&#281;c debugowa&#263; tak jak zwyk&#322;y kod Pythona (Cheeatah wymaga r&#281;cznej kompilacji). Mo&#380;na je bez problemu u&#380;ywa&#263; jako niezale&#380;n&#261; bibliotek&#281;. Nie s&#261; one zale&#380;ne od jakiegokolwiek frameworku. Mo&#380;na je zintegrowa&#263; z dowolnym frameworkiem u&#380;ywaj&#261;cym standardu&lt;sup&gt;&lt;a href="#fn3"&gt;3&lt;/a&gt;&lt;/sup&gt; &lt;span class="caps"&gt;WSGI&lt;/span&gt;. U&#380;ytkownicy frameworka &lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt; prawie nic nie musz&#261; robi&#263;, bo Mako s&#261; ju&#380; tam przygotowane do pracy.&lt;/p&gt;


	&lt;p&gt;Og&#243;lnie rzecz bior&#261;c, &lt;strong&gt;Mako&lt;/strong&gt; to &amp;#8211; moim zdaniem &amp;#8211; najlepszy aktualnie istniej&#261;cy system szablon&#243;w dla Pythona.&lt;/p&gt;


	&lt;p&gt;Za&#347; co do framework&#243;w&amp;#8230; to coraz bardziej zaczynam nabiera&#263; pewno&#347;ci, &#380;e przysz&#322;o&#347;&#263; nie nale&#380;y ani do Django, ani do Rails&#243;w. Nic nie mo&#380;e r&#243;wna&#263; si&#281; z mo&#380;liwo&#347;ciami czystego, 100%  frameworka &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Takim jest np. &lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt;. Ale o tym, i o &amp;#8220;bitwie&amp;#8221; Pylons vs. Django i Rails, napisz&#281; ju&#380; innym razem.&lt;/p&gt;


	&lt;p&gt;Appendix 2007-01-29: Zobacz te&#380; &lt;a href="http://blog.zabiello.com/articles/2007/01/27/haml-nast%C4%99pna-generacja-szablon%C3%B3w"&gt;szablony Haml&lt;/a&gt;
.&lt;/p&gt;


&lt;hr /&gt;

	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Poprawnie rzecz m&#243;wi&#261;c, powinien napisa&#263; swojego helpera. Je&#347;li wi&#281;c chcemy wy&#347;wietli&#263; w p&#281;tli rekordy z bazy, a widok jest czu&#322;y na zawarto&#347;&#263; tych danych, to powinni&#347;my ca&#322;a list&#281; rekord&#243;w wrzuci&#263; do helplera, przeiterowa&#263; w p&#281;tli, doda&#263; dodatkow&#261; zmienn&#261; i dopiero tak zmodyfikowan&#261; list&#281; przekaza&#263; do szablonu.&lt;/p&gt;


	&lt;p id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; Smarty mimo posiadania w&#322;asnej sk&#322;adni pozwala na odpalanie pe&#322;nego j&#281;zyka &lt;span class="caps"&gt;PHP&lt;/span&gt;: {php}print phpinfo();{/php}. Tak praktyka jest jednak odradzana, bo wprowadza jeszcze wi&#281;kszy ba&#322;agan ni&#380; ju&#380; jest w &lt;span class="caps"&gt;PHP&lt;/span&gt;.&lt;/p&gt;


	&lt;p id="fn3"&gt;&lt;sup&gt;3&lt;/sup&gt; Zobacz artyku&#322; &lt;a href="http://www.xml.com/pub/a/2006/09/27/introducing-wsgi-pythons-secret-web-weapon.html"&gt;Introducing &lt;span class="caps"&gt;WSGI&lt;/span&gt;: Python&amp;#8217;s Secret Web Weapon&lt;/a&gt; oraz &lt;a href="http://www.groovie.org/articles/2006/09/18/wsgi-paste-pylons-and-all-that"&gt;prezentacj&#281; koncepcji &lt;span class="caps"&gt;WSGI&lt;/span&gt;&lt;/a&gt; na video.&lt;/p&gt;</description>
      <pubDate>Sun, 14 Jan 2007 04:25:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:85bc8794-3490-4af9-9c34-8cd949244305</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/01/14/templates-and-mvc-3</link>
      <category>templates</category>
      <category>savant</category>
      <category>spyce</category>
      <category>myghty</category>
      <category>cheetah</category>
      <category>mako</category>
      <category>django</category>
      <category>jinja</category>
      <category>pylons</category>
      <category>rails</category>
      <category>python</category>
      <category>ruby</category>
      <category>php</category>
      <category>mvc</category>
    </item>
    <item>
      <title>Szablony i wzorzec MVC - cz. II</title>
      <description>&lt;p&gt;W &lt;a href="http://blog.zabiello.com/articles/2007/01/03/templates-and-mvc"&gt;pierwszej cz&#281;&#347;ci&lt;/a&gt; wyjasniono czym jest wzorzec &lt;span class="caps"&gt;MVC&lt;/span&gt;, szablony i helpery. Pora na przyjrzenie si&#281; szablonom.&lt;/p&gt;


	&lt;p&gt;Jednym z najwa&#380;niejszych kryteri&#243;w, jest podzia&#322; &lt;strong&gt;&amp;#8220;programista czy designer&amp;#8221;&lt;/strong&gt; &amp;#8211; ma on du&#380;y wp&#322;yw na to, &lt;strong&gt;dla kogo&lt;/strong&gt; szablony b&#281;d&#261; proste a dla kogo &amp;#8211; uci&#261;&#380;liwe czy z&#322;o&#380;one. Tzn. czy szablonami b&#281;d&#261; zajmowa&#263; si&#281; programi&#347;ci czy te&#380; klasyczni web designerzy nie posiadaj&#261;cy specjalnie du&#380;ej wiedzy o programowaniu? W wypadku designera, szablony pos&#322;uguj&#261;ce si&#281; pe&#322;nym j&#281;zykiem programowania mog&#261; by&#263; nie lada wyzwaniem. Przeci&#281;tny designer pos&#322;uguje si&#281; Dreamweaverem i najch&#281;tniej w og&#243;le by nie chcia&#322; programowa&#263;. A je&#347;li ju&#380;, to tylko w zakresie jaki jest mu potrzebny do pracy nad szablonem.&lt;/p&gt;


	&lt;p&gt;Je&#347;li zatem mamy zar&#243;wno zesp&#243;&#322; programist&#243;w jak i takich designer&#243;w, i o nie chcemy aby programi&#347;ci musieli &lt;strong&gt;wszystkim si&#281; zajmowa&#263;&lt;/strong&gt;, warto wybra&#263; taki rodzaj szablon&#243;w, kt&#243;ry m&#243;g&#322;by by&#263; &amp;#8220;przyswajalny&amp;#8221; dla designer&#243;w.&lt;/p&gt;


	&lt;h2&gt;Szablony zgodne z &lt;span class="caps"&gt;XML&lt;/span&gt;.&lt;/h2&gt;


	&lt;p&gt;Najbardziej skrajnym przypadkiem jest u&#380;ycie takich szablon&#243;w, kt&#243;re s&#261; &amp;#8220;przezroczyste&amp;#8221; dla edytor&#243;w wizualnie wspomagaj&#261;cych projektowanie kodu &lt;span class="caps"&gt;HTML&lt;/span&gt;, np. Dreamweaver. W tym wypadku designer przygotowuje statyczne pliki &lt;span class="caps"&gt;HTML&lt;/span&gt; za pomoc&#261; takiego edytora i oddaje go programistom aby wt&#322;oczyli w nie &#380;ycie &amp;#8211; czyli dynamik&#281; kodu wykonywalnego po stronie serwera.&lt;/p&gt;


	&lt;p&gt;Szablony tego typo s&#261; w  100% zgodne z &lt;span class="caps"&gt;XML&lt;/span&gt;. Logika skryptu jest za&#347; sprytnie ukryta w dodatkowych atrybutach tag&#243;w &lt;span class="caps"&gt;HTML&lt;/span&gt; (m&#243;wi si&#281; tu o &lt;a href="http://www.zope.org/Wikis/DevSite/Projects/ZPT/TAL"&gt;&lt;span class="caps"&gt;TAL&lt;/span&gt;&lt;/a&gt; czyli tag attribute language &amp;#8211; j&#281;zyk atrybut&#243;w znacznik&#243;w) Kod zawarty w atrybutach tag&#243;w jest ignorowany przez Dreamweavera.&lt;/p&gt;


	&lt;p&gt;Tego typu szablony, cho&#263; s&#261; wygodne dla designer&#243;w (nic nie musz&#261; dodatkowo robi&#263;) s&#261; dosy&#263; uci&#261;&#380;liwe dla programist&#243;w. S&#261; w praktyce bardziej skomplikowane ni&#380; te, kt&#243;re daj&#261; mo&#380;liwo&#347;&#263; u&#380;ycia pe&#322;nego j&#281;zyka. Problemem jest te&#380; trudno&#347;&#263; w generowaniu za pomoc&#261; takich szablon&#243;w kodu niezgodnego z &lt;span class="caps"&gt;XML&lt;/span&gt;, np. &lt;span class="caps"&gt;CSS&lt;/span&gt; (styli kaskadowych) . Zalet&#261; jednak jest to, &#380;e jakakolwiek potrzeba poprawy layoutu sprowadza si&#281; do podrzucenia plik&#243;w designerom. Dreamveaver nie jest w stanie zniszczy&#263; logiki jak&#261; pracowicie programi&#347;ci dodali do atrybut&#243;w &lt;span class="caps"&gt;HTML&lt;/span&gt;. Nie trzeba na nowo za ka&#380;dym razem jej dodawa&#263;.&lt;/p&gt;


	&lt;h4&gt;Python&lt;/h4&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.zope.org/Documentation/ZopeBook/ZPT.stx"&gt;&lt;span class="caps"&gt;ZPT&lt;/span&gt;&lt;/a&gt; (Zope Page Templates) &amp;#8211; szablony u&#380;ywane przez serwer aplikacji &lt;a href="http://zope.org"&gt;Zope&lt;/a&gt;. &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.owlfish.com/software/simpleTAL/"&gt;SimpleTAL&lt;/a&gt; &amp;#8211; tak jak &lt;span class="caps"&gt;ZPT&lt;/span&gt;, ale dzia&#322;aj&#261;ce jako niezale&#380;na biblioteka, mo&#380;na je u&#380;ywa&#263; bez potrzeby instalacji Zope.&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://kid-templating.org/"&gt;Kid&lt;/a&gt; &amp;#8211; szablony wzorowane te&#380; na &lt;span class="caps"&gt;ZPT&lt;/span&gt; ale atrybuty wykorzystuj&#261; sk&#322;adni&#281; &lt;span class="caps"&gt;XSLT&lt;/span&gt;. Mo&#380;na te&#380; tworzy&#263; kolejne szablony na drodze obiektowego dziedziczenia.&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://genshi.edgewall.org/"&gt;&lt;strong&gt;Genshi&lt;/strong&gt;&lt;/a&gt; &amp;#8211; najlepsze w swej klasie. Wzorowane na &lt;a href="http://genshi.edgewall.org/wiki/Documentation/xpath.html"&gt;&lt;span class="caps"&gt;XSLT&lt;/span&gt;&lt;/a&gt; (np. mo&#380;na u&#380;ywa&#263; XPath) i szablonach Kid. Genshi potrafi kod &lt;span class="caps"&gt;XML&lt;/span&gt; jak i nie-XML. Zosta&#322;y pierwotnie stworzone dla doskona&#322;ego &lt;a href="http://trac.edgewall.org/"&gt;Traca&lt;/a&gt; (kt&#243;ry aktualnie migruje z szablon&#243;w &lt;a href="http://www.clearsilver.net/"&gt;ClearSilver&lt;/a&gt; do Genshi).&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h4&gt;Ruby&lt;/h4&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://masterview.org/"&gt;MasterView&lt;/a&gt; &amp;#8211; ciekawe szablony dla Ruby i Rails&#243;w. Wykorzystuj&#261; pe&#322;n&#261; moc i produktywno&#347;&#263; Rails&#243;w w&#322;&#261;cznie z szablonami wzorcowymi (layouts), podszablonami (partials) oraz mas&#261; helper&#243;w jakimi dysponuje Rails. R&#243;wnocze&#347;nie s&#261; przezroczyste dla Dreamweavera, wi&#281;c nadaj&#261; si&#281; doskonale dla designer&#243;w operuj&#261;cych tego typu edytorem.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h4&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/h4&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://phptal.motion-twin.com"&gt;&lt;span class="caps"&gt;PHP TAL&lt;/span&gt;&lt;/a&gt; jest pehapow&#261; implementacj&#261; pythonowych &lt;span class="caps"&gt;ZPT&lt;/span&gt;. Jak wida&#263; szablony u&#380;ywane w Zope jest &#378;r&#243;d&#322;em inspiracji dla ca&#322;ej reszty. :)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Szablony uniwersalne (z uproszczonym j&#281;zykiem)&lt;/h2&gt;


	&lt;p&gt;Je&#347;li nie mamy do czynienia z grup&#261; designer&#243;w boj&#261;cych si&#281; dotyka&#263; kodu, mo&#380;na pokusi&#263; si&#281; o u&#380;ycie szablon&#243;w wykorzystuj&#261;cych uproszczony j&#281;zyk programowania.&lt;/p&gt;


	&lt;h3&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/h3&gt;


	&lt;p&gt;Przyk&#322;adem najlepszych szablon&#243;w w tej klasie dla &lt;span class="caps"&gt;PHP&lt;/span&gt; s&#261; &lt;a href="http://smarty.templates.org"&gt;Smarty&lt;/a&gt;. Posiadaj&#261; dosy&#263; wygodn&#261; sk&#322;adni&#281; z mo&#380;e jednym wyj&#261;tkiem. Domy&#347;lne ustawienia dla wstawek kodu wykorzystuj&#261; dosy&#263; niefortunnie klamry. Sprawia to potem problem dla JavaScript. Na szcz&#281;&#347;cie mo&#380;na to przedefiniowa&#263;. Poza tym Smarty oferuj&#261; bardzo wygodne modyfikatory kt&#243;ry niczym uniksowe kaskady pipes filtruj&#261; zawarto&#347;&#263; zmiennej: {$zmienna|filtr1|filtr2}. Maj&#261; te&#380; w&#322;asny cache (cho&#263; oparty tylko na systemie plik&#243;w) Mo&#380;na te&#380; tworzy&#263; w&#322;asne komponenty(cho&#263; w ograniczonym zakresie, np. trudno je iterowa&#263; w p&#281;tli z powodu kolizji nazw &amp;#8211; &lt;span class="caps"&gt;PHP&lt;/span&gt; posiada tylko jedn&#261;, p&#322;ask&#261; przestrze&#324; nazw dla wszystkich funkcji)&lt;/p&gt;


	&lt;h3&gt;Python&lt;/h3&gt;


	&lt;p&gt;Bardzo dobrym przyk&#322;adem szablon&#243;w kt&#243;re mo&#380;na by da&#263; designerom do r&#281;ki s&#261; szablony u&#380;ywane we frameworku &lt;a href="http://djangotemplates.org"&gt;Django&lt;/a&gt;. Korzystaj&#261; one z element&#243;w Smarty i pythonowego &lt;a href="http://cheetahtemplate.org/"&gt;Cheetah&lt;/a&gt;. Posiadaj&#261; swoj&#261; sk&#322;adni&#281;, ale bardzo prost&#261; i wygodny spos&#243;b tworzenia kolejnych szablon&#243;w na bazie ju&#380; istniej&#261;cych. Tzw. w szablonach Smarty kolejne szablony s&#261; tworzone za pomoc&#261; ci&#281;cia i sklejania kawa&#322;k&#243;w kodu (pliki z szablonami mo&#380;na &amp;#8220;includowa&#263;&amp;#8221; do wi&#281;kszej ca&#322;o&#347;ci). W Django mo&#380;na to zrobi&#263; tak&#380;e na drodze obiektowego dziedziczenia. Tw&#243;rcy Django wyci&#261;gn&#281;li te&#380; lekcj&#281; ze Smart&#243;w i u&#380;ywaj&#261; dw&#243;ch klamr, zamiast jednej, co nie powoduje kolizji z kodem JavaScript.&lt;/p&gt;


base.html
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_html "&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; xml:lang=&amp;quot;en&amp;quot; lang=&amp;quot;en&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;style.css&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;{% block title %}szablon bazowy{% endblock %}&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
  {% block content %}tre&#347;&#263; szablonu bazowego{% endblock %}
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

example.html
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_html "&gt;{% extends &amp;quot;base.html&amp;quot; %}
{% block title %}Szablon  example.html{% endblock %}
{% block content %}
    &amp;lt;h1&amp;gt;{{ section.title }}&amp;lt;/h1&amp;gt;
    {% for story in story_list %}
    &amp;lt;h2&amp;gt;
      &amp;lt;a href=&amp;quot;{{ story.get_absolute_url }}&amp;quot;&amp;gt;
      {{ story.headline|upper }}
      &amp;lt;/a&amp;gt;
    &amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;{{ story.tease|truncatewords:&amp;quot;100&amp;quot; }}&amp;lt;/p&amp;gt;
   {% endfor %}
{% endblock %}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Szablony Django doczeka&#322;y si&#281; swoich nast&#281;pc&#243;w/na&#347;ladowc&#243;w.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://wsgiarea.pocoo.org/jinja/"&gt;&lt;strong&gt;Jinja&lt;/strong&gt;&lt;/a&gt; to szablony implementuj&#261;ce funkcjonalno&#347;&#263; Django, ale nie s&#261; zwi&#261;zane z samym frameworkiem. Stanowi&#261; oddzieln&#261; bibliotek&#281; kt&#243;r&#261; mo&#380;na u&#380;ywa&#263; w dowolnym kodzie Pythona. &#321;atwo je w&#322;&#261;czy&#263; np. do &lt;a href="http://pylonshq.com"&gt;Pylons&#243;w&lt;/a&gt;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Ruby&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="ttp://home.leetsoft.com/liquid"&gt;Liquid&lt;/a&gt; &amp;#8211; implementacja szablon&#243;w Django w j&#281;zyku Ruby. Mo&#380;na je u&#380;ywa&#263; np. we frameworku &lt;a href="http://rubyonrails.org"&gt;Rails&lt;/a&gt;. Nie posiadaj&#261; wszystkich djangowych cech, m.in. najwa&#380;niejszej &amp;#8211; obiektowo&#347;ci. Nie posiadaj&#261; te&#380; wszystkich helper&#243;w jakie s&#261; w Django. Jednak pozwalaj&#261; na u&#380;ywanie ich razem z szablonami  standardowymi &amp;#8211; &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/"&gt;ERb&lt;/a&gt;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;O kolejnej (w wypadku Pythona &amp;#8211; najliczniejszej)  grupie szablon&#243;w pozwalaj&#261;cej na pe&#322;ny dost&#281;p do j&#281;zyka b&#281;dzie w &lt;a href="http://blog.zabiello.com/articles/2007/01/14/templates-and-mvc-3"&gt;nast&#281;pnej cz&#281;&#347;ci&lt;/a&gt;. Daj&#261; one pe&#322;ny komfort programistom kln&#261;cym na ograniczenia szablon&#243;w u&#380;ywaj&#261;cych swoich w&#322;asnych j&#281;zyk&#243;w.&lt;/p&gt;</description>
      <pubDate>Sat, 06 Jan 2007 11:35:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:bf55ffa0-e3cf-4c19-8889-d97f35f14c94</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/01/06/templates-and-mvc-2</link>
      <category>templates</category>
      <category>zpt</category>
      <category>simpletal</category>
      <category>kid</category>
      <category>genshi</category>
      <category>smarty</category>
      <category>dango</category>
      <category>jinja</category>
      <category>liquid</category>
      <category>mvc</category>
    </item>
    <item>
      <title>Szablony i wzorzec MVC</title>
      <description>&lt;h2&gt;Wzorzec &lt;span class="caps"&gt;MVC&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://pl.wikipedia.org/wiki/MVC"&gt;&lt;span class="caps"&gt;MVC&lt;/span&gt;&lt;/a&gt; to skr&#243;t od ang. Model &amp;#8211; View &amp;#8211; Controller (czyli Model &amp;#8211; Widok &amp;#8211; Kontroler). Jest to jeden z popularniejszych &lt;a href="http://pl.wikipedia.org/wiki/Wzorzec_projektowy_%28informatyka%29"&gt;wzorc&#243;w projektowych&lt;/a&gt; (czy &amp;#8220;wzorc&#243;w architektonicznych w oprogramowanu&amp;#8221; jak si&#281; mog&#261; czepia&#263; niekt&#243;rzy pury&#347;ci) W uproszczeniu, wzorce projektowe to standardowe, sprawdzone rozwi&#261;zania dla typowych problem&#243;w programistycznych (g&#322;&#243;wnie dotycz&#261; programowania obiektowego). Ich przeciwie&#324;stwem s&#261; &lt;a href="http://pl.wikipedia.org/wiki/Antywzorce"&gt;anty-wzorce&lt;/a&gt;, czyli to, jak nie nale&#380;y programowa&#263;. Typowym antywzorcem jest &lt;em&gt;spaghetti-code&lt;/em&gt;, wymieszanie logiki biznesowej z warstw&#261; prezentacji, wszystkiego razem w jednym &#347;mietniku. To typowy styl programowania wi&#281;kszo&#347;ci niedo&#347;wiadczonych programist&#243;w &lt;span class="caps"&gt;PHP&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;W skr&#243;cie, wzorzec &lt;span class="caps"&gt;MVC&lt;/span&gt; polega na takim podziale kodu, aby sk&#322;ada&#322; si&#281; z trzech, funkcjonalnie oddzielnych cz&#281;&#347;ci.&lt;/p&gt;


	&lt;h3&gt;Model&lt;/h3&gt;


	&lt;p&gt;Modelem nazywamy t&#261; cz&#281;&#347;&#263; kodu aplikacji, kt&#243;ra jest odpowiedzialna za kontakt z danymi biznesowymi, gdziekolwiek s&#261; sk&#322;adowane (zwykle w relacyjnej bazie danych). Model nie tylko s&#322;u&#380;y do pobierania i modyfikacji danych biznesowych, ale tak&#380;e zajmuje si&#281; ich sp&#243;jno&#347;ci&#261; i integralno&#347;ci&#261; poprzez odpowiednie mechanizmy walidacji danych. Model s&#322;u&#380;y wi&#281;c za zar&#243;wno stra&#380;nika jak i dysponenta danych biznesowych. Bardzo elegancko wida&#263; to w &lt;a href="http://rubyonrails.pl"&gt;Ruby on Rails&lt;/a&gt; gdzie przyk&#322;adowy kod pe&#322;ni&#261;cy rol&#281; modelu wygl&#261;da&#263; mo&#380;e tak:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Project&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;belongs_to&lt;/span&gt; &lt;span class="symbol"&gt;:portfolio&lt;/span&gt;
  &lt;span class="ident"&gt;has_one&lt;/span&gt; &lt;span class="symbol"&gt;:project_manager&lt;/span&gt;
  &lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:milestones&lt;/span&gt;
  &lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:deliverables&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:through&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:milestones&lt;/span&gt;

  &lt;span class="ident"&gt;validates_presence_of&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:description&lt;/span&gt;
  &lt;span class="ident"&gt;validates_acceptance_of&lt;/span&gt; &lt;span class="symbol"&gt;:non_disclosure_agreement&lt;/span&gt;
  &lt;span class="ident"&gt;validates_uniqueness_of&lt;/span&gt; &lt;span class="symbol"&gt;:short_name&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Widok&lt;/h3&gt;


	&lt;p&gt;Widok s&#322;u&#380;y do generowania tego, co mogliby&#347;my okre&#347;li&#263; jako prezentacj&#281; naszej aplikacji. Przy czym nie jest okre&#347;lone jak ta prezentacja ma wygl&#261;da&#263;. Og&#243;lnie prezentacj&#261; jest to wszystko, co aplikacja &amp;#8220;wypluwa&amp;#8221; na zewn&#261;trz. Nie musi to by&#263; &#380;aden &amp;#8220;interfejs u&#380;ytkownika&amp;#8221; jak wypisuj&#261; bzdury co niekt&#243;rzy. Model &lt;span class="caps"&gt;MVC&lt;/span&gt; nie zak&#322;ada przecie&#380; tego, kto ma by&#263; &lt;em&gt;odbiornikiem&lt;/em&gt;  wysy&#322;anego strumiena danych. Mo&#380;e to by&#263; zar&#243;wno pani Genowefa miotaj&#261;ca si&#281; po internecie za pomoc&#261; Internet Explodera jak i rozbudowany czytnik kana&#322;&#243;w &lt;span class="caps"&gt;RSS&lt;/span&gt;, albo jakie&#347; dowolne urz&#261;dzenie odbieraj&#261;ce generowany strumie&#324; danych (w tym ostatnim wypadku nie musi to by&#263; w og&#243;le aplikacja webowa) Generowany strumie&#324; danych nie musi by&#263; w og&#243;le &#380;adnym tekstem. Mog&#261; to by&#263; bowiem r&#243;wnie dobrze strumie&#324; danych binarnych.&lt;/p&gt;


	&lt;p&gt;Zreszt&#261; tak w&#322;a&#347;nie dzia&#322;aj&#261; aplikacje webowe, kt&#243;re dzia&#322;aj&#261; wg zasady client-server. Tzn. klient wysy&#322;a &#380;&#261;danie, a serwer odpowiada. Przegl&#261;darka Iinternetowa wysy&#322;a &#380;&#261;danie do serwera &lt;span class="caps"&gt;WWW&lt;/span&gt;, a on odpowiada jej strumieniem danych. (w wypadku aplikacji webowych serwer wysy&#322;a wpierw tekst z nag&#322;&#243;wkiem informuj&#261;cym co b&#281;dzie wysy&#322;ane, bo to wynika z zasad protoko&#322;u &lt;a href="http://pl.wikipedia.org/wiki/HTTP"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;BTW&lt;/span&gt;, z tego wynika wa&#380;na lekcja odno&#347;nie adres&#243;w &lt;a href="http://pl.wikipedia.org/wiki/URL_%28informatyka%29"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/a&gt;. To co wklepujemy w przegl&#261;darce nie musi mie&#263; &#380;adnego zwi&#261;zku z jakimikolwiek &#347;cie&#380;kami na serwerze. Wszystkie technologie, u&#380;ywaj&#261;ce jawnych rozszerze&#324; plik&#243;w (.asp, .php, .jsp, .aspx itp) s&#261; g&#322;upie, bo po pierwsze, sugeruj&#261; &#380;e to co&#347; w adresie z ko&#324;c&#243;wk&#261; .php to zawsze jest konkretny plik po konkretnym katalogu. Po drugie, bez sensu eksponuj&#261; u&#380;yt&#261; technologi&#281;, co wi&#261;&#380;e troch&#281; r&#281;ce tym, kt&#243;rzy by chcieli zmieni&#263; wewnetrzny system generuj&#261;cy strony &lt;span class="caps"&gt;WWW&lt;/span&gt; ale bez ruszania starych adres&#243;w &lt;span class="caps"&gt;URL&lt;/span&gt;. Po trzecie, spidery takie jak Google nie lubi&#261; indeksowa&#263; stron generowanych dynamiczne. Je&#347;li zobacz&#261; w adresie znak zapytania to najcz&#281;&#347;ciej to, co za nim stoi jest ignorowane. Odbija sie to na &amp;#8220;pozycjonowaniu&amp;#8221; tak napisanej aplikacji. I po czwarte takie adresy (z rozszerzeniami i parametrami po znaku zapytania) s&#261; najzwyczajniej brzydkie i trudne do zapami&#281;tania. Nie znaczy to, &#380;e tak (/?x=1&amp;#38;y=2&amp;#38;z=4)w og&#243;le nie przekazywa&#263; parametr&#243;w. Chodzi tylko o to, aby to robi&#263; to oszcz&#281;dnie i tylko wtedy, kiedy jest to naprawd&#281; koniecznie.&lt;/p&gt;


	&lt;h3&gt;Kontroler&lt;/h3&gt;


	&lt;p&gt;Kod, kt&#243;ry spina wszystko razem i stanowi serce aplikacji to kontroler. To on pobiera dane z bazy za pomoc&#261; modelu i to on wybrane dane wysy&#322;a do widoku aby je jako&#347; zaprezentowa&#322; dla odbiorcy. Kontroler tak&#380;e dba o takie kwestie jak autoryzacja i autentykacja u&#380;ytkownik&#243;w (okre&#347;la kto mo&#380;e mie&#263; dost&#281;p do poszczeg&#243;lnych cz&#281;&#347;ci aplikacji). Kontroler zajmuje si&#281; te&#380; sposobem przep&#322;ywu danych zgodnie z potrzebami logiki biznesowej.&lt;/p&gt;


	&lt;h2&gt;Szablony i Helpery&lt;/h2&gt;


	&lt;p&gt;Czym s&#261; szablony? Szablony przynale&#380;&#261; do warstwy Widoku wzorca &lt;span class="caps"&gt;MVC&lt;/span&gt;. Otrzymuj&#261; dane z kontrolera i na tej podstawie generuj&#261; kod &lt;span class="caps"&gt;HTML&lt;/span&gt; jaki jest wysy&#322;any do przegl&#261;darki. Szablony powinny by&#263; raczej proste tak, aby mo&#380;na by&#322;o &#322;atwo modyfikowa&#263; spos&#243;b prezentacji bez godzin &#347;l&#281;czenia nad kodem. Najcz&#281;&#347;ciej kwesti&#261; prezentacji zajmuj&#261; si&#281; r&#243;&#380;nej ma&#347;ci webmasterzy i designerzy, czyli og&#243;lniej osoby, kt&#243;re niekoniecznie s&#261; zaawansowanymi programistami.&lt;/p&gt;


	&lt;p&gt;W wypadku kiedy spos&#243;b prezentacji jest z&#322;o&#380;ony, aby nie komplikowa&#263; szablonu stosuje si&#281; do pomocy&amp;#8230; pomocnika ;) G&#322;&#243;wnym zadaniem helpera jest takie wstepne przetworzenie danych (jakie kontroler wrzuci&#322; do szablonu) aby szablon mog&#261;cy je wy&#347;wietli&#263; by&#322; jak najprostszy i jak najbardziej czytelny. Helper dane pobiera od szablonu, modyfikuje je i odsy&#322;a je z powrotem. Dzi&#281;ki temu logika niezb&#281;dna do wygenerowania prezentacji jest w szablonie znacznie uproszczona.&lt;/p&gt;


	&lt;p&gt;Szablony mo&#380;na podzieli&#263; na kilka rodzaj&#243;w, stosownie do oczekiwanych od nich funkcji. Ale o tym (i o strategii wyboru w&#322;a&#347;ciwych szablon&#243;w) ju&#380; w &lt;a href="http://blog.zabiello.com/articles/2007/01/06/templates-and-mvc-2"&gt;drugiej cz&#281;&#347;ci&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 03 Jan 2007 20:30:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:24eef7ec-0037-4de2-b03c-eb6582b028a8</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/01/03/templates-and-mvc</link>
      <category>mvc</category>
      <category>templates</category>
      <category>design</category>
      <category>rails</category>
    </item>
  </channel>
</rss>
