Szybki start z Rails, Merb i Pylons

Opublikowane przez Jarosław Zabiełło Sun, 16 Dec 2007 06:31:00 GMT

Celem tego tekstu jest porównanie podstawowych czynności niezbędnych do tego aby uruchomić Rails, Merb oraz Pylons. Zakładam że używany będzie

Czytaj dalej...

Tagi , , , , , , , ,  | 15 comments

Szablony i wzorzec MVC - cz. III

Opublikowane przez Jarosław Zabiełło Sun, 14 Jan 2007 03:25:00 GMT

W poprzedniej części omówiono szablony dedykowane głównie do współpracy z designerami bojącymi się programować. Były to albo szablony wkładające swoją logikę do znaczników XML/XHTML (ZPT, SimpleTAL, Kid, Genshi, MasterView, PHP TAL), albo szablony posiadające swój własny, specjalizowany język (Smarty, Django, Jinja, Liquid). W założeniu taki język miał być prostym substytutem języka używanego w warstwie kontrolera. Szablony tego typu może są wygodne dla designera, ale na pewno nie dla programisty, który musi je przygotować. Po pierwsze, trzeba się uczyć kolejnego języka… szablonów. Po drugie, wszystkie tego typu języki są ograniczające dla programisty. Mimo że pozornie prostsze, w praktyce są bardziej złożone i to nawet dla designera. Np. szablony Django i Jinja nie posiadają żadnej składni na określenie trywialnego warunku większości, mniejszości:

{{ x }} jest 
{% if x > y %} 
    większe 
{% else %} 
    mniejsze 
{% endif %} 
od {{ y }}

Powoduje to masę kłopotów dla programisty1. Prymitywna składnia szablonu wymusza więc kupę dodatkowej pracy. O ileż prościej jest użyć po prostu pełnej składni języka tak jak to robią szablony Cheetah:

$x jest 
# if x > y 
    większe 
# else 
    mniejsze 
# endif  
od $y

Dochodzimy tu więc do sytuacji kiedy byśmy chcieli coś bardziej elastycznego – pełnego dostępu do języka programowania. Taka sytuacja jest pożądana wtedy kiedy i tak szablony budują programiści na podstawie dostarczonego czystego kodu HTML od designerów.

PHP

Język PHP jest dosyć specyficzny, bo w istocie jest to język szablonów. Tzn. pierwotnie tak został stworzony, ale z czasem się skomplikował że dostąpił miana języka skryptowego. Ale jego korzenie widać w składni, która z definicji jest zagnieżdżaniem instrukcji PHP wewnątrz kodu HTML. Idąc tym tropem, niektórzy pomyśleli, że nie ma sensu wymyślać dodatkową składnię. Wystarczy użyć PHP w odpowiedni sposób. I tak powstały szablony Savant.

Właściwie to Savant nie powinny nazywać się szablonami, bo to nic innego jak PHP użyty w taki sposób, aby rozdzielić warstwę prezentacji, od wartwy logiki biznesowej. A skoro to PHP, to odpada nauka dodatkowej składni oraz potrzeby kompilacji specjalizowanego języka szablonów do końcowego kodu PHP (jak to ma miejsce w szablonach Smarty).

Czy takie podejście jest lepsze, czy gorsze, to już każdy może sobie ocenić. Moim zdaniem PHP ma na tyle mętną składnię, że warstwa prezentacji używająca Smarty2 jest bardziej czytelna niż czysty PHP jaki używają Savant.

Ruby

Kiedy mówimy o Ruby w kontekście stron internetowych to najczęściej mamy na myśli jego najsłynniejszy framework – Rails. Ruby sam w sobie nie jest związany z HTML tak jak PHP. Rails do szablonów używa biblioteki ERb (ang. “embed Ruby”, czyli “zagnieżdżony Ruby”) Składnia jest bardzo podobna do PHP, JSP czy ASP. Ruby jest tu językiem zagnieżdżonym w HTML.

<%= x %> jest 
<% if x > y %> 
    większe 
<% else %>
    mniejsze 
<% end %>
od <%= y %>

Python

Jeśli chodzi o Pythona to istnieje cała masa systemów szablonowych. Ograniczę się do paru, tych bardziej interesujących.

Spyce

Szablony Spyce zostało stworzone jako pythonowa konkurencja dla PHP. Podobnie potrafią przeplatać język (tu: Pythona) z tagami HTML. Najbardziej oczywista przewaga Spyce wynika z faktu używania języka Python, który jest znacznie lepiej zaprojektowany i posiada dużo więcej możliwości niż PHP. Spyce potrafii budować własne znaczniki (custom tags, podobnie jak to potrafią javowe JSP) oraz łatwiej w nich zbudować komponenty, kod do wielokrotnego użytku.

Myghty

Szablony Myghty powstały pierwotnie jako pythonowa implementacja systemu komponentowego Mason dla Perla. Mimo wielu podobieństw, Myghty są znacznie potężniejsze o Masona, np. intensywnie wykorzystują obiektowość Pythona (zobacz różnice). Od początku Myghty powstało z myślą o dużych obciążeniach, ciężkich, profesjonalnych zastosowaniach. Mają doskonały własny cache, są bardzo szybkie, odporne na wątki, świetnie się nadają do tworzenia komponentów.

Programiści Pythona bardzo cenią sobie filozofię tego języka (która podkreśla prostotę, oczywistość i elegancję składni). Problem w tym, że Myghty dla pythonowców jest zbyt podobne do Perla. Są za mało “pythonic” – pythonowe. Dodatkowo, poprzez podkreślanie swojej komponentowości, Myghty niektórym zbyt kojarzy się z filozofią komponentową frameworku ASP.NET (a wzorzec MVC wydaje się być bardziej przejrzysty niż wzorzec sterowanych zdarzeniami komponentów). Myghty, jako system komponentowy, może być używane w stylu MVC, ale nie jest to takie naturalne i oczywiste. (Na szczęście, wszystko zmienił Pylons który zapewnia przejrzystą pracę zgodną z wzorcem MVC i Myghty są tam zredukowane tylko do obsługi szablonów szablonów. Sterowaniem zajmują się kontrolery Pylonsa a nie Myghty).

Cheetah

Szablony Cheetah posiadają jedną z najbardziej czytelnych i eleganckich składni. Autorzy wzorowali się trochę na javowych Velocity i Webmacro. Tym, którzy cenią sobie czystość Pythona z prostotą składni szablonów z pewnością Cheetah mogą przypaść do gustu. Przez dłuższy czas były moimi ulubionymi szablonami i do te pory lubię ich klarowność. Cheetah posiadają elegancką składnię obiektowego budowania szablonów potomnych na bazie już istniejących. Myghty też to potrafi, ale Cheetah to ma bardzo czytelnie zrobione. Cheetah są również bardzo szybkie.

Mako

Mako to najmłodsze dziecko stworzone przez programistów Pylonsów. Powstały na bazie doświadczeń i najlepszych cech szablonów Myghty, Cheetah, Django/Jinja czy Smarty. Największą ich zaletą jest ogromna szybkość i pythonowa filozofia pracy. Programiści Pythona mogą zauważyć, że składnia Mako jest bardzo bliska sposobowi pracy w samym języku Python. Mako posiadają wielką łatwość tworzenia komponentów, ale w sposób bardzo podobny do tego jak Python wykorzystuje swoje moduły. Szablony można także rozszerzać na drodze obiektowego dziedziczenia. Dziedziczenie szablonów może być określane w sposób dynamiczny (tego już nie potrafią np. Cheetah). Dowolny fragment szablonu można również zamienić na komponent z własnym cache. Mako posiadają także składnię modyfikatorów, które spopularyzowane zostały przez Smarty. Działają one jak uniksowe pipes (${zmienna|filter}.

Mako automatycznie kompilują swój kod do modułów Pythona. Można je więc debugować tak jak zwykły kod Pythona (Cheeatah wymaga ręcznej kompilacji). Można je bez problemu używać jako niezależną bibliotekę. Nie są one zależne od jakiegokolwiek frameworku. Można je zintegrować z dowolnym frameworkiem używającym standardu3 WSGI. Użytkownicy frameworka Pylons prawie nic nie muszą robić, bo Mako są już tam przygotowane do pracy.

Ogólnie rzecz biorąc, Mako to – moim zdaniem – najlepszy aktualnie istniejący system szablonów dla Pythona.

Zaś co do frameworków… to coraz bardziej zaczynam nabierać pewności, że przyszłość nie należy ani do Django, ani do Railsów. Nic nie może równać się z możliwościami czystego, 100% frameworka WSGI. Takim jest np. Pylons. Ale o tym, i o “bitwie” Pylons vs. Django i Rails, napiszę już innym razem.

Appendix 2007-01-29: Zobacz też szablony Haml .


1 Poprawnie rzecz mówiąc, powinien napisać swojego helpera. Jeśli więc chcemy wyświetlić w pętli rekordy z bazy, a widok jest czuły na zawartość tych danych, to powinniśmy cała listę rekordów wrzucić do helplera, przeiterować w pętli, dodać dodatkową zmienną i dopiero tak zmodyfikowaną listę przekazać do szablonu.

2 Smarty mimo posiadania własnej składni pozwala na odpalanie pełnego języka PHP: {php}print phpinfo();{/php}. Tak praktyka jest jednak odradzana, bo wprowadza jeszcze większy bałagan niż już jest w PHP.

3 Zobacz artykuł Introducing WSGI: Python’s Secret Web Weapon oraz prezentację koncepcji WSGI na video.

Tagi , , , , , , , , , , , , ,  | 15 comments

Pylons + Mako

Opublikowane przez Jarosław Zabiełło Tue, 02 Jan 2007 03:46:00 GMT

Mako – nowy, wydajny system szablonów dla Pylonsów jest już dostępny publicznie na stronie http://makotemplates.org. Można go pobrać za pomocą setuptoolsów, czyli skryptem:

easy_install Mako

Posted in  | Tagi ,  | 3 comments

Pylons 0.9.4

Opublikowane przez Jarosław Zabiełło Sun, 31 Dec 2006 01:40:00 GMT

Wyszła nowa wersja pythonowego megaframeworka (korzysta z zewn., już istniejących bibliotek) do szybkiego budowania aplikacji webowych – Pylons. W wersji 0.9.4 dodano trochę poprawek i ulepszeń. M.in. jest nowy Routes 1.6.1, ulepszono introspekcję dla XML-RPC,Akcje kontrolerów są teraz generatorami a helpery oraz metoda _ (z gettext) generują teraz obiekty Unicodowe zamiast stringów UTF-8. Znowu Pylons znacznie wyprzedza, to co dopiero jest w powijakach dla Django.

SQLAlchemy

Coraz bardziej zaznacza się tendencja w używanych pod Pythonem ORM’ach (Pylons może korzystać z dowolnych) aby zamiast SQLObject wybierać raczej SQLAlchemy. Ten drugi jest uważany za znacznie bardziej wyrafinowany i o większych możliwościach. Na liście dyskusyjnej Pylonsów Ben Bangert pokazał jak w praktyce można używać SQLAlchemy.

Szablony

Pylons potrafi korzystać z dowolnych systemów szablonów dostępnych dla Pythona. Generalnie, popularne są dwa podejścia. Szablony pisane pod propgramistów lub pod webmasterów/designerów, którzy zajmują się samą kwestią prezentacji, wizualizacji i pracują najczęściej ze “wspomagaczami” takimi jak edytor Dreamweaver.

Dla tych drugich, polecane jest podejście albo takie jak promuje Django, czyli specjalnie uproszczony język szablonów umożliwiającym generowanie zaróno HTML jak i CSS, czy innej dowolnej treści.

Albo podejście jeszcze bardziej uproszczone (dla designerów, nie dla programistów), czyli koncepcja, jaką promują twórcy frameworka Zope. Chodzi o szablony ZPT, Kid czy Genshi gdzie logika szablonów jest dodana do atrybutów. Dzięki temu są one przezroczyste dla edytorów takich jak Dreamweaver i jeśli wymagana jest częsta konsultacja z designerami to takie podejście oszczędza ponownego, ręcznego dodawania logiki dla programistów.

Nadchodzi Mako

Moim zdaniem, znacznie lepszym podejściem jest podejście jakie oferują szablony Cheetah czy Myghty. Te drugie, są aktualnie najpoteżniejsze. Mają nie tylko duża szybkość, ale bardzo dobrze działający (lepszy od Cheetah) cache oraz łatwość do tworzenia komponentów, klocków wielokrotnego użycia.

Nadchodzi jednak coś jeszcze lepszego. Developerzy Pylonsów szykują zupełnie nowy system szablonów zwany Mako (http://makotemplates.org). Jest on wzorowany na najlepszych funkcjach jakie oferują Myghty, Cheetah, Genshi i Django. Jest też bardzo szybki.

Mako oferują wielostrefowe dziedziczenie (podobnie jak Cheetah i Django). Nie jest też wymagane tak jak w Myghty, aby wstawki Pythona (zaczynające się w szablonach Myghty od znaku procenta) zaczynały wiersz. Można wstawiać je w środku tekstu lub gdziekolwiek w ramach tagów <% kod Pythona %>.

<%inherit file="base.html"/>
<%
    rows = [[v for v in range(0,10)] for row in range(0,10)]
%>
<table>
    % for row in rows:
        ${makerow(row)}
    % endfor
</table>

<%def name="makerow(row)">
    <tr>
    % for name in row:
        <td>${name}</td>\
    % endfor
    </tr>
</%def>

Unikalne dziedziczenie dynamiczne (zmienna może określać które szablony mają być bazowymi dla innych). Szablony mogą być też buforowane. Można wygodnie filtrować dane w stylu Django (Python) czy Smarty (PHP).

<%!
    def myescape(text):
        return "<TAG>" + text + "</TAG>"
%>

Heres some tagged text: ${"text" | myescape}

Oczywiście można dowolny element szablonów keszować na wiele sposobów.

<%def name="mycomp" cache="true" cache_timeout="30" cache_type="memory">
    other text
</%def>

Pylons 0.9.4 ma już wbudowaną obsługę dla Mako. Wystarczy je ściągnąć z SVN:

svn co http://svn.makotemplates.org/mako/trunk mako

Po zainstalowaniu, jedyne co trzeba, to dodać opcję

template_engine='mako' 

do wywołania config.init_app w middleware.py.

Posted in  | Tagi , , ,  | 1 comment